diff options
-rw-r--r-- | arch/x86_64/mm/fault.c | 39 | ||||
-rw-r--r-- | include/asm-x86_64/kdebug.h | 2 |
2 files changed, 39 insertions, 2 deletions
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 55250593d8c9..0803d3858af1 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -41,6 +41,41 @@ | |||
41 | #define PF_RSVD (1<<3) | 41 | #define PF_RSVD (1<<3) |
42 | #define PF_INSTR (1<<4) | 42 | #define PF_INSTR (1<<4) |
43 | 43 | ||
44 | #ifdef CONFIG_KPROBES | ||
45 | ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); | ||
46 | |||
47 | /* Hook to register for page fault notifications */ | ||
48 | int register_page_fault_notifier(struct notifier_block *nb) | ||
49 | { | ||
50 | vmalloc_sync_all(); | ||
51 | return atomic_notifier_chain_register(¬ify_page_fault_chain, nb); | ||
52 | } | ||
53 | |||
54 | int unregister_page_fault_notifier(struct notifier_block *nb) | ||
55 | { | ||
56 | return atomic_notifier_chain_unregister(¬ify_page_fault_chain, nb); | ||
57 | } | ||
58 | |||
59 | static inline int notify_page_fault(enum die_val val, const char *str, | ||
60 | struct pt_regs *regs, long err, int trap, int sig) | ||
61 | { | ||
62 | struct die_args args = { | ||
63 | .regs = regs, | ||
64 | .str = str, | ||
65 | .err = err, | ||
66 | .trapnr = trap, | ||
67 | .signr = sig | ||
68 | }; | ||
69 | return atomic_notifier_call_chain(¬ify_page_fault_chain, val, &args); | ||
70 | } | ||
71 | #else | ||
72 | static inline int notify_page_fault(enum die_val val, const char *str, | ||
73 | struct pt_regs *regs, long err, int trap, int sig) | ||
74 | { | ||
75 | return NOTIFY_DONE; | ||
76 | } | ||
77 | #endif | ||
78 | |||
44 | void bust_spinlocks(int yes) | 79 | void bust_spinlocks(int yes) |
45 | { | 80 | { |
46 | int loglevel_save = console_loglevel; | 81 | int loglevel_save = console_loglevel; |
@@ -348,7 +383,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
348 | if (vmalloc_fault(address) >= 0) | 383 | if (vmalloc_fault(address) >= 0) |
349 | return; | 384 | return; |
350 | } | 385 | } |
351 | if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, | 386 | if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, |
352 | SIGSEGV) == NOTIFY_STOP) | 387 | SIGSEGV) == NOTIFY_STOP) |
353 | return; | 388 | return; |
354 | /* | 389 | /* |
@@ -358,7 +393,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
358 | goto bad_area_nosemaphore; | 393 | goto bad_area_nosemaphore; |
359 | } | 394 | } |
360 | 395 | ||
361 | if (notify_die(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, | 396 | if (notify_page_fault(DIE_PAGE_FAULT, "page fault", regs, error_code, 14, |
362 | SIGSEGV) == NOTIFY_STOP) | 397 | SIGSEGV) == NOTIFY_STOP) |
363 | return; | 398 | return; |
364 | 399 | ||
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h index cf795631d9b4..cd52c7f33bca 100644 --- a/include/asm-x86_64/kdebug.h +++ b/include/asm-x86_64/kdebug.h | |||
@@ -15,6 +15,8 @@ struct die_args { | |||
15 | 15 | ||
16 | extern int register_die_notifier(struct notifier_block *); | 16 | extern int register_die_notifier(struct notifier_block *); |
17 | extern int unregister_die_notifier(struct notifier_block *); | 17 | extern int unregister_die_notifier(struct notifier_block *); |
18 | extern int register_page_fault_notifier(struct notifier_block *); | ||
19 | extern int unregister_page_fault_notifier(struct notifier_block *); | ||
18 | extern struct atomic_notifier_head die_chain; | 20 | extern struct atomic_notifier_head die_chain; |
19 | 21 | ||
20 | /* Grossly misnamed. */ | 22 | /* Grossly misnamed. */ |