diff options
-rw-r--r-- | arch/x86/kernel/kprobes_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/kprobes_64.c | 1 | ||||
-rw-r--r-- | arch/x86/mm/fault_32.c | 43 | ||||
-rw-r--r-- | arch/x86/mm/fault_64.c | 44 | ||||
-rw-r--r-- | include/asm-avr32/kdebug.h | 16 | ||||
-rw-r--r-- | include/asm-avr32/kprobes.h | 2 | ||||
-rw-r--r-- | include/asm-ia64/kdebug.h | 15 | ||||
-rw-r--r-- | include/asm-ia64/kprobes.h | 1 | ||||
-rw-r--r-- | include/asm-powerpc/kdebug.h | 19 | ||||
-rw-r--r-- | include/asm-powerpc/kprobes.h | 1 | ||||
-rw-r--r-- | include/asm-s390/kdebug.h | 15 | ||||
-rw-r--r-- | include/asm-s390/kprobes.h | 1 | ||||
-rw-r--r-- | include/asm-sh/kdebug.h | 2 | ||||
-rw-r--r-- | include/asm-sparc64/kdebug.h | 18 | ||||
-rw-r--r-- | include/asm-sparc64/kprobes.h | 1 | ||||
-rw-r--r-- | include/asm-x86/kdebug_32.h | 6 | ||||
-rw-r--r-- | include/asm-x86/kdebug_64.h | 6 | ||||
-rw-r--r-- | include/asm-x86/kprobes_32.h | 2 | ||||
-rw-r--r-- | include/asm-x86/kprobes_64.h | 1 | ||||
-rw-r--r-- | kernel/kprobes.c | 39 |
20 files changed, 44 insertions, 192 deletions
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c index e7d0d3c2ef64..06b86e5617f6 100644 --- a/arch/x86/kernel/kprobes_32.c +++ b/arch/x86/kernel/kprobes_32.c | |||
@@ -584,7 +584,7 @@ out: | |||
584 | return 1; | 584 | return 1; |
585 | } | 585 | } |
586 | 586 | ||
587 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 587 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
588 | { | 588 | { |
589 | struct kprobe *cur = kprobe_running(); | 589 | struct kprobe *cur = kprobe_running(); |
590 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 590 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -666,7 +666,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
666 | ret = NOTIFY_STOP; | 666 | ret = NOTIFY_STOP; |
667 | break; | 667 | break; |
668 | case DIE_GPF: | 668 | case DIE_GPF: |
669 | case DIE_PAGE_FAULT: | ||
670 | /* kprobe_running() needs smp_processor_id() */ | 669 | /* kprobe_running() needs smp_processor_id() */ |
671 | preempt_disable(); | 670 | preempt_disable(); |
672 | if (kprobe_running() && | 671 | if (kprobe_running() && |
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c index 62e28e52d784..7c16506d681f 100644 --- a/arch/x86/kernel/kprobes_64.c +++ b/arch/x86/kernel/kprobes_64.c | |||
@@ -657,7 +657,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
657 | ret = NOTIFY_STOP; | 657 | ret = NOTIFY_STOP; |
658 | break; | 658 | break; |
659 | case DIE_GPF: | 659 | case DIE_GPF: |
660 | case DIE_PAGE_FAULT: | ||
661 | /* kprobe_running() needs smp_processor_id() */ | 660 | /* kprobe_running() needs smp_processor_id() */ |
662 | preempt_disable(); | 661 | preempt_disable(); |
663 | if (kprobe_running() && | 662 | if (kprobe_running() && |
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c index fcb38e7f3543..be72c2a5b03b 100644 --- a/arch/x86/mm/fault_32.c +++ b/arch/x86/mm/fault_32.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kprobes.h> | 25 | #include <linux/kprobes.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
28 | #include <linux/kprobes.h> | ||
28 | 29 | ||
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
30 | #include <asm/desc.h> | 31 | #include <asm/desc.h> |
@@ -32,33 +33,27 @@ | |||
32 | 33 | ||
33 | extern void die(const char *,struct pt_regs *,long); | 34 | extern void die(const char *,struct pt_regs *,long); |
34 | 35 | ||
35 | static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | 36 | #ifdef CONFIG_KPROBES |
36 | 37 | static inline int notify_page_fault(struct pt_regs *regs) | |
37 | int register_page_fault_notifier(struct notifier_block *nb) | ||
38 | { | 38 | { |
39 | vmalloc_sync_all(); | 39 | int ret = 0; |
40 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | 40 | |
41 | } | 41 | /* kprobe_running() needs smp_processor_id() */ |
42 | EXPORT_SYMBOL_GPL(register_page_fault_notifier); | 42 | if (!user_mode_vm(regs)) { |
43 | preempt_disable(); | ||
44 | if (kprobe_running() && kprobe_fault_handler(regs, 14)) | ||
45 | ret = 1; | ||
46 | preempt_enable(); | ||
47 | } | ||
43 | 48 | ||
44 | int unregister_page_fault_notifier(struct notifier_block *nb) | 49 | return ret; |
45 | { | ||
46 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
47 | } | 50 | } |
48 | EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); | 51 | #else |
49 | 52 | static inline int notify_page_fault(struct pt_regs *regs) | |
50 | static inline int notify_page_fault(struct pt_regs *regs, long err) | ||
51 | { | 53 | { |
52 | struct die_args args = { | 54 | return 0; |
53 | .regs = regs, | ||
54 | .str = "page fault", | ||
55 | .err = err, | ||
56 | .trapnr = 14, | ||
57 | .signr = SIGSEGV | ||
58 | }; | ||
59 | return atomic_notifier_call_chain(¬ify_page_fault_chain, | ||
60 | DIE_PAGE_FAULT, &args); | ||
61 | } | 55 | } |
56 | #endif | ||
62 | 57 | ||
63 | /* | 58 | /* |
64 | * Return EIP plus the CS segment base. The segment limit is also | 59 | * Return EIP plus the CS segment base. The segment limit is also |
@@ -331,7 +326,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, | |||
331 | if (unlikely(address >= TASK_SIZE)) { | 326 | if (unlikely(address >= TASK_SIZE)) { |
332 | if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) | 327 | if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) |
333 | return; | 328 | return; |
334 | if (notify_page_fault(regs, error_code) == NOTIFY_STOP) | 329 | if (notify_page_fault(regs)) |
335 | return; | 330 | return; |
336 | /* | 331 | /* |
337 | * Don't take the mm semaphore here. If we fixup a prefetch | 332 | * Don't take the mm semaphore here. If we fixup a prefetch |
@@ -340,7 +335,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs, | |||
340 | goto bad_area_nosemaphore; | 335 | goto bad_area_nosemaphore; |
341 | } | 336 | } |
342 | 337 | ||
343 | if (notify_page_fault(regs, error_code) == NOTIFY_STOP) | 338 | if (notify_page_fault(regs)) |
344 | return; | 339 | return; |
345 | 340 | ||
346 | /* It's safe to allow irq's after cr2 has been saved and the vmalloc | 341 | /* It's safe to allow irq's after cr2 has been saved and the vmalloc |
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c index 54816adb8e93..5e0e54906c48 100644 --- a/arch/x86/mm/fault_64.c +++ b/arch/x86/mm/fault_64.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/kprobes.h> | 25 | #include <linux/kprobes.h> |
26 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
27 | #include <linux/kdebug.h> | 27 | #include <linux/kdebug.h> |
28 | #include <linux/kprobes.h> | ||
28 | 29 | ||
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
30 | #include <asm/pgalloc.h> | 31 | #include <asm/pgalloc.h> |
@@ -40,34 +41,27 @@ | |||
40 | #define PF_RSVD (1<<3) | 41 | #define PF_RSVD (1<<3) |
41 | #define PF_INSTR (1<<4) | 42 | #define PF_INSTR (1<<4) |
42 | 43 | ||
43 | static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | 44 | #ifdef CONFIG_KPROBES |
44 | 45 | static inline int notify_page_fault(struct pt_regs *regs) | |
45 | /* Hook to register for page fault notifications */ | ||
46 | int register_page_fault_notifier(struct notifier_block *nb) | ||
47 | { | 46 | { |
48 | vmalloc_sync_all(); | 47 | int ret = 0; |
49 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | 48 | |
50 | } | 49 | /* kprobe_running() needs smp_processor_id() */ |
51 | EXPORT_SYMBOL_GPL(register_page_fault_notifier); | 50 | if (!user_mode(regs)) { |
51 | preempt_disable(); | ||
52 | if (kprobe_running() && kprobe_fault_handler(regs, 14)) | ||
53 | ret = 1; | ||
54 | preempt_enable(); | ||
55 | } | ||
52 | 56 | ||
53 | int unregister_page_fault_notifier(struct notifier_block *nb) | 57 | return ret; |
54 | { | ||
55 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
56 | } | 58 | } |
57 | EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); | 59 | #else |
58 | 60 | static inline int notify_page_fault(struct pt_regs *regs) | |
59 | static inline int notify_page_fault(struct pt_regs *regs, long err) | ||
60 | { | 61 | { |
61 | struct die_args args = { | 62 | return 0; |
62 | .regs = regs, | ||
63 | .str = "page fault", | ||
64 | .err = err, | ||
65 | .trapnr = 14, | ||
66 | .signr = SIGSEGV | ||
67 | }; | ||
68 | return atomic_notifier_call_chain(¬ify_page_fault_chain, | ||
69 | DIE_PAGE_FAULT, &args); | ||
70 | } | 63 | } |
64 | #endif | ||
71 | 65 | ||
72 | /* Sometimes the CPU reports invalid exceptions on prefetch. | 66 | /* Sometimes the CPU reports invalid exceptions on prefetch. |
73 | Check that here and ignore. | 67 | Check that here and ignore. |
@@ -345,7 +339,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
345 | if (vmalloc_fault(address) >= 0) | 339 | if (vmalloc_fault(address) >= 0) |
346 | return; | 340 | return; |
347 | } | 341 | } |
348 | if (notify_page_fault(regs, error_code) == NOTIFY_STOP) | 342 | if (notify_page_fault(regs)) |
349 | return; | 343 | return; |
350 | /* | 344 | /* |
351 | * Don't take the mm semaphore here. If we fixup a prefetch | 345 | * Don't take the mm semaphore here. If we fixup a prefetch |
@@ -354,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
354 | goto bad_area_nosemaphore; | 348 | goto bad_area_nosemaphore; |
355 | } | 349 | } |
356 | 350 | ||
357 | if (notify_page_fault(regs, error_code) == NOTIFY_STOP) | 351 | if (notify_page_fault(regs)) |
358 | return; | 352 | return; |
359 | 353 | ||
360 | if (likely(regs->eflags & X86_EFLAGS_IF)) | 354 | if (likely(regs->eflags & X86_EFLAGS_IF)) |
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h index 7f54e2b15d13..fd7e99046b2f 100644 --- a/include/asm-avr32/kdebug.h +++ b/include/asm-avr32/kdebug.h | |||
@@ -1,26 +1,10 @@ | |||
1 | #ifndef __ASM_AVR32_KDEBUG_H | 1 | #ifndef __ASM_AVR32_KDEBUG_H |
2 | #define __ASM_AVR32_KDEBUG_H | 2 | #define __ASM_AVR32_KDEBUG_H |
3 | 3 | ||
4 | #include <linux/notifier.h> | ||
5 | |||
6 | /* Grossly misnamed. */ | 4 | /* Grossly misnamed. */ |
7 | enum die_val { | 5 | enum die_val { |
8 | DIE_BREAKPOINT, | 6 | DIE_BREAKPOINT, |
9 | DIE_SSTEP, | 7 | DIE_SSTEP, |
10 | }; | 8 | }; |
11 | 9 | ||
12 | /* | ||
13 | * These are only here because kprobes.c wants them to implement a | ||
14 | * blatant layering violation. Will hopefully go away soon once all | ||
15 | * architectures are updated. | ||
16 | */ | ||
17 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
18 | { | ||
19 | return 0; | ||
20 | } | ||
21 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | #endif /* __ASM_AVR32_KDEBUG_H */ | 10 | #endif /* __ASM_AVR32_KDEBUG_H */ |
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h index 190a6377c809..0f3e636e6e4d 100644 --- a/include/asm-avr32/kprobes.h +++ b/include/asm-avr32/kprobes.h | |||
@@ -17,8 +17,6 @@ typedef u16 kprobe_opcode_t; | |||
17 | #define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ | 17 | #define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ |
18 | #define MAX_INSN_SIZE 2 | 18 | #define MAX_INSN_SIZE 2 |
19 | 19 | ||
20 | #define ARCH_INACTIVE_KPROBE_COUNT 1 | ||
21 | |||
22 | #define arch_remove_kprobe(p) do { } while (0) | 20 | #define arch_remove_kprobe(p) do { } while (0) |
23 | 21 | ||
24 | /* Architecture specific copy of original instruction */ | 22 | /* Architecture specific copy of original instruction */ |
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h index 320cd8e754ea..35e49407d06c 100644 --- a/include/asm-ia64/kdebug.h +++ b/include/asm-ia64/kdebug.h | |||
@@ -26,21 +26,6 @@ | |||
26 | * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more | 26 | * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more |
27 | * events. | 27 | * events. |
28 | */ | 28 | */ |
29 | #include <linux/notifier.h> | ||
30 | |||
31 | /* | ||
32 | * These are only here because kprobes.c wants them to implement a | ||
33 | * blatant layering violation. Will hopefully go away soon once all | ||
34 | * architectures are updated. | ||
35 | */ | ||
36 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
37 | { | ||
38 | return 0; | ||
39 | } | ||
40 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
41 | { | ||
42 | return 0; | ||
43 | } | ||
44 | 29 | ||
45 | enum die_val { | 30 | enum die_val { |
46 | DIE_BREAK = 1, | 31 | DIE_BREAK = 1, |
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h index 067d9dea68f9..6c79edf24d73 100644 --- a/include/asm-ia64/kprobes.h +++ b/include/asm-ia64/kprobes.h | |||
@@ -83,7 +83,6 @@ struct kprobe_ctlblk { | |||
83 | }; | 83 | }; |
84 | 84 | ||
85 | #define ARCH_SUPPORTS_KRETPROBES | 85 | #define ARCH_SUPPORTS_KRETPROBES |
86 | #define ARCH_INACTIVE_KPROBE_COUNT 1 | ||
87 | 86 | ||
88 | #define SLOT0_OPCODE_SHIFT (37) | 87 | #define SLOT0_OPCODE_SHIFT (37) |
89 | #define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) | 88 | #define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) |
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h index 295f0162c608..ae6d206728af 100644 --- a/include/asm-powerpc/kdebug.h +++ b/include/asm-powerpc/kdebug.h | |||
@@ -2,25 +2,6 @@ | |||
2 | #define _ASM_POWERPC_KDEBUG_H | 2 | #define _ASM_POWERPC_KDEBUG_H |
3 | #ifdef __KERNEL__ | 3 | #ifdef __KERNEL__ |
4 | 4 | ||
5 | /* nearly identical to x86_64/i386 code */ | ||
6 | |||
7 | #include <linux/notifier.h> | ||
8 | |||
9 | /* | ||
10 | * These are only here because kprobes.c wants them to implement a | ||
11 | * blatant layering violation. Will hopefully go away soon once all | ||
12 | * architectures are updated. | ||
13 | */ | ||
14 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
15 | { | ||
16 | return 0; | ||
17 | } | ||
18 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
19 | { | ||
20 | return 0; | ||
21 | } | ||
22 | extern struct atomic_notifier_head powerpc_die_chain; | ||
23 | |||
24 | /* Grossly misnamed. */ | 5 | /* Grossly misnamed. */ |
25 | enum die_val { | 6 | enum die_val { |
26 | DIE_OOPS = 1, | 7 | DIE_OOPS = 1, |
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h index 8b08b447d6f3..c16973d5de62 100644 --- a/include/asm-powerpc/kprobes.h +++ b/include/asm-powerpc/kprobes.h | |||
@@ -81,7 +81,6 @@ typedef unsigned int kprobe_opcode_t; | |||
81 | #endif | 81 | #endif |
82 | 82 | ||
83 | #define ARCH_SUPPORTS_KRETPROBES | 83 | #define ARCH_SUPPORTS_KRETPROBES |
84 | #define ARCH_INACTIVE_KPROBE_COUNT 1 | ||
85 | #define flush_insn_slot(p) do { } while (0) | 84 | #define flush_insn_slot(p) do { } while (0) |
86 | 85 | ||
87 | void kretprobe_trampoline(void); | 86 | void kretprobe_trampoline(void); |
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h index 04418af08f85..40db27cd6e60 100644 --- a/include/asm-s390/kdebug.h +++ b/include/asm-s390/kdebug.h | |||
@@ -4,24 +4,9 @@ | |||
4 | /* | 4 | /* |
5 | * Feb 2006 Ported to s390 <grundym@us.ibm.com> | 5 | * Feb 2006 Ported to s390 <grundym@us.ibm.com> |
6 | */ | 6 | */ |
7 | #include <linux/notifier.h> | ||
8 | 7 | ||
9 | struct pt_regs; | 8 | struct pt_regs; |
10 | 9 | ||
11 | /* | ||
12 | * These are only here because kprobes.c wants them to implement a | ||
13 | * blatant layering violation. Will hopefully go away soon once all | ||
14 | * architectures are updated. | ||
15 | */ | ||
16 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
17 | { | ||
18 | return 0; | ||
19 | } | ||
20 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
21 | { | ||
22 | return 0; | ||
23 | } | ||
24 | |||
25 | enum die_val { | 10 | enum die_val { |
26 | DIE_OOPS = 1, | 11 | DIE_OOPS = 1, |
27 | DIE_BPT, | 12 | DIE_BPT, |
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h index 340ba10446ea..8bc67cc9ffd2 100644 --- a/include/asm-s390/kprobes.h +++ b/include/asm-s390/kprobes.h | |||
@@ -47,7 +47,6 @@ typedef u16 kprobe_opcode_t; | |||
47 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | 47 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) |
48 | 48 | ||
49 | #define ARCH_SUPPORTS_KRETPROBES | 49 | #define ARCH_SUPPORTS_KRETPROBES |
50 | #define ARCH_INACTIVE_KPROBE_COUNT 0 | ||
51 | 50 | ||
52 | #define KPROBE_SWAP_INST 0x10 | 51 | #define KPROBE_SWAP_INST 0x10 |
53 | 52 | ||
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h index 382cfc7deb73..49cd69051a88 100644 --- a/include/asm-sh/kdebug.h +++ b/include/asm-sh/kdebug.h | |||
@@ -1,8 +1,6 @@ | |||
1 | #ifndef __ASM_SH_KDEBUG_H | 1 | #ifndef __ASM_SH_KDEBUG_H |
2 | #define __ASM_SH_KDEBUG_H | 2 | #define __ASM_SH_KDEBUG_H |
3 | 3 | ||
4 | #include <linux/notifier.h> | ||
5 | |||
6 | /* Grossly misnamed. */ | 4 | /* Grossly misnamed. */ |
7 | enum die_val { | 5 | enum die_val { |
8 | DIE_TRAP, | 6 | DIE_TRAP, |
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h index 9974c7b0aebc..f905b773235a 100644 --- a/include/asm-sparc64/kdebug.h +++ b/include/asm-sparc64/kdebug.h | |||
@@ -1,26 +1,8 @@ | |||
1 | #ifndef _SPARC64_KDEBUG_H | 1 | #ifndef _SPARC64_KDEBUG_H |
2 | #define _SPARC64_KDEBUG_H | 2 | #define _SPARC64_KDEBUG_H |
3 | 3 | ||
4 | /* Nearly identical to x86_64/i386 code. */ | ||
5 | |||
6 | #include <linux/notifier.h> | ||
7 | |||
8 | struct pt_regs; | 4 | struct pt_regs; |
9 | 5 | ||
10 | /* | ||
11 | * These are only here because kprobes.c wants them to implement a | ||
12 | * blatant layering violation. Will hopefully go away soon once all | ||
13 | * architectures are updated. | ||
14 | */ | ||
15 | static inline int register_page_fault_notifier(struct notifier_block *nb) | ||
16 | { | ||
17 | return 0; | ||
18 | } | ||
19 | static inline int unregister_page_fault_notifier(struct notifier_block *nb) | ||
20 | { | ||
21 | return 0; | ||
22 | } | ||
23 | |||
24 | extern void bad_trap(struct pt_regs *, long); | 6 | extern void bad_trap(struct pt_regs *, long); |
25 | 7 | ||
26 | /* Grossly misnamed. */ | 8 | /* Grossly misnamed. */ |
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h index 7f6774dca5f4..a04145b77f96 100644 --- a/include/asm-sparc64/kprobes.h +++ b/include/asm-sparc64/kprobes.h | |||
@@ -11,7 +11,6 @@ typedef u32 kprobe_opcode_t; | |||
11 | #define MAX_INSN_SIZE 2 | 11 | #define MAX_INSN_SIZE 2 |
12 | 12 | ||
13 | #define arch_remove_kprobe(p) do {} while (0) | 13 | #define arch_remove_kprobe(p) do {} while (0) |
14 | #define ARCH_INACTIVE_KPROBE_COUNT 0 | ||
15 | 14 | ||
16 | #define flush_insn_slot(p) \ | 15 | #define flush_insn_slot(p) \ |
17 | do { flushi(&(p)->ainsn.insn[0]); \ | 16 | do { flushi(&(p)->ainsn.insn[0]); \ |
diff --git a/include/asm-x86/kdebug_32.h b/include/asm-x86/kdebug_32.h index a185b5f73e7f..181d437eef4b 100644 --- a/include/asm-x86/kdebug_32.h +++ b/include/asm-x86/kdebug_32.h | |||
@@ -5,14 +5,9 @@ | |||
5 | * Aug-05 2004 Ported by Prasanna S Panchamukhi <prasanna@in.ibm.com> | 5 | * Aug-05 2004 Ported by Prasanna S Panchamukhi <prasanna@in.ibm.com> |
6 | * from x86_64 architecture. | 6 | * from x86_64 architecture. |
7 | */ | 7 | */ |
8 | #include <linux/notifier.h> | ||
9 | 8 | ||
10 | struct pt_regs; | 9 | struct pt_regs; |
11 | 10 | ||
12 | extern int register_page_fault_notifier(struct notifier_block *); | ||
13 | extern int unregister_page_fault_notifier(struct notifier_block *); | ||
14 | |||
15 | |||
16 | /* Grossly misnamed. */ | 11 | /* Grossly misnamed. */ |
17 | enum die_val { | 12 | enum die_val { |
18 | DIE_OOPS = 1, | 13 | DIE_OOPS = 1, |
@@ -27,7 +22,6 @@ enum die_val { | |||
27 | DIE_GPF, | 22 | DIE_GPF, |
28 | DIE_CALL, | 23 | DIE_CALL, |
29 | DIE_NMI_IPI, | 24 | DIE_NMI_IPI, |
30 | DIE_PAGE_FAULT, | ||
31 | }; | 25 | }; |
32 | 26 | ||
33 | #endif | 27 | #endif |
diff --git a/include/asm-x86/kdebug_64.h b/include/asm-x86/kdebug_64.h index d7e2bcf49e4f..df413e05375e 100644 --- a/include/asm-x86/kdebug_64.h +++ b/include/asm-x86/kdebug_64.h | |||
@@ -1,13 +1,10 @@ | |||
1 | #ifndef _X86_64_KDEBUG_H | 1 | #ifndef _X86_64_KDEBUG_H |
2 | #define _X86_64_KDEBUG_H 1 | 2 | #define _X86_64_KDEBUG_H 1 |
3 | 3 | ||
4 | #include <linux/notifier.h> | 4 | #include <linux/compiler.h> |
5 | 5 | ||
6 | struct pt_regs; | 6 | struct pt_regs; |
7 | 7 | ||
8 | extern int register_page_fault_notifier(struct notifier_block *); | ||
9 | extern int unregister_page_fault_notifier(struct notifier_block *); | ||
10 | |||
11 | /* Grossly misnamed. */ | 8 | /* Grossly misnamed. */ |
12 | enum die_val { | 9 | enum die_val { |
13 | DIE_OOPS = 1, | 10 | DIE_OOPS = 1, |
@@ -22,7 +19,6 @@ enum die_val { | |||
22 | DIE_GPF, | 19 | DIE_GPF, |
23 | DIE_CALL, | 20 | DIE_CALL, |
24 | DIE_NMI_IPI, | 21 | DIE_NMI_IPI, |
25 | DIE_PAGE_FAULT, | ||
26 | }; | 22 | }; |
27 | 23 | ||
28 | extern void printk_address(unsigned long address); | 24 | extern void printk_address(unsigned long address); |
diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h index 06f7303c30ca..f2489d07ce88 100644 --- a/include/asm-x86/kprobes_32.h +++ b/include/asm-x86/kprobes_32.h | |||
@@ -43,7 +43,6 @@ typedef u8 kprobe_opcode_t; | |||
43 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | 43 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) |
44 | 44 | ||
45 | #define ARCH_SUPPORTS_KRETPROBES | 45 | #define ARCH_SUPPORTS_KRETPROBES |
46 | #define ARCH_INACTIVE_KPROBE_COUNT 0 | ||
47 | #define flush_insn_slot(p) do { } while (0) | 46 | #define flush_insn_slot(p) do { } while (0) |
48 | 47 | ||
49 | void arch_remove_kprobe(struct kprobe *p); | 48 | void arch_remove_kprobe(struct kprobe *p); |
@@ -89,4 +88,5 @@ static inline void restore_interrupts(struct pt_regs *regs) | |||
89 | 88 | ||
90 | extern int kprobe_exceptions_notify(struct notifier_block *self, | 89 | extern int kprobe_exceptions_notify(struct notifier_block *self, |
91 | unsigned long val, void *data); | 90 | unsigned long val, void *data); |
91 | extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); | ||
92 | #endif /* _ASM_KPROBES_H */ | 92 | #endif /* _ASM_KPROBES_H */ |
diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h index 7db825403e01..3f495e5308b1 100644 --- a/include/asm-x86/kprobes_64.h +++ b/include/asm-x86/kprobes_64.h | |||
@@ -42,7 +42,6 @@ typedef u8 kprobe_opcode_t; | |||
42 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | 42 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) |
43 | 43 | ||
44 | #define ARCH_SUPPORTS_KRETPROBES | 44 | #define ARCH_SUPPORTS_KRETPROBES |
45 | #define ARCH_INACTIVE_KPROBE_COUNT 1 | ||
46 | 45 | ||
47 | void kretprobe_trampoline(void); | 46 | void kretprobe_trampoline(void); |
48 | extern void arch_remove_kprobe(struct kprobe *p); | 47 | extern void arch_remove_kprobe(struct kprobe *p); |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 4b8a4493c541..f9798ff7899f 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -64,7 +64,6 @@ | |||
64 | 64 | ||
65 | static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; | 65 | static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; |
66 | static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; | 66 | static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; |
67 | static atomic_t kprobe_count; | ||
68 | 67 | ||
69 | /* NOTE: change this value only with kprobe_mutex held */ | 68 | /* NOTE: change this value only with kprobe_mutex held */ |
70 | static bool kprobe_enabled; | 69 | static bool kprobe_enabled; |
@@ -73,11 +72,6 @@ DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */ | |||
73 | DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ | 72 | DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ |
74 | static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; | 73 | static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; |
75 | 74 | ||
76 | static struct notifier_block kprobe_page_fault_nb = { | ||
77 | .notifier_call = kprobe_exceptions_notify, | ||
78 | .priority = 0x7fffffff /* we need to notified first */ | ||
79 | }; | ||
80 | |||
81 | #ifdef __ARCH_WANT_KPROBES_INSN_SLOT | 75 | #ifdef __ARCH_WANT_KPROBES_INSN_SLOT |
82 | /* | 76 | /* |
83 | * kprobe->ainsn.insn points to the copy of the instruction to be | 77 | * kprobe->ainsn.insn points to the copy of the instruction to be |
@@ -556,8 +550,6 @@ static int __kprobes __register_kprobe(struct kprobe *p, | |||
556 | old_p = get_kprobe(p->addr); | 550 | old_p = get_kprobe(p->addr); |
557 | if (old_p) { | 551 | if (old_p) { |
558 | ret = register_aggr_kprobe(old_p, p); | 552 | ret = register_aggr_kprobe(old_p, p); |
559 | if (!ret) | ||
560 | atomic_inc(&kprobe_count); | ||
561 | goto out; | 553 | goto out; |
562 | } | 554 | } |
563 | 555 | ||
@@ -569,13 +561,9 @@ static int __kprobes __register_kprobe(struct kprobe *p, | |||
569 | hlist_add_head_rcu(&p->hlist, | 561 | hlist_add_head_rcu(&p->hlist, |
570 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); | 562 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); |
571 | 563 | ||
572 | if (kprobe_enabled) { | 564 | if (kprobe_enabled) |
573 | if (atomic_add_return(1, &kprobe_count) == \ | ||
574 | (ARCH_INACTIVE_KPROBE_COUNT + 1)) | ||
575 | register_page_fault_notifier(&kprobe_page_fault_nb); | ||
576 | |||
577 | arch_arm_kprobe(p); | 565 | arch_arm_kprobe(p); |
578 | } | 566 | |
579 | out: | 567 | out: |
580 | mutex_unlock(&kprobe_mutex); | 568 | mutex_unlock(&kprobe_mutex); |
581 | 569 | ||
@@ -658,16 +646,6 @@ valid_p: | |||
658 | } | 646 | } |
659 | mutex_unlock(&kprobe_mutex); | 647 | mutex_unlock(&kprobe_mutex); |
660 | } | 648 | } |
661 | |||
662 | /* Call unregister_page_fault_notifier() | ||
663 | * if no probes are active | ||
664 | */ | ||
665 | mutex_lock(&kprobe_mutex); | ||
666 | if (atomic_add_return(-1, &kprobe_count) == \ | ||
667 | ARCH_INACTIVE_KPROBE_COUNT) | ||
668 | unregister_page_fault_notifier(&kprobe_page_fault_nb); | ||
669 | mutex_unlock(&kprobe_mutex); | ||
670 | return; | ||
671 | } | 649 | } |
672 | 650 | ||
673 | static struct notifier_block kprobe_exceptions_nb = { | 651 | static struct notifier_block kprobe_exceptions_nb = { |
@@ -815,7 +793,6 @@ static int __init init_kprobes(void) | |||
815 | INIT_HLIST_HEAD(&kprobe_table[i]); | 793 | INIT_HLIST_HEAD(&kprobe_table[i]); |
816 | INIT_HLIST_HEAD(&kretprobe_inst_table[i]); | 794 | INIT_HLIST_HEAD(&kretprobe_inst_table[i]); |
817 | } | 795 | } |
818 | atomic_set(&kprobe_count, 0); | ||
819 | 796 | ||
820 | /* By default, kprobes are enabled */ | 797 | /* By default, kprobes are enabled */ |
821 | kprobe_enabled = true; | 798 | kprobe_enabled = true; |
@@ -921,13 +898,6 @@ static void __kprobes enable_all_kprobes(void) | |||
921 | if (kprobe_enabled) | 898 | if (kprobe_enabled) |
922 | goto already_enabled; | 899 | goto already_enabled; |
923 | 900 | ||
924 | /* | ||
925 | * Re-register the page fault notifier only if there are any | ||
926 | * active probes at the time of enabling kprobes globally | ||
927 | */ | ||
928 | if (atomic_read(&kprobe_count) > ARCH_INACTIVE_KPROBE_COUNT) | ||
929 | register_page_fault_notifier(&kprobe_page_fault_nb); | ||
930 | |||
931 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { | 901 | for (i = 0; i < KPROBE_TABLE_SIZE; i++) { |
932 | head = &kprobe_table[i]; | 902 | head = &kprobe_table[i]; |
933 | hlist_for_each_entry_rcu(p, node, head, hlist) | 903 | hlist_for_each_entry_rcu(p, node, head, hlist) |
@@ -968,10 +938,7 @@ static void __kprobes disable_all_kprobes(void) | |||
968 | mutex_unlock(&kprobe_mutex); | 938 | mutex_unlock(&kprobe_mutex); |
969 | /* Allow all currently running kprobes to complete */ | 939 | /* Allow all currently running kprobes to complete */ |
970 | synchronize_sched(); | 940 | synchronize_sched(); |
971 | 941 | return; | |
972 | mutex_lock(&kprobe_mutex); | ||
973 | /* Unconditionally unregister the page_fault notifier */ | ||
974 | unregister_page_fault_notifier(&kprobe_page_fault_nb); | ||
975 | 942 | ||
976 | already_disabled: | 943 | already_disabled: |
977 | mutex_unlock(&kprobe_mutex); | 944 | mutex_unlock(&kprobe_mutex); |