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