From: Masami Hiramatsu (Google) <[email protected]> Support BTF typecast feature on other probe events (but only if it is kernel function entry or return.)
To support other probe events, we just need to use last_struct type when we find a function parameter in parse_btf_arg(). This also update <tracefs>/README file to show struct typecast. Signed-off-by: Masami Hiramatsu (Google) <[email protected]> --- Documentation/trace/fprobetrace.rst | 3 +++ Documentation/trace/kprobetrace.rst | 4 ++++ kernel/trace/trace.c | 2 +- kernel/trace/trace_probe.c | 12 +++++++----- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/Documentation/trace/fprobetrace.rst b/Documentation/trace/fprobetrace.rst index b4c2ca3d02c1..7435ded2d66d 100644 --- a/Documentation/trace/fprobetrace.rst +++ b/Documentation/trace/fprobetrace.rst @@ -57,6 +57,9 @@ Synopsis of fprobe-events (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types (x8/x16/x32/x64), "char", "string", "ustring", "symbol", "symstr" and bitfield are supported. + (STRUCT)FIELD->MEMBER[->MEMBER] : If BTF is supported, typecast FIELD to + a pointer to STRUCT and then derference the pointer defined by + ->MEMBER. (\*1) This is available only when BTF is enabled. (\*2) only for the probe on function entry (offs == 0). Note, this argument access diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst index 3b6791c17e9b..f73614997d52 100644 --- a/Documentation/trace/kprobetrace.rst +++ b/Documentation/trace/kprobetrace.rst @@ -61,6 +61,10 @@ Synopsis of kprobe_events (x8/x16/x32/x64), VFS layer common type(%pd/%pD), "char", "string", "ustring", "symbol", "symstr" and bitfield are supported. + (STRUCT)FIELD->MEMBER[->MEMBER] : If BTF is supported, typecast FIELD to + a pointer to STRUCT and then derference the pointer defined by + ->MEMBER. Note that this is available only when the probe is + on function entry. (\*1) only for the probe on function entry (offs == 0). Note, this argument access is best effort, because depending on the argument type, it may be passed on diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 6eb4d3097a4d..aa93e7b01146 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -4325,7 +4325,7 @@ static const char readme_msg[] = #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API "\t $stack<index>, $stack, $retval, $comm, $arg<N>,\n" #ifdef CONFIG_PROBE_EVENTS_BTF_ARGS - "\t <argname>[->field[->field|.field...]],\n" + "\t [(structname)]<argname>[->field[->field|.field...]],\n" #endif #else "\t $stack<index>, $stack, $retval, $comm,\n" diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c index fd1caa1f9723..609b156986c5 100644 --- a/kernel/trace/trace_probe.c +++ b/kernel/trace/trace_probe.c @@ -759,7 +759,10 @@ static int parse_btf_arg(char *varname, return -ENOENT; found: - type = btf_type_skip_modifiers(ctx->btf, tid, &tid); + if (ctx->struct_btf) + type = ctx->last_struct; + else + type = btf_type_skip_modifiers(ctx->btf, tid, &tid); found_type: if (!type) { trace_probe_log_err(ctx->offset, BAD_BTF_TID); @@ -836,10 +839,9 @@ static int handle_typecast(char *arg, struct fetch_insn **pcode, char *tmp; int ret; - /* Currently this only works for eprobes */ - if (!(ctx->flags & TPARG_FL_TEVENT)) { - trace_probe_log_err(ctx->offset, TYPECAST_NOT_EVENT); - return -EINVAL; + if (!(tparg_is_function_entry(ctx->flags) || tparg_is_function_return(ctx->flags))) { + trace_probe_log_err(ctx->offset, NOSUP_BTFARG); + return -EOPNOTSUPP; } tmp = strchr(arg, ')');
