As a foundation patch, new structure called arch_misc_regs added to perf_regs. And perf_reg_value() is modified to expect perf_regs instead of pt_regs. This way, perf_reg_value() can decide on the struct to pick based on the register idx.
Signed-off-by: Madhavan Srinivasan <ma...@linux.vnet.ibm.com> Cc: Thomas Gleixner <t...@linutronix.de> Cc: Ingo Molnar <mi...@kernel.org> Cc: Peter Zijlstra <pet...@infradead.org> Cc: Jiri Olsa <jo...@kernel.org> Cc: Arnaldo Carvalho de Melo <a...@kernel.org> Cc: Stephane Eranian <eran...@gmail.com> Cc: Russell King <li...@arm.linux.org.uk> Cc: Catalin Marinas <catalin.mari...@arm.com> Cc: Will Deacon <will.dea...@arm.com> Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org> Cc: Michael Ellerman <m...@ellerman.id.au> Cc: Sukadev Bhattiprolu <suka...@linux.vnet.ibm.com> --- Will really appreciate comments and feedback for the patch arch/arm/include/asm/ptrace.h | 2 ++ arch/arm/kernel/perf_regs.c | 4 +++- arch/arm64/include/asm/ptrace.h | 2 ++ arch/arm64/kernel/perf_regs.c | 4 +++- arch/powerpc/include/uapi/asm/ptrace.h | 2 ++ arch/powerpc/perf/perf_regs.c | 4 +++- arch/x86/include/asm/ptrace.h | 2 ++ arch/x86/kernel/perf_regs.c | 4 +++- include/linux/perf_regs.h | 5 +++-- kernel/events/core.c | 6 +++--- 10 files changed, 26 insertions(+), 9 deletions(-) diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h index 51622ba7c4a6..26cd8dbf1f02 100644 --- a/arch/arm/include/asm/ptrace.h +++ b/arch/arm/include/asm/ptrace.h @@ -17,6 +17,8 @@ struct pt_regs { unsigned long uregs[18]; }; +struct arch_misc_regs {}; + #define user_mode(regs) \ (((regs)->ARM_cpsr & 0xf) == 0) diff --git a/arch/arm/kernel/perf_regs.c b/arch/arm/kernel/perf_regs.c index 592dda3f21ff..18999abbadbe 100644 --- a/arch/arm/kernel/perf_regs.c +++ b/arch/arm/kernel/perf_regs.c @@ -6,8 +6,10 @@ #include <asm/perf_regs.h> #include <asm/ptrace.h> -u64 perf_reg_value(struct pt_regs *regs, int idx) +u64 perf_reg_value(struct perf_regs *p_regs, int idx) { + struct pt_regs *regs = p_regs->regs; + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM_MAX)) return 0; diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 536274ed292e..9a33ab69f19f 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -118,6 +118,8 @@ struct pt_regs { u64 syscallno; }; +struct arch_misc_regs {}; + #define arch_has_single_step() (1) #ifdef CONFIG_COMPAT diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c index 3f62b35fb6f1..8ee80d7c8604 100644 --- a/arch/arm64/kernel/perf_regs.c +++ b/arch/arm64/kernel/perf_regs.c @@ -7,8 +7,10 @@ #include <asm/perf_regs.h> #include <asm/ptrace.h> -u64 perf_reg_value(struct pt_regs *regs, int idx) +u64 perf_reg_value(struct perf_regs *p_regs, int idx) { + struct pt_regs *regs = p_regs->regs; + if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX)) return 0; diff --git a/arch/powerpc/include/uapi/asm/ptrace.h b/arch/powerpc/include/uapi/asm/ptrace.h index 8036b385417d..0025651ab8bc 100644 --- a/arch/powerpc/include/uapi/asm/ptrace.h +++ b/arch/powerpc/include/uapi/asm/ptrace.h @@ -51,6 +51,8 @@ struct pt_regs { unsigned long result; /* Result of a system call */ }; +struct arch_misc_regs {}; + #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/perf/perf_regs.c b/arch/powerpc/perf/perf_regs.c index 0520492d4078..f7995b46078a 100644 --- a/arch/powerpc/perf/perf_regs.c +++ b/arch/powerpc/perf/perf_regs.c @@ -61,8 +61,10 @@ static unsigned int pt_regs_offset[PERF_REG_POWERPC_MAX] = { PT_REGS_OFFSET(PERF_REG_POWERPC_DSISR, dsisr), }; -u64 perf_reg_value(struct pt_regs *regs, int idx) +u64 perf_reg_value(struct perf_regs *p_regs, int idx) { + struct pt_regs *regs = p_regs->regs; + if (WARN_ON_ONCE(idx >= PERF_REG_POWERPC_MAX)) return 0; return regs_get_register(regs, pt_regs_offset[idx]); diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 6271281f947d..410a2eb885c1 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h @@ -67,6 +67,8 @@ struct pt_regs { #endif /* !__i386__ */ +struct arch_misc_regs {}; + #ifdef CONFIG_PARAVIRT #include <asm/paravirt_types.h> #endif diff --git a/arch/x86/kernel/perf_regs.c b/arch/x86/kernel/perf_regs.c index da8cb987b973..c6e41f7f648b 100644 --- a/arch/x86/kernel/perf_regs.c +++ b/arch/x86/kernel/perf_regs.c @@ -55,8 +55,10 @@ static unsigned int pt_regs_offset[PERF_REG_X86_MAX] = { #endif }; -u64 perf_reg_value(struct pt_regs *regs, int idx) +u64 perf_reg_value(struct perf_regs *p_regs, int idx) { + struct pt_regs *regs = p_regs->regs; + if (WARN_ON_ONCE(idx >= ARRAY_SIZE(pt_regs_offset))) return 0; diff --git a/include/linux/perf_regs.h b/include/linux/perf_regs.h index a5f98d53d732..7727a30e7d84 100644 --- a/include/linux/perf_regs.h +++ b/include/linux/perf_regs.h @@ -4,18 +4,19 @@ struct perf_regs { __u64 abi; struct pt_regs *regs; + struct arch_misc_regs *arch_regs; }; #ifdef CONFIG_HAVE_PERF_REGS #include <asm/perf_regs.h> -u64 perf_reg_value(struct pt_regs *regs, int idx); +u64 perf_reg_value(struct perf_regs *p_regs, int idx); int perf_reg_validate(u64 mask); u64 perf_reg_abi(struct task_struct *task); void perf_get_regs_user(struct perf_regs *regs_user, struct pt_regs *regs, struct pt_regs *regs_user_copy); #else -static inline u64 perf_reg_value(struct pt_regs *regs, int idx) +static inline u64 perf_reg_value(struct perf_regs *p_regs, int idx) { return 0; } diff --git a/kernel/events/core.c b/kernel/events/core.c index b11756f9b6dc..c04bdad3d365 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -4934,7 +4934,7 @@ EXPORT_SYMBOL_GPL(perf_unregister_guest_info_callbacks); static void perf_output_sample_regs(struct perf_output_handle *handle, - struct pt_regs *regs, u64 mask) + struct perf_regs *regs, u64 mask) { int bit; @@ -5331,7 +5331,7 @@ void perf_output_sample(struct perf_output_handle *handle, if (abi) { u64 mask = event->attr.sample_regs_user; perf_output_sample_regs(handle, - data->regs_user.regs, + &data->regs_user, mask); } } @@ -5363,7 +5363,7 @@ void perf_output_sample(struct perf_output_handle *handle, u64 mask = event->attr.sample_regs_intr; perf_output_sample_regs(handle, - data->regs_intr.regs, + &data->regs_intr, mask); } } -- 1.9.1 _______________________________________________ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev