Merge tag 'trace-probes-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull trace probes updates from Steven Rostedt: - New "symstr" type for dynamic events that writes the name of the function+offset into the ring buffer and not just the address - Prevent kernel symbol processing on addresses in user space probes (uprobes). - And minor fixes and clean ups * tag 'trace-probes-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: tracing/probes: Reject symbol/symstr type for uprobe tracing/probes: Add symstr type for dynamic events kprobes: kretprobe events missing on 2-core KVM guest kprobes: Fix check for probe enabled in kill_kprobe() test_kprobes: Fix implicit declaration error of test_kprobes tracing: Fix race where eprobes can be called before the event
This commit is contained in:
+42
-23
@@ -76,9 +76,11 @@ const char PRINT_TYPE_FMT_NAME(string)[] = "\\\"%s\\\"";
|
||||
/* Fetch type information table */
|
||||
static const struct fetch_type probe_fetch_types[] = {
|
||||
/* Special types */
|
||||
__ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1,
|
||||
__ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1, 1,
|
||||
"__data_loc char[]"),
|
||||
__ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1,
|
||||
__ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1, 1,
|
||||
"__data_loc char[]"),
|
||||
__ASSIGN_FETCH_TYPE("symstr", string, string, sizeof(u32), 1, 1,
|
||||
"__data_loc char[]"),
|
||||
/* Basic types */
|
||||
ASSIGN_FETCH_TYPE(u8, u8, 0),
|
||||
@@ -98,10 +100,15 @@ static const struct fetch_type probe_fetch_types[] = {
|
||||
ASSIGN_FETCH_TYPE_END
|
||||
};
|
||||
|
||||
static const struct fetch_type *find_fetch_type(const char *type)
|
||||
static const struct fetch_type *find_fetch_type(const char *type, unsigned long flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reject the symbol/symstr for uprobes */
|
||||
if (type && (flags & TPARG_FL_USER) &&
|
||||
(!strcmp(type, "symbol") || !strcmp(type, "symstr")))
|
||||
return NULL;
|
||||
|
||||
if (!type)
|
||||
type = DEFAULT_FETCH_TYPE_STR;
|
||||
|
||||
@@ -119,13 +126,13 @@ static const struct fetch_type *find_fetch_type(const char *type)
|
||||
|
||||
switch (bs) {
|
||||
case 8:
|
||||
return find_fetch_type("u8");
|
||||
return find_fetch_type("u8", flags);
|
||||
case 16:
|
||||
return find_fetch_type("u16");
|
||||
return find_fetch_type("u16", flags);
|
||||
case 32:
|
||||
return find_fetch_type("u32");
|
||||
return find_fetch_type("u32", flags);
|
||||
case 64:
|
||||
return find_fetch_type("u64");
|
||||
return find_fetch_type("u64", flags);
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
@@ -478,7 +485,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
|
||||
DEREF_OPEN_BRACE);
|
||||
return -EINVAL;
|
||||
} else {
|
||||
const struct fetch_type *t2 = find_fetch_type(NULL);
|
||||
const struct fetch_type *t2 = find_fetch_type(NULL, flags);
|
||||
|
||||
*tmp = '\0';
|
||||
ret = parse_probe_arg(arg, t2, &code, end, flags, offs);
|
||||
@@ -630,9 +637,9 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
|
||||
/* The type of $comm must be "string", and not an array. */
|
||||
if (parg->count || (t && strcmp(t, "string")))
|
||||
goto out;
|
||||
parg->type = find_fetch_type("string");
|
||||
parg->type = find_fetch_type("string", flags);
|
||||
} else
|
||||
parg->type = find_fetch_type(t);
|
||||
parg->type = find_fetch_type(t, flags);
|
||||
if (!parg->type) {
|
||||
trace_probe_log_err(offset + (t ? (t - arg) : 0), BAD_TYPE);
|
||||
goto out;
|
||||
@@ -662,16 +669,26 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
|
||||
|
||||
ret = -EINVAL;
|
||||
/* Store operation */
|
||||
if (!strcmp(parg->type->name, "string") ||
|
||||
!strcmp(parg->type->name, "ustring")) {
|
||||
if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF &&
|
||||
code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM &&
|
||||
code->op != FETCH_OP_DATA && code->op != FETCH_OP_TP_ARG) {
|
||||
trace_probe_log_err(offset + (t ? (t - arg) : 0),
|
||||
BAD_STRING);
|
||||
goto fail;
|
||||
if (parg->type->is_string) {
|
||||
if (!strcmp(parg->type->name, "symstr")) {
|
||||
if (code->op != FETCH_OP_REG && code->op != FETCH_OP_STACK &&
|
||||
code->op != FETCH_OP_RETVAL && code->op != FETCH_OP_ARG &&
|
||||
code->op != FETCH_OP_DEREF && code->op != FETCH_OP_TP_ARG) {
|
||||
trace_probe_log_err(offset + (t ? (t - arg) : 0),
|
||||
BAD_SYMSTRING);
|
||||
goto fail;
|
||||
}
|
||||
} else {
|
||||
if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF &&
|
||||
code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM &&
|
||||
code->op != FETCH_OP_DATA && code->op != FETCH_OP_TP_ARG) {
|
||||
trace_probe_log_err(offset + (t ? (t - arg) : 0),
|
||||
BAD_STRING);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM ||
|
||||
if (!strcmp(parg->type->name, "symstr") ||
|
||||
(code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM ||
|
||||
code->op == FETCH_OP_DATA) || code->op == FETCH_OP_TP_ARG ||
|
||||
parg->count) {
|
||||
/*
|
||||
@@ -679,6 +696,8 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
|
||||
* must be kept, and if parg->count != 0, this is an
|
||||
* array of string pointers instead of string address
|
||||
* itself.
|
||||
* For the symstr, it doesn't need to dereference, thus
|
||||
* it just get the value.
|
||||
*/
|
||||
code++;
|
||||
if (code->op != FETCH_OP_NOP) {
|
||||
@@ -690,6 +709,8 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
|
||||
if (!strcmp(parg->type->name, "ustring") ||
|
||||
code->op == FETCH_OP_UDEREF)
|
||||
code->op = FETCH_OP_ST_USTRING;
|
||||
else if (!strcmp(parg->type->name, "symstr"))
|
||||
code->op = FETCH_OP_ST_SYMSTR;
|
||||
else
|
||||
code->op = FETCH_OP_ST_STRING;
|
||||
code->size = parg->type->size;
|
||||
@@ -919,8 +940,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
|
||||
for (i = 0; i < tp->nr_args; i++) {
|
||||
parg = tp->args + i;
|
||||
if (parg->count) {
|
||||
if ((strcmp(parg->type->name, "string") == 0) ||
|
||||
(strcmp(parg->type->name, "ustring") == 0))
|
||||
if (parg->type->is_string)
|
||||
fmt = ", __get_str(%s[%d])";
|
||||
else
|
||||
fmt = ", REC->%s[%d]";
|
||||
@@ -928,8 +948,7 @@ static int __set_print_fmt(struct trace_probe *tp, char *buf, int len,
|
||||
pos += snprintf(buf + pos, LEN_OR_ZERO,
|
||||
fmt, parg->name, j);
|
||||
} else {
|
||||
if ((strcmp(parg->type->name, "string") == 0) ||
|
||||
(strcmp(parg->type->name, "ustring") == 0))
|
||||
if (parg->type->is_string)
|
||||
fmt = ", __get_str(%s)";
|
||||
else
|
||||
fmt = ", REC->%s";
|
||||
|
||||
Reference in New Issue
Block a user