kprobes: Introduce kprobe_handle_fault()
Subsystems (8)
PATCH 1/2 kprobes: Introduce kprobe_handle_fault()
Use a central kprobe_handle_fault() inline in kprobes.h to remove all of the arch-dependant, practically identical implementations in avr32, ia64, powerpc, s390, sparc64, and x86.
avr32 was the only arch without the preempt_disable/enable pair in its notify_page_fault implementation.
This uncovered a possible bug in the s390 version as that purely copied the x86 version unconditionally passing 14 as the trapnr rather than the error_code parameter. s390 is changed to pass error_code in this patch.
---
Andrew, 1/2 is low risk, 2/2 has been tested on x86-32 and 64, but the !preemptible invariant seems correct.
arch/arm/mm/fault.c | 25 +------------------------ arch/avr32/mm/fault.c | 21 +-------------------- arch/ia64/mm/fault.c | 24 +----------------------- arch/powerpc/mm/fault.c | 25 +------------------------ arch/s390/mm/fault.c | 25 +------------------------ arch/sparc64/mm/fault.c | 23 +---------------------- arch/x86/mm/fault.c | 26 ++------------------------ include/linux/kprobes.h | 20 ++++++++++++++++++++ 8 files changed, 28 insertions(+), 161 deletions(-)
arch/arm/mm/fault.c +1 -24
@@ -21,29 +21,6 @@#include "fault.h" - -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs,unsigned int fsr) -{ -int ret =0 ; - -if (!user_mode (regs)) { -/* kprobe_running() needs smp_processor_id() */ -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs, fsr)) - ret =1 ; -preempt_enable (); - } - -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs,unsigned int fsr) -{ -return 0 ; -} -#endif -/* * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'.
@@ -246,7 +223,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)struct mm_struct *mm;int fault, sig, code; -if (notify_page_fault (regs, fsr)) +if (handle_kprobe_fault (regs, fsr))return 0 ; tsk = current;
arch/avr32/mm/fault.c +1 -20
@@ -20,25 +20,6 @@#include <asm/tlb.h> #include <asm/uaccess.h> -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs,int trap) -{ -int ret =0 ; - -if (!user_mode (regs)) { -if (kprobe_running () &&kprobe_fault_handler (regs, trap)) - ret =1 ; - } - -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs,int trap) -{ -return 0 ; -} -#endif -int exception_trace =1 ;/*
@@ -66,7 +47,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)int code;int fault; -if (notify_page_fault (regs, ecr)) +if (kprobe_handle_fault (regs, ecr))return ; address =sysreg_read (TLBEAR );
arch/ia64/mm/fault.c +1 -23
@@ -18,28 +18,6 @@extern void die (char *,struct pt_regs *,long ); -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs,int trap) -{ -int ret =0 ; - -if (!user_mode (regs)) { -/* kprobe_running() needs smp_processor_id() */ -preempt_disable (); -if (kprobe_running () &&kprobes_fault_handler (regs, trap)) - ret =1 ; -preempt_enable (); - } - -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs,int trap) -{ -return 0 ; -} -#endif -/* * Return TRUE if ADDRESS points at a page in the kernel's mapped segment * (inside region 5, on ia64) and that page is present.
@@ -106,7 +84,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re/* * This is to handle the kprobes on user space access instructions */ -if (notify_page_fault (regs,TRAP_BRKPT )) +if (kprobe_handle_fault (regs,TRAP_BRKPT ))return ;down_read (&mm->mmap_sem);
arch/powerpc/mm/fault.c +1 -24
@@ -39,29 +39,6 @@#include <asm/tlbflush.h> #include <asm/siginfo.h> - -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs) -{ -int ret =0 ; - -/* kprobe_running() needs smp_processor_id() */ -if (!user_mode (regs)) { -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs,11 )) - ret =1 ; -preempt_enable (); - } - -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs) -{ -return 0 ; -} -#endif -/* * Check whether the instruction at regs->nip is a store using * an update addressing form which will update r1.
@@ -164,7 +141,7 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, is_write = error_code &ESR_DST ;#endif /* CONFIG_4xx || CONFIG_BOOKE */ -if (notify_page_fault (regs)) +if (kprobe_handle_fault (regs,11 ))return 0 ;if (unlikely (debugger_fault_handler (regs)))
arch/s390/mm/fault.c +1 -24
@@ -51,29 +51,6 @@ extern int sysctl_userprocess_debug;extern void die (const char *,struct pt_regs *,long ); -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs,long err) -{ -int ret =0 ; - -/* kprobe_running() needs smp_processor_id() */ -if (!user_mode (regs)) { -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs,14 )) - ret =1 ; -preempt_enable (); - } - -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs,long err) -{ -return 0 ; -} -#endif - -/* * Unlock any spinlocks which will prevent us from getting the * message out.
@@ -309,7 +286,7 @@ do_exception(struct pt_regs *regs, unsigned long error_code, int write)int si_code;int fault; -if (notify_page_fault (regs, error_code)) +if (kprobe_handle_fault (regs, error_code))return ; tsk = current;
arch/sparc64/mm/fault.c +1 -22
@@ -31,27 +31,6 @@#include <asm/sections.h> #include <asm/mmu_context.h> -#ifdef CONFIG_KPROBES -static inline int notify_page_fault (struct pt_regs *regs) -{ -int ret =0 ; - -/* kprobe_running() needs smp_processor_id() */ -if (!user_mode (regs)) { -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs,0 )) - ret =1 ; -preempt_enable (); - } -return ret; -} -#else -static inline int notify_page_fault (struct pt_regs *regs) -{ -return 0 ; -} -#endif -/* * To debug kernel to catch accesses to certain virtual/physical addresses. * Mode = 0 selects physical watchpoints, mode = 1 selects virtual watchpoints.
@@ -280,7 +259,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code =get_thread_fault_code (); -if (notify_page_fault (regs)) +if (kprobe_handle_fault (regs,0 ))return ; si_code =SEGV_MAPERR ;
arch/x86/mm/fault.c +2 -24
@@ -49,29 +49,6 @@#define PF_RSVD (1<<3)#define PF_INSTR (1<<4) -static inline int notify_page_fault (struct pt_regs *regs) -{ -#ifdef CONFIG_KPROBES - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ -#ifdef CONFIG_X86_32 - if (!user_mode_vm(regs)) { -#else - if (!user_mode(regs)) { -#endif - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 14)) - ret = 1; - preempt_enable(); - } - - return ret; -#else - return 0; -#endif -} -/* * X86_32 * Sometimes AMD Athlon/Opteron CPUs report invalid exceptions on prefetch.
@@ -589,7 +566,8 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) si_code =SEGV_MAPERR ; -if (notify_page_fault (regs)) +/* Must not try to handle kprobes in v8086 mode */ +if (!v8086_mode (regs) &&kprobe_handle_fault (regs,14 ))return ;/*
include/linux/kprobes.h +20 -0
@@ -36,6 +36,7 @@#include <linux/spinlock.h> #include <linux/rcupdate.h> #include <linux/mutex.h> +#include <linux/hardirq.h> #ifdef CONFIG_KPROBES #include <asm/kprobes.h>
@@ -212,6 +213,21 @@ static inline struct kprobe *kprobe_running(void)return (__get_cpu_var (current_kprobe)); } +static inline int kprobe_handle_fault (struct pt_regs *regs,int trapnr) +{ +int ret =0 ; + +/* kprobe_running() needs smp_processor_id() */ +if (!user_mode (regs)) { +preempt_disable (); +if (kprobe_running () &&kprobe_fault_handler (regs, trapnr)) + ret =1 ; +preempt_enable (); + } + +return ret; +} +static inline void reset_current_kprobe (void ) {__get_cpu_var (current_kprobe) =NULL ;
@@ -247,6 +263,10 @@ static inline struct kprobe *kprobe_running(void) {return NULL ; } +static inline int kprobe_handle_fault (struct pt_regs *regs,int trapnr) +{ +return 0 ; +}static inline int register_kprobe (struct kprobe *p) {return -ENOSYS ;
Signature · 1 line
1.5.4.rc4.1142.gf5a97
Quoted 7 lines · Harvey Harrison
Use a central
kprobe_handle_fault()inline inkprobes.hto remove all of the arch-dependant, practically identical implementations in avr32, ia64, powerpc, s390, sparc64, and x86.avr32 was the only arch without the preempt_disable/enable pair in its
notify_page_faultimplementation.
Quoted 6 lines
This uncovered a possible bug in the s390 version as that purely copied the x86 version unconditionally passing 14 as the trapnr rather than the
error_codeparameter. s390 is changed to passerror_codein this patch.Signed-off-by Harvey Harrison <[email protected]>
for the s390 bits:
Quoted 7 lines · Harvey Harrison
Use a central
kprobe_handle_fault()inline inkprobes.hto remove all of the arch-dependant, practically identical implementations in avr32, ia64, powerpc, s390, sparc64, and x86.avr32 was the only arch without the preempt_disable/enable pair in its
notify_page_faultimplementation.
Quoted 6 lines
This uncovered a possible bug in the s390 version as that purely copied the x86 version unconditionally passing 14 as the trapnr rather than the
error_codeparameter. s390 is changed to passerror_codein this patch.Signed-off-by Harvey Harrison <[email protected]>
Tested on i386/x86-64.
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected]
Quoted 17 lines · On Sat, 02 Feb 2008 19:00:23 -0800 Harvey Harrison <[email protected]>…
Use a central
kprobe_handle_fault()inline inkprobes.hto remove all of the arch-dependant, practically identical implementations in avr32, ia64, powerpc, s390, sparc64, and x86.avr32 was the only arch without the preempt_disable/enable pair in its
notify_page_faultimplementation.This uncovered a possible bug in the s390 version as that purely copied the x86 version unconditionally passing 14 as the trapnr rather than the
error_codeparameter. s390 is changed to passerror_codein this patch.Signed-off-by Harvey Harrison <[email protected]>---
Andrew, 1/2 is low risk, 2/2 has been tested on x86-32 and 64, but the !preemptible invariant seems correct.
Quoted 9 lines
arch/arm/mm/fault.c | 25 +------------------------ arch/avr32/mm/fault.c | 21 +-------------------- arch/ia64/mm/fault.c | 24 +----------------------- arch/powerpc/mm/fault.c | 25 +------------------------ arch/s390/mm/fault.c | 25 +------------------------ arch/sparc64/mm/fault.c | 23 +---------------------- arch/x86/mm/fault.c | 26 ++------------------------ include/linux/kprobes.h | 20 ++++++++++++++++++++ 8 files changed, 28 insertions(+), 161 deletions(-)
Breaks the ia64 build:
include/linux/kprobes.h: In function `kprobe_handle_fault':include/linux/kprobes.h:234: error: implicit declaration of function `kprobe_fault_handler'
and ia64 doesn't implement kprobe_fault_handler() so there's no easy fix here.
There's too much inlining in linux/kprobes.h, btw.
Quoted 29 lines · Andrew Morton
Quoted 17 lines · On Sat, 02 Feb 2008 19:00:23 -0800 Harvey Harrison <[email protected]>…
Use a central
kprobe_handle_fault()inline inkprobes.hto remove all of the arch-dependant, practically identical implementations in avr32, ia64, powerpc, s390, sparc64, and x86.avr32 was the only arch without the preempt_disable/enable pair in its
notify_page_faultimplementation.This uncovered a possible bug in the s390 version as that purely copied the x86 version unconditionally passing 14 as the trapnr rather than the
error_codeparameter. s390 is changed to passerror_codein this patch.Signed-off-by Harvey Harrison <[email protected]>---
Andrew, 1/2 is low risk, 2/2 has been tested on x86-32 and 64, but the !preemptible invariant seems correct.Quoted 9 lines
arch/arm/mm/fault.c | 25 +------------------------ arch/avr32/mm/fault.c | 21 +-------------------- arch/ia64/mm/fault.c | 24 +----------------------- arch/powerpc/mm/fault.c | 25 +------------------------ arch/s390/mm/fault.c | 25 +------------------------ arch/sparc64/mm/fault.c | 23 +---------------------- arch/x86/mm/fault.c | 26 ++------------------------ include/linux/kprobes.h | 20 ++++++++++++++++++++ 8 files changed, 28 insertions(+), 161 deletions(-)
Quoted 7 lines
Breaks the ia64 build:
include/linux/kprobes.h: In function `kprobe_handle_fault':
include/linux/kprobes.h:234: error: implicit declaration of function `kprobe_fault_handler'and ia64 doesn't implement
kprobe_fault_handler()so there's no easy fix here.
Yes there is, ia64 apparently called theirs kprobes_handle_fault, sorry I didn't notice the extra 's'. Want a new patch, or will you change the three occurances?
Harvey