diff options
Diffstat (limited to 'arch/x86/mm/fault.c')
-rw-r--r-- | arch/x86/mm/fault.c | 26 |
1 files changed, 14 insertions, 12 deletions
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index a5b9ddb0f1fe..0d45f6debb3a 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c | |||
@@ -46,17 +46,19 @@ kmmio_fault(struct pt_regs *regs, unsigned long addr) | |||
46 | 46 | ||
47 | static nokprobe_inline int kprobes_fault(struct pt_regs *regs) | 47 | static nokprobe_inline int kprobes_fault(struct pt_regs *regs) |
48 | { | 48 | { |
49 | int ret = 0; | 49 | if (!kprobes_built_in()) |
50 | 50 | return 0; | |
51 | /* kprobe_running() needs smp_processor_id() */ | 51 | if (user_mode(regs)) |
52 | if (kprobes_built_in() && !user_mode(regs)) { | 52 | return 0; |
53 | preempt_disable(); | 53 | /* |
54 | if (kprobe_running() && kprobe_fault_handler(regs, 14)) | 54 | * To be potentially processing a kprobe fault and to be allowed to call |
55 | ret = 1; | 55 | * kprobe_running(), we have to be non-preemptible. |
56 | preempt_enable(); | 56 | */ |
57 | } | 57 | if (preemptible()) |
58 | 58 | return 0; | |
59 | return ret; | 59 | if (!kprobe_running()) |
60 | return 0; | ||
61 | return kprobe_fault_handler(regs, X86_TRAP_PF); | ||
60 | } | 62 | } |
61 | 63 | ||
62 | /* | 64 | /* |
@@ -711,7 +713,7 @@ no_context(struct pt_regs *regs, unsigned long error_code, | |||
711 | int sig; | 713 | int sig; |
712 | 714 | ||
713 | /* Are we prepared to handle this kernel fault? */ | 715 | /* Are we prepared to handle this kernel fault? */ |
714 | if (fixup_exception(regs, X86_TRAP_PF)) { | 716 | if (fixup_exception(regs, X86_TRAP_PF, error_code, address)) { |
715 | /* | 717 | /* |
716 | * Any interrupt that takes a fault gets the fixup. This makes | 718 | * Any interrupt that takes a fault gets the fixup. This makes |
717 | * the below recursive fault logic only apply to a faults from | 719 | * the below recursive fault logic only apply to a faults from |