diff options
Diffstat (limited to 'arch/ppc64/mm/fault.c')
| -rw-r--r-- | arch/ppc64/mm/fault.c | 31 |
1 files changed, 25 insertions, 6 deletions
diff --git a/arch/ppc64/mm/fault.c b/arch/ppc64/mm/fault.c index 772f0714a5b7..7fbc68bbb739 100644 --- a/arch/ppc64/mm/fault.c +++ b/arch/ppc64/mm/fault.c | |||
| @@ -77,6 +77,28 @@ static int store_updates_sp(struct pt_regs *regs) | |||
| 77 | return 0; | 77 | return 0; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static void do_dabr(struct pt_regs *regs, unsigned long error_code) | ||
| 81 | { | ||
| 82 | siginfo_t info; | ||
| 83 | |||
| 84 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, | ||
| 85 | 11, SIGSEGV) == NOTIFY_STOP) | ||
| 86 | return; | ||
| 87 | |||
| 88 | if (debugger_dabr_match(regs)) | ||
| 89 | return; | ||
| 90 | |||
| 91 | /* Clear the DABR */ | ||
| 92 | set_dabr(0); | ||
| 93 | |||
| 94 | /* Deliver the signal to userspace */ | ||
| 95 | info.si_signo = SIGTRAP; | ||
| 96 | info.si_errno = 0; | ||
| 97 | info.si_code = TRAP_HWBKPT; | ||
| 98 | info.si_addr = (void __user *)regs->nip; | ||
| 99 | force_sig_info(SIGTRAP, &info, current); | ||
| 100 | } | ||
| 101 | |||
| 80 | /* | 102 | /* |
| 81 | * The error_code parameter is | 103 | * The error_code parameter is |
| 82 | * - DSISR for a non-SLB data access fault, | 104 | * - DSISR for a non-SLB data access fault, |
| @@ -111,12 +133,9 @@ int __kprobes do_page_fault(struct pt_regs *regs, unsigned long address, | |||
| 111 | if (!user_mode(regs) && (address >= TASK_SIZE)) | 133 | if (!user_mode(regs) && (address >= TASK_SIZE)) |
| 112 | return SIGSEGV; | 134 | return SIGSEGV; |
| 113 | 135 | ||
| 114 | if (error_code & DSISR_DABRMATCH) { | 136 | if (error_code & DSISR_DABRMATCH) { |
| 115 | if (notify_die(DIE_DABR_MATCH, "dabr_match", regs, error_code, | 137 | do_dabr(regs, error_code); |
| 116 | 11, SIGSEGV) == NOTIFY_STOP) | 138 | return 0; |
| 117 | return 0; | ||
| 118 | if (debugger_dabr_match(regs)) | ||
| 119 | return 0; | ||
| 120 | } | 139 | } |
| 121 | 140 | ||
| 122 | if (in_atomic() || mm == NULL) { | 141 | if (in_atomic() || mm == NULL) { |
