On Thu, 2024-02-01 at 15:46 +0000, Jiaxun Yang wrote: > On architectures with delay slot, architecture level instruction > pointer (or program counter) in pt_regs may differ from where > exception was triggered. > > Introduce exception_ip hook to invoke architecture code and determine > actual instruction pointer to the exception. > > Link: > https://lore.kernel.org/lkml/00d1b813-c55f-4365-8d81-d70258e10b16@xxxxxxxxxxxxxxxx/ > Signed-off-by: Jiaxun Yang <jiaxun.yang@xxxxxxxxxxx> How about adding something like #ifndef arch_exception_ip #define exception_ip(regs) instruction_pointer(regs) #else #define exception_ip(regs) arch_exception_ip(regs) #endif into a generic header, instead of having to add exception_ip definition everywhere? > --- > arch/alpha/include/asm/ptrace.h | 1 + > arch/arc/include/asm/ptrace.h | 1 + > arch/arm/include/asm/ptrace.h | 1 + > arch/csky/include/asm/ptrace.h | 1 + > arch/hexagon/include/uapi/asm/ptrace.h | 1 + > arch/loongarch/include/asm/ptrace.h | 1 + > arch/m68k/include/asm/ptrace.h | 1 + > arch/microblaze/include/asm/ptrace.h | 3 ++- > arch/mips/include/asm/ptrace.h | 1 + > arch/mips/kernel/ptrace.c | 7 +++++++ > arch/nios2/include/asm/ptrace.h | 3 ++- > arch/openrisc/include/asm/ptrace.h | 1 + > arch/parisc/include/asm/ptrace.h | 1 + > arch/s390/include/asm/ptrace.h | 1 + > arch/sparc/include/asm/ptrace.h | 2 ++ > arch/um/include/asm/ptrace-generic.h | 1 + > 16 files changed, 25 insertions(+), 2 deletions(-) > > diff --git a/arch/alpha/include/asm/ptrace.h > b/arch/alpha/include/asm/ptrace.h > index 3557ce64ed21..1ded3f2d09e9 100644 > --- a/arch/alpha/include/asm/ptrace.h > +++ b/arch/alpha/include/asm/ptrace.h > @@ -8,6 +8,7 @@ > #define arch_has_single_step() (1) > #define user_mode(regs) (((regs)->ps & 8) != 0) > #define instruction_pointer(regs) ((regs)->pc) > +#define exception_ip(regs) instruction_pointer(regs) > #define profile_pc(regs) instruction_pointer(regs) > #define current_user_stack_pointer() rdusp() > > diff --git a/arch/arc/include/asm/ptrace.h > b/arch/arc/include/asm/ptrace.h > index 00b9318e551e..94084f1048df 100644 > --- a/arch/arc/include/asm/ptrace.h > +++ b/arch/arc/include/asm/ptrace.h > @@ -105,6 +105,7 @@ struct callee_regs { > #endif > > #define instruction_pointer(regs) ((regs)->ret) > +#define exception_ip(regs) instruction_pointer(regs) > #define profile_pc(regs) instruction_pointer(regs) > > /* return 1 if user mode or 0 if kernel mode */ > diff --git a/arch/arm/include/asm/ptrace.h > b/arch/arm/include/asm/ptrace.h > index 7f44e88d1f25..fb4dc23eba78 100644 > --- a/arch/arm/include/asm/ptrace.h > +++ b/arch/arm/include/asm/ptrace.h > @@ -89,6 +89,7 @@ static inline long regs_return_value(struct pt_regs > *regs) > } > > #define instruction_pointer(regs) (regs)->ARM_pc > +#define > exception_ip(regs) instruction_pointer(regs) > > #ifdef CONFIG_THUMB2_KERNEL > #define frame_pointer(regs) (regs)->ARM_r7 > diff --git a/arch/csky/include/asm/ptrace.h > b/arch/csky/include/asm/ptrace.h > index 0634b7895d81..a738630e64b0 100644 > --- a/arch/csky/include/asm/ptrace.h > +++ b/arch/csky/include/asm/ptrace.h > @@ -22,6 +22,7 @@ > > #define user_mode(regs) (!((regs)->sr & PS_S)) > #define instruction_pointer(regs) ((regs)->pc) > +#define exception_ip(regs) instruction_pointer(regs) > #define profile_pc(regs) instruction_pointer(regs) > #define trap_no(regs) ((regs->sr >> 16) & 0xff) > > diff --git a/arch/hexagon/include/uapi/asm/ptrace.h > b/arch/hexagon/include/uapi/asm/ptrace.h > index 2a3ea14ad9b9..846471936237 100644 > --- a/arch/hexagon/include/uapi/asm/ptrace.h > +++ b/arch/hexagon/include/uapi/asm/ptrace.h > @@ -25,6 +25,7 @@ > #include <asm/registers.h> > > #define instruction_pointer(regs) pt_elr(regs) > +#define exception_ip(regs) instruction_pointer(regs) > #define user_stack_pointer(regs) ((regs)->r29) > > #define profile_pc(regs) instruction_pointer(regs) > diff --git a/arch/loongarch/include/asm/ptrace.h > b/arch/loongarch/include/asm/ptrace.h > index f3ddaed9ef7f..a34327f0e69d 100644 > --- a/arch/loongarch/include/asm/ptrace.h > +++ b/arch/loongarch/include/asm/ptrace.h > @@ -160,6 +160,7 @@ static inline void regs_set_return_value(struct > pt_regs *regs, unsigned long val > } > > #define instruction_pointer(regs) ((regs)->csr_era) > +#define exception_ip(regs) instruction_pointer(regs) > #define profile_pc(regs) instruction_pointer(regs) > > extern void die(const char *str, struct pt_regs *regs); > diff --git a/arch/m68k/include/asm/ptrace.h > b/arch/m68k/include/asm/ptrace.h > index ea5a80ca1ab3..cb553e2ec73a 100644 > --- a/arch/m68k/include/asm/ptrace.h > +++ b/arch/m68k/include/asm/ptrace.h > @@ -13,6 +13,7 @@ > > #define user_mode(regs) (!((regs)->sr & PS_S)) > #define instruction_pointer(regs) ((regs)->pc) > +#define exception_ip(regs) instruction_pointer(regs) > #define profile_pc(regs) instruction_pointer(regs) > #define current_pt_regs() \ > (struct pt_regs *)((char *)current_thread_info() + > THREAD_SIZE) - 1 > diff --git a/arch/microblaze/include/asm/ptrace.h > b/arch/microblaze/include/asm/ptrace.h > index bfcb89df5e26..974c00fa7212 100644 > --- a/arch/microblaze/include/asm/ptrace.h > +++ b/arch/microblaze/include/asm/ptrace.h > @@ -12,7 +12,8 @@ > #define user_mode(regs) (!kernel_mode(regs)) > > #define instruction_pointer(regs) ((regs)->pc) > -#define profile_pc(regs) instruction_pointer(regs) > +#define > exception_ip(regs) instruction_pointer(regs) > +#define > profile_pc(regs) instruction_pointer(regs) > #define user_stack_pointer(regs) ((regs)->r1) > > static inline long regs_return_value(struct pt_regs *regs) > diff --git a/arch/mips/include/asm/ptrace.h > b/arch/mips/include/asm/ptrace.h > index daf3cf244ea9..97589731fd40 100644 > --- a/arch/mips/include/asm/ptrace.h > +++ b/arch/mips/include/asm/ptrace.h > @@ -154,6 +154,7 @@ static inline long regs_return_value(struct > pt_regs *regs) > } > > #define instruction_pointer(regs) ((regs)->cp0_epc) > +extern unsigned long exception_ip(struct pt_regs *regs); > #define profile_pc(regs) instruction_pointer(regs) > > extern asmlinkage long syscall_trace_enter(struct pt_regs *regs, long > syscall); > diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c > index d9df543f7e2c..59288c13b581 100644 > --- a/arch/mips/kernel/ptrace.c > +++ b/arch/mips/kernel/ptrace.c > @@ -31,6 +31,7 @@ > #include <linux/seccomp.h> > #include <linux/ftrace.h> > > +#include <asm/branch.h> > #include <asm/byteorder.h> > #include <asm/cpu.h> > #include <asm/cpu-info.h> > @@ -48,6 +49,12 @@ > #define CREATE_TRACE_POINTS > #include <trace/events/syscalls.h> > > +unsigned long exception_ip(struct pt_regs *regs) > +{ > + return exception_epc(regs); > +} > +EXPORT_SYMBOL(exception_ip); > + > /* > * Called by kernel/ptrace.c when detaching.. > * > diff --git a/arch/nios2/include/asm/ptrace.h > b/arch/nios2/include/asm/ptrace.h > index 9da34c3022a2..136f5679ae79 100644 > --- a/arch/nios2/include/asm/ptrace.h > +++ b/arch/nios2/include/asm/ptrace.h > @@ -66,7 +66,8 @@ struct switch_stack { > #define user_mode(regs) (((regs)->estatus & ESTATUS_EU)) > > #define instruction_pointer(regs) ((regs)->ra) > -#define profile_pc(regs) instruction_pointer(regs) > +#define > exception_ip(regs) instruction_pointer(regs) > +#define > profile_pc(regs) instruction_pointer(regs) > #define user_stack_pointer(regs) ((regs)->sp) > extern void show_regs(struct pt_regs *); > > diff --git a/arch/openrisc/include/asm/ptrace.h > b/arch/openrisc/include/asm/ptrace.h > index 375147ff71fc..67c28484d17e 100644 > --- a/arch/openrisc/include/asm/ptrace.h > +++ b/arch/openrisc/include/asm/ptrace.h > @@ -67,6 +67,7 @@ struct pt_regs { > #define STACK_FRAME_OVERHEAD 128 /* size of minimum stack frame */ > > #define instruction_pointer(regs) ((regs)->pc) > +#define > exception_ip(regs) instruction_pointer(regs) > #define user_mode(regs) (((regs)->sr & > SPR_SR_SM) == 0) > #define user_stack_pointer(regs) ((unsigned long)(regs)->sp) > #define profile_pc(regs) instruction_pointer(regs) > diff --git a/arch/parisc/include/asm/ptrace.h > b/arch/parisc/include/asm/ptrace.h > index eea3f3df0823..d7e8dcf26582 100644 > --- a/arch/parisc/include/asm/ptrace.h > +++ b/arch/parisc/include/asm/ptrace.h > @@ -17,6 +17,7 @@ > #define user_mode(regs) (((regs)->iaoq[0] & > 3) != PRIV_KERNEL) > #define user_space(regs) ((regs)->iasq[1] != > PRIV_KERNEL) > #define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) > +#define > exception_ip(regs) instruction_pointer(regs) > #define user_stack_pointer(regs) ((regs)->gr[30]) > unsigned long profile_pc(struct pt_regs *); > > diff --git a/arch/s390/include/asm/ptrace.h > b/arch/s390/include/asm/ptrace.h > index d28bf8fb2799..a5255b2337af 100644 > --- a/arch/s390/include/asm/ptrace.h > +++ b/arch/s390/include/asm/ptrace.h > @@ -211,6 +211,7 @@ static inline int > test_and_clear_pt_regs_flag(struct pt_regs *regs, int flag) > > #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) > #define instruction_pointer(regs) ((regs)->psw.addr) > +#define exception_ip(regs) instruction_pointer(regs) > #define user_stack_pointer(regs)((regs)->gprs[15]) > #define profile_pc(regs) instruction_pointer(regs) > > diff --git a/arch/sparc/include/asm/ptrace.h > b/arch/sparc/include/asm/ptrace.h > index d1419e669027..41ae186f2245 100644 > --- a/arch/sparc/include/asm/ptrace.h > +++ b/arch/sparc/include/asm/ptrace.h > @@ -63,6 +63,7 @@ extern union global_cpu_snapshot > global_cpu_snapshot[NR_CPUS]; > #define force_successful_syscall_return() set_thread_noerror(1) > #define user_mode(regs) (!((regs)->tstate & TSTATE_PRIV)) > #define instruction_pointer(regs) ((regs)->tpc) > +#define exception_ip(regs) instruction_pointer(regs) > #define instruction_pointer_set(regs, val) do { \ > (regs)->tpc = (val); \ > (regs)->tnpc = (val)+4; \ > @@ -142,6 +143,7 @@ static inline bool pt_regs_clear_syscall(struct > pt_regs *regs) > > #define user_mode(regs) (!((regs)->psr & PSR_PS)) > #define instruction_pointer(regs) ((regs)->pc) > +#define exception_ip(regs) instruction_pointer(regs) > #define user_stack_pointer(regs) ((regs)->u_regs[UREG_FP]) > unsigned long profile_pc(struct pt_regs *); > #else /* (!__ASSEMBLY__) */ > diff --git a/arch/um/include/asm/ptrace-generic.h > b/arch/um/include/asm/ptrace-generic.h > index adf91ef553ae..f9ada287ca12 100644 > --- a/arch/um/include/asm/ptrace-generic.h > +++ b/arch/um/include/asm/ptrace-generic.h > @@ -26,6 +26,7 @@ struct pt_regs { > #define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) > > #define instruction_pointer(regs) PT_REGS_IP(regs) > +#define exception_ip(regs) instruction_pointer(regs) > > #define PTRACE_OLDSETOPTIONS 21 > > -- Xi Ruoyao <xry111@xxxxxxxxxxx> School of Aerospace Science and Technology, Xidian University