diff options
Diffstat (limited to 'arch/sh/mm')
-rw-r--r-- | arch/sh/mm/fault_32.c | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/arch/sh/mm/fault_32.c b/arch/sh/mm/fault_32.c index e8efda9846bb..659811c179e6 100644 --- a/arch/sh/mm/fault_32.c +++ b/arch/sh/mm/fault_32.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * Page fault handler for SH with an MMU. | 2 | * Page fault handler for SH with an MMU. |
3 | * | 3 | * |
4 | * Copyright (C) 1999 Niibe Yutaka | 4 | * Copyright (C) 1999 Niibe Yutaka |
5 | * Copyright (C) 2003 - 2007 Paul Mundt | 5 | * Copyright (C) 2003 - 2008 Paul Mundt |
6 | * | 6 | * |
7 | * Based on linux/arch/i386/mm/fault.c: | 7 | * Based on linux/arch/i386/mm/fault.c: |
8 | * Copyright (C) 1995 Linus Torvalds | 8 | * Copyright (C) 1995 Linus Torvalds |
@@ -21,6 +21,27 @@ | |||
21 | #include <asm/tlbflush.h> | 21 | #include <asm/tlbflush.h> |
22 | #include <asm/kgdb.h> | 22 | #include <asm/kgdb.h> |
23 | 23 | ||
24 | #ifdef CONFIG_KPROBES | ||
25 | static inline int notify_page_fault(struct pt_regs *regs, int trap) | ||
26 | { | ||
27 | int ret = 0; | ||
28 | |||
29 | if (!user_mode(regs)) { | ||
30 | preempt_disable(); | ||
31 | if (kprobe_running() && kprobe_fault_handler(regs, trap)) | ||
32 | ret = 1; | ||
33 | preempt_enable(); | ||
34 | } | ||
35 | |||
36 | return ret; | ||
37 | } | ||
38 | #else | ||
39 | static inline int notify_page_fault(struct pt_regs *regs, int trap) | ||
40 | { | ||
41 | return 0; | ||
42 | } | ||
43 | #endif | ||
44 | |||
24 | /* | 45 | /* |
25 | * This routine handles page faults. It determines the address, | 46 | * This routine handles page faults. It determines the address, |
26 | * and the problem, and then passes it off to one of the appropriate | 47 | * and the problem, and then passes it off to one of the appropriate |
@@ -37,6 +58,9 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, | |||
37 | int fault; | 58 | int fault; |
38 | siginfo_t info; | 59 | siginfo_t info; |
39 | 60 | ||
61 | if (notify_page_fault(regs, writeaccess)) | ||
62 | return; | ||
63 | |||
40 | #ifdef CONFIG_SH_KGDB | 64 | #ifdef CONFIG_SH_KGDB |
41 | if (kgdb_nofault && kgdb_bus_err_hook) | 65 | if (kgdb_nofault && kgdb_bus_err_hook) |
42 | kgdb_bus_err_hook(); | 66 | kgdb_bus_err_hook(); |
@@ -269,6 +293,9 @@ asmlinkage int __kprobes __do_page_fault(struct pt_regs *regs, | |||
269 | pte_t *pte; | 293 | pte_t *pte; |
270 | pte_t entry; | 294 | pte_t entry; |
271 | 295 | ||
296 | if (notify_page_fault(regs, writeaccess)) | ||
297 | return 0; | ||
298 | |||
272 | #ifdef CONFIG_SH_KGDB | 299 | #ifdef CONFIG_SH_KGDB |
273 | if (kgdb_nofault && kgdb_bus_err_hook) | 300 | if (kgdb_nofault && kgdb_bus_err_hook) |
274 | kgdb_bus_err_hook(); | 301 | kgdb_bus_err_hook(); |