x86: Use is_kprobe_fault to better match usage
PATCH 1/1 x86: Use is_kprobe_fault to better match usage
Currently the notify_page_fault helper is used to test it the page fault was caused by a kprobe causing an early return from do_page_fault.
Change the name of the helper to is_kprobe_fault to match the usage and remove the preempt_disable/enable pair around kprobe_running() with an explicit test for preemption. The idea for this comes from a patch by Quentin Barnes to kprobes.c
---
Ingo, this may not be functionally equivalent, feel free to yank it out if there is any trouble, but from what I've seen it should be OK.
Did you ever find a good kprobes test?
arch/x86/mm/fault_32.c | 30 ++++++++++++++---------------- arch/x86/mm/fault_64.c | 30 ++++++++++++++---------------- 2 files changed, 28 insertions(+), 32 deletions(-)
arch/x86/mm/fault_32.c +14 -16
@@ -12,6 +12,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> +#include <linux/hardirq.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/tty.h>
@@ -42,23 +43,20 @@#define PF_RSVD (1<<3)#define PF_INSTR (1<<4) -static inline int notify_page_fault (struct pt_regs *regs) +static inline int is_kprobe_fault (struct pt_regs *regs) { -#ifdef CONFIG_KPROBES int ret =0 ; - -/* kprobe_running() needs smp_processor_id() */ -if (!user_mode_vm (regs)) { -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs,14 )) - ret =1 ; -preempt_enable (); - } - -return ret; -#else -return 0 ; +#ifdef CONFIG_KPROBES +/* +* If it is a kprobe fault we can not be premptible so return before +* calling kprobe_running() as it will assert on smp_processor_id if +* preemption is enabled. +*/ +if (!user_mode_vm (regs) && !preemptible () &&kprobe_running () && +kprobe_fault_handler (regs,14 )) + ret =1 ;#endif +return ret; }#ifdef CONFIG_X86_32
@@ -428,7 +426,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) return; }#endif -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* * Don't take the mm semaphore here. If we fixup a prefetch
@@ -437,7 +435,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) goto bad_area_nosemaphore; } -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* It's safe to allow irq's after cr2 has been saved and the vmalloc
arch/x86/mm/fault_64.c +14 -16
@@ -13,6 +13,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> +#include <linux/hardirq.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/tty.h>
@@ -45,23 +46,20 @@#define PF_RSVD (1<<3)#define PF_INSTR (1<<4) -static inline int notify_page_fault (struct pt_regs *regs) +static inline int is_kprobe_fault (struct pt_regs *regs) { -#ifdef CONFIG_KPROBES 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 -return 0 ; +#ifdef CONFIG_KPROBES +/* +* If it is a kprobe fault we can not be premptible so return before +* calling kprobe_running() as it will assert on smp_processor_id if +* preemption is enabled. +*/ +if (!user_mode_vm (regs) && !preemptible () &&kprobe_running () && +kprobe_fault_handler (regs,14 )) + ret =1 ;#endif +return ret; }#ifdef CONFIG_X86_32
@@ -478,7 +476,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, return; }#endif -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* * Don't take the mm semaphore here. If we fixup a prefetch
@@ -487,7 +485,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;if (likely (regs->flags &X86_EFLAGS_IF ))
Signature · 1 line
1.5.4.rc2.1097.gb6e0d
Hi Harvey,
Quoted 7 lines · Harvey Harrison
Currently the
notify_page_faulthelper is used to test it the page fault was caused by a kprobe causing an early return fromdo_page_fault.Change the name of the helper to
is_kprobe_faultto match the usage and remove the preempt_disable/enable pair aroundkprobe_running()with an explicit test for preemption. The idea for this comes from a patch by Quentin Barnes tokprobes.c
Sure, that's right.
However, since other architectures also have notify_page_fault(), I think all of those code might better be changed same time for maintainability.
Thanks,
Quoted 141 lines
Signed-off-by Harvey Harrison <[email protected]>---
Ingo, this may not be functionally equivalent, feel free to yank it out if there is any trouble, but from what I've seen it should be OK.Did you ever find a good kprobes test?
arch/x86/mm/fault_32.c | 30 ++++++++++++++---------------- arch/x86/mm/fault_64.c | 30 ++++++++++++++---------------- 2 files changed, 28 insertions(+), 32 deletions(-)arch/x86/mm/fault_32.c +14
-16@@ -12,6 +12,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> +#include <linux/hardirq.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/tty.h> @@ -42,23 +43,20 @@#define PF_RSVD (1<<3)#define PF_INSTR (1<<4) -static inline int notify_page_fault (struct pt_regs *regs) +static inline int is_kprobe_fault (struct pt_regs *regs) { -#ifdef CONFIG_KPROBES int ret =0 ; - -/* kprobe_running() needs smp_processor_id() */ -if (!user_mode_vm (regs)) { -preempt_disable (); -if (kprobe_running () &&kprobe_fault_handler (regs,14 )) - ret =1 ; -preempt_enable (); - } - -return ret; -#else -return 0 ; +#ifdef CONFIG_KPROBES +/* +* If it is a kprobe fault we can not be premptible so return before +* calling kprobe_running() as it will assert on smp_processor_id if +* preemption is enabled. +*/ +if (!user_mode_vm (regs) && !preemptible () &&kprobe_running () && +kprobe_fault_handler (regs,14 )) + ret =1 ;#endif +return ret; }#ifdef CONFIG_X86_32 @@ -428,7 +426,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) return; }#endif -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* * Don't take the mm semaphore here. If we fixup a prefetch @@ -437,7 +435,7 @@ void __kprobes do_page_fault(struct pt_regs *regs, unsigned long error_code) goto bad_area_nosemaphore; } -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* It's safe to allow irq's after cr2 has been saved and the vmalloc arch/x86/mm/fault_64.c +14
-16@@ -13,6 +13,7 @@#include <linux/mman.h> #include <linux/mm.h> #include <linux/smp.h> +#include <linux/hardirq.h> #include <linux/interrupt.h> #include <linux/init.h> #include <linux/tty.h> @@ -45,23 +46,20 @@#define PF_RSVD (1<<3)#define PF_INSTR (1<<4) -static inline int notify_page_fault (struct pt_regs *regs) +static inline int is_kprobe_fault (struct pt_regs *regs) { -#ifdef CONFIG_KPROBES 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 -return 0 ; +#ifdef CONFIG_KPROBES +/* +* If it is a kprobe fault we can not be premptible so return before +* calling kprobe_running() as it will assert on smp_processor_id if +* preemption is enabled. +*/ +if (!user_mode_vm (regs) && !preemptible () &&kprobe_running () && +kprobe_fault_handler (regs,14 )) + ret =1 ;#endif +return ret; }#ifdef CONFIG_X86_32 @@ -478,7 +476,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, return; }#endif -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;/* * Don't take the mm semaphore here. If we fixup a prefetch @@ -487,7 +485,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, goto bad_area_nosemaphore; } -if (notify_page_fault (regs)) +if (is_kprobe_fault (regs))return ;if (likely (regs->flags &X86_EFLAGS_IF ))
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 11 lines · Masami Hiramatsu
Hi Harvey,
Quoted 7 lines · Harvey Harrison
Currently the
notify_page_faulthelper is used to test it the page fault was caused by a kprobe causing an early return fromdo_page_fault.Change the name of the helper to
is_kprobe_faultto match the usage and remove the preempt_disable/enable pair aroundkprobe_running()with an explicit test for preemption. The idea for this comes from a patch by Quentin Barnes tokprobes.c
Quoted 5 lines
Sure, that's right.
However, since other architectures also havenotify_page_fault(), I think all of those code might better be changed same time for maintainability.
How about a static inline in linux/kprobes.h with a big comment above about when/why the !preemptible() check is sufficient?
Harvey
Quoted 11 lines · Harvey Harrison
Quoted 10 lines · Masami Hiramatsu
Hi Harvey,
Quoted 7 lines · Harvey Harrison
Currently the
notify_page_faulthelper is used to test it the page fault was caused by a kprobe causing an early return fromdo_page_fault.Change the name of the helper to
is_kprobe_faultto match the usage and remove the preempt_disable/enable pair aroundkprobe_running()with an explicit test for preemption. The idea for this comes from a patch by Quentin Barnes tokprobes.c
Quoted 8 lines
Quoted 5 lines
Sure, that's right.
However, since other architectures also havenotify_page_fault(), I think all of those code might better be changed same time for maintainability.How about a static inline in
linux/kprobes.hwith a big comment above about when/why the !preemptible() check is sufficient?
Hmm, fault handling depends on the architecture. But current notify_page_fault()s are very similar. I think unifying it is good idea. We will be happy to review that if you send it.
Many thanks!
Quoted 5 lines
Harvey
Signature · 7 lines
Masami Hiramatsu Software Engineer Hitachi Computer Products (America) Inc. Software Solutions Division e-mail: [email protected], [email protected]
Quoted 10 lines · Harvey Harrison
Currently the
notify_page_faulthelper is used to test it the page fault was caused by a kprobe causing an early return fromdo_page_fault.Change the name of the helper to
is_kprobe_faultto match the usage and remove the preempt_disable/enable pair aroundkprobe_running()with an explicit test for preemption. The idea for this comes from a patch by Quentin Barnes tokprobes.cSigned-off-by Harvey Harrison <[email protected]>
hm, this doesnt apply:
Hunk #3 FAILED at 426.
Hunk #4 succeeded at 413 (offset -22 lines).
1 out of 4 hunks FAILED -- rejects in file arch/x86/mm/fault_32.c patching file arch/x86/mm/fault_64.c
Hunk #3 FAILED at 476.
Hunk #4 succeeded at 475 (offset -10 lines).
1 out of 4 hunks FAILED -- rejects in file arch/x86/mm/fault_64.c
could you double-check x86.git#mm, perhaps we are out of sync with a patch somewhere?
Ingo