Messages in this thread Patch in this message | | | From | Qing Zhang <> | Subject | [PATCH RESEND] LoongArch: ptrace: Add function argument access API | Date | Wed, 15 Feb 2023 17:24:56 +0800 |
| |
Add regs_get_argument() which returns N th argument of the function call, This enables ftrace kprobe events to access kernel function arguments via $argN syntax.
eg: echo 'p bio_add_page arg1=$arg1' > kprobe_events bash: echo: write error: Invalid argument
Signed-off-by: Qing Zhang <zhangqing@loongson.cn> --- arch/loongarch/Kconfig | 1 + arch/loongarch/include/asm/ptrace.h | 33 +++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+)
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index e3eba2eb4b44..103046966893 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -97,6 +97,7 @@ config LOONGARCH select HAVE_EXIT_THREAD select HAVE_FAST_GUP select HAVE_FTRACE_MCOUNT_RECORD + select HAVE_FUNCTION_ARG_ACCESS_API select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER select HAVE_GENERIC_VDSO diff --git a/arch/loongarch/include/asm/ptrace.h b/arch/loongarch/include/asm/ptrace.h index 66a0e6c480a3..f6ffcc00753c 100644 --- a/arch/loongarch/include/asm/ptrace.h +++ b/arch/loongarch/include/asm/ptrace.h @@ -120,6 +120,39 @@ static inline long regs_return_value(struct pt_regs *regs) return regs->regs[4]; } +/** + * regs_get_kernel_argument() - get Nth function argument in kernel + * @regs: pt_regs of that context + * @n: function argument number (start from 0) + * + * regs_get_argument() returns @n th argument of the function call. + * Note that this chooses most probably assignment, in some case + * it can be incorrect. + * This is expected to be called from kprobes or ftrace with regs + * where the top of stack is the return address. + */ +static inline unsigned long regs_get_kernel_argument(struct pt_regs *regs, + unsigned int n) +{ + static const unsigned int argument_offs[] = { + offsetof(struct pt_regs, regs[4]), + offsetof(struct pt_regs, regs[5]), + offsetof(struct pt_regs, regs[6]), + offsetof(struct pt_regs, regs[7]), + offsetof(struct pt_regs, regs[8]), + offsetof(struct pt_regs, regs[9]), + offsetof(struct pt_regs, regs[10]), + offsetof(struct pt_regs, regs[11]), +#define NR_REG_ARGUMENTS 8 + }; + + if (n >= NR_REG_ARGUMENTS) { + n -= NR_REG_ARGUMENTS; + return regs_get_kernel_stack_nth(regs, n); + } else + return regs_get_register(regs, argument_offs[n]); +} + #define instruction_pointer(regs) ((regs)->csr_era) #define profile_pc(regs) instruction_pointer(regs) -- 2.36.0
| |