From: He Chuyue hechuyue@wxiat.com
Sunway inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I56X48
--------------------------------
To enable kprobes-based dynamic events, we implement the APIs needed to access registers and stack entries from pt_regs, then select HAVE_REGS_AND_STACK_ACCESS_API by default.
Signed-off-by: He Chuyue hechuyue@wxiat.com
Signed-off-by: Gu Zitao guzitao@wxiat.com --- arch/sw_64/Kconfig | 1 + arch/sw_64/include/asm/ptrace.h | 2 ++ arch/sw_64/kernel/ptrace.c | 26 ++++++++++++++++++++++++++ 3 files changed, 29 insertions(+)
diff --git a/arch/sw_64/Kconfig b/arch/sw_64/Kconfig index 6c9fb51347f3..a37e92c1c8e4 100644 --- a/arch/sw_64/Kconfig +++ b/arch/sw_64/Kconfig @@ -103,6 +103,7 @@ config SW64 select SET_FS select PCI_MSI_ARCH_FALLBACKS select DMA_OPS if PCI + select HAVE_REGS_AND_STACK_ACCESS_API
config LOCKDEP_SUPPORT def_bool y diff --git a/arch/sw_64/include/asm/ptrace.h b/arch/sw_64/include/asm/ptrace.h index 33f5cc97c976..74349a05b9e4 100644 --- a/arch/sw_64/include/asm/ptrace.h +++ b/arch/sw_64/include/asm/ptrace.h @@ -45,6 +45,8 @@ static inline u64 regs_get_register(struct pt_regs *regs, unsigned int offset) return *(unsigned long *)((unsigned long)regs + offset); } extern int regs_query_register_offset(const char *name); +extern unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, + unsigned int n);
static inline unsigned long regs_return_value(struct pt_regs *regs) { diff --git a/arch/sw_64/kernel/ptrace.c b/arch/sw_64/kernel/ptrace.c index 5f29c500c8b1..5052c444f29a 100644 --- a/arch/sw_64/kernel/ptrace.c +++ b/arch/sw_64/kernel/ptrace.c @@ -705,3 +705,29 @@ int regs_query_register_offset(const char *name) return roff->offset; return -EINVAL; } + +static int regs_within_kernel_stack(struct pt_regs *regs, unsigned long addr) +{ + unsigned long ksp = kernel_stack_pointer(regs); + + return (addr & ~(THREAD_SIZE - 1)) == (ksp & ~(THREAD_SIZE - 1)); +} + +/** + * regs_get_kernel_stack_nth() - get Nth entry of the stack + * @regs:pt_regs which contains kernel stack pointer. + * @n:stack entry number. + * + * regs_get_kernel_stack_nth() returns @n th entry of the kernel stack which + * is specifined by @regs. If the @n th entry is NOT in the kernel stack, + * this returns 0. + */ +unsigned long regs_get_kernel_stack_nth(struct pt_regs *regs, unsigned int n) +{ + unsigned long addr; + + addr = kernel_stack_pointer(regs) + n * sizeof(long); + if (!regs_within_kernel_stack(regs, addr)) + return 0; + return *(unsigned long *)addr; +}