aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-08 21:25:48 -0400
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-07-08 21:25:48 -0400
commit5f07aa7524e98d6f68f2bec54f155ef6012e2c9a (patch)
tree393b2db3213e6618ad1338f9b66019b0c05c6f75 /arch/powerpc/kernel
parente467e104bb7482170b79f516d2025e7cfcaaa733 (diff)
parentd09ec7387184eba9e3030496f0451204090ff610 (diff)
Merge commit 'paulus-perf/master' into next
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/Makefile1
-rw-r--r--arch/powerpc/kernel/exceptions-64s.S1
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c364
-rw-r--r--arch/powerpc/kernel/machine_kexec_64.c3
-rw-r--r--arch/powerpc/kernel/process.c14
-rw-r--r--arch/powerpc/kernel/ptrace.c64
-rw-r--r--arch/powerpc/kernel/signal.c3
-rw-r--r--arch/powerpc/kernel/traps.c8
8 files changed, 453 insertions, 5 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 58d0572de6f9..01006040f59e 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -34,6 +34,7 @@ obj-y += vdso32/
34obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ 34obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \
35 signal_64.o ptrace32.o \ 35 signal_64.o ptrace32.o \
36 paca.o nvram_64.o firmware.o 36 paca.o nvram_64.o firmware.o
37obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
37obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o 38obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
38obj64-$(CONFIG_RELOCATABLE) += reloc_64.o 39obj64-$(CONFIG_RELOCATABLE) += reloc_64.o
39obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o 40obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o
diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 3e423fbad6bc..f53029a01554 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -828,6 +828,7 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
828 828
829/* We have a data breakpoint exception - handle it */ 829/* We have a data breakpoint exception - handle it */
830handle_dabr_fault: 830handle_dabr_fault:
831 bl .save_nvgprs
831 ld r4,_DAR(r1) 832 ld r4,_DAR(r1)
832 ld r5,_DSISR(r1) 833 ld r5,_DSISR(r1)
833 addi r3,r1,STACK_FRAME_OVERHEAD 834 addi r3,r1,STACK_FRAME_OVERHEAD
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
new file mode 100644
index 000000000000..5ecd0401cdb1
--- /dev/null
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -0,0 +1,364 @@
1/*
2 * HW_breakpoint: a unified kernel/user-space hardware breakpoint facility,
3 * using the CPU's debug registers. Derived from
4 * "arch/x86/kernel/hw_breakpoint.c"
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Copyright 2010 IBM Corporation
21 * Author: K.Prasad <prasad@linux.vnet.ibm.com>
22 *
23 */
24
25#include <linux/hw_breakpoint.h>
26#include <linux/notifier.h>
27#include <linux/kprobes.h>
28#include <linux/percpu.h>
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/sched.h>
32#include <linux/init.h>
33#include <linux/smp.h>
34
35#include <asm/hw_breakpoint.h>
36#include <asm/processor.h>
37#include <asm/sstep.h>
38#include <asm/uaccess.h>
39
40/*
41 * Stores the breakpoints currently in use on each breakpoint address
42 * register for every cpu
43 */
44static DEFINE_PER_CPU(struct perf_event *, bp_per_reg);
45
46/*
47 * Returns total number of data or instruction breakpoints available.
48 */
49int hw_breakpoint_slots(int type)
50{
51 if (type == TYPE_DATA)
52 return HBP_NUM;
53 return 0; /* no instruction breakpoints available */
54}
55
56/*
57 * Install a perf counter breakpoint.
58 *
59 * We seek a free debug address register and use it for this
60 * breakpoint.
61 *
62 * Atomic: we hold the counter->ctx->lock and we only handle variables
63 * and registers local to this cpu.
64 */
65int arch_install_hw_breakpoint(struct perf_event *bp)
66{
67 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
68 struct perf_event **slot = &__get_cpu_var(bp_per_reg);
69
70 *slot = bp;
71
72 /*
73 * Do not install DABR values if the instruction must be single-stepped.
74 * If so, DABR will be populated in single_step_dabr_instruction().
75 */
76 if (current->thread.last_hit_ubp != bp)
77 set_dabr(info->address | info->type | DABR_TRANSLATION);
78
79 return 0;
80}
81
82/*
83 * Uninstall the breakpoint contained in the given counter.
84 *
85 * First we search the debug address register it uses and then we disable
86 * it.
87 *
88 * Atomic: we hold the counter->ctx->lock and we only handle variables
89 * and registers local to this cpu.
90 */
91void arch_uninstall_hw_breakpoint(struct perf_event *bp)
92{
93 struct perf_event **slot = &__get_cpu_var(bp_per_reg);
94
95 if (*slot != bp) {
96 WARN_ONCE(1, "Can't find the breakpoint");
97 return;
98 }
99
100 *slot = NULL;
101 set_dabr(0);
102}
103
104/*
105 * Perform cleanup of arch-specific counters during unregistration
106 * of the perf-event
107 */
108void arch_unregister_hw_breakpoint(struct perf_event *bp)
109{
110 /*
111 * If the breakpoint is unregistered between a hw_breakpoint_handler()
112 * and the single_step_dabr_instruction(), then cleanup the breakpoint
113 * restoration variables to prevent dangling pointers.
114 */
115 if (bp->ctx->task)
116 bp->ctx->task->thread.last_hit_ubp = NULL;
117}
118
119/*
120 * Check for virtual address in kernel space.
121 */
122int arch_check_bp_in_kernelspace(struct perf_event *bp)
123{
124 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
125
126 return is_kernel_addr(info->address);
127}
128
129int arch_bp_generic_fields(int type, int *gen_bp_type)
130{
131 switch (type) {
132 case DABR_DATA_READ:
133 *gen_bp_type = HW_BREAKPOINT_R;
134 break;
135 case DABR_DATA_WRITE:
136 *gen_bp_type = HW_BREAKPOINT_W;
137 break;
138 case (DABR_DATA_WRITE | DABR_DATA_READ):
139 *gen_bp_type = (HW_BREAKPOINT_W | HW_BREAKPOINT_R);
140 break;
141 default:
142 return -EINVAL;
143 }
144 return 0;
145}
146
147/*
148 * Validate the arch-specific HW Breakpoint register settings
149 */
150int arch_validate_hwbkpt_settings(struct perf_event *bp)
151{
152 int ret = -EINVAL;
153 struct arch_hw_breakpoint *info = counter_arch_bp(bp);
154
155 if (!bp)
156 return ret;
157
158 switch (bp->attr.bp_type) {
159 case HW_BREAKPOINT_R:
160 info->type = DABR_DATA_READ;
161 break;
162 case HW_BREAKPOINT_W:
163 info->type = DABR_DATA_WRITE;
164 break;
165 case HW_BREAKPOINT_R | HW_BREAKPOINT_W:
166 info->type = (DABR_DATA_READ | DABR_DATA_WRITE);
167 break;
168 default:
169 return ret;
170 }
171
172 info->address = bp->attr.bp_addr;
173 info->len = bp->attr.bp_len;
174
175 /*
176 * Since breakpoint length can be a maximum of HW_BREAKPOINT_LEN(8)
177 * and breakpoint addresses are aligned to nearest double-word
178 * HW_BREAKPOINT_ALIGN by rounding off to the lower address, the
179 * 'symbolsize' should satisfy the check below.
180 */
181 if (info->len >
182 (HW_BREAKPOINT_LEN - (info->address & HW_BREAKPOINT_ALIGN)))
183 return -EINVAL;
184 return 0;
185}
186
187/*
188 * Restores the breakpoint on the debug registers.
189 * Invoke this function if it is known that the execution context is
190 * about to change to cause loss of MSR_SE settings.
191 */
192void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
193{
194 struct arch_hw_breakpoint *info;
195
196 if (likely(!tsk->thread.last_hit_ubp))
197 return;
198
199 info = counter_arch_bp(tsk->thread.last_hit_ubp);
200 regs->msr &= ~MSR_SE;
201 set_dabr(info->address | info->type | DABR_TRANSLATION);
202 tsk->thread.last_hit_ubp = NULL;
203}
204
205/*
206 * Handle debug exception notifications.
207 */
208int __kprobes hw_breakpoint_handler(struct die_args *args)
209{
210 int rc = NOTIFY_STOP;
211 struct perf_event *bp;
212 struct pt_regs *regs = args->regs;
213 int stepped = 1;
214 struct arch_hw_breakpoint *info;
215 unsigned int instr;
216 unsigned long dar = regs->dar;
217
218 /* Disable breakpoints during exception handling */
219 set_dabr(0);
220
221 /*
222 * The counter may be concurrently released but that can only
223 * occur from a call_rcu() path. We can then safely fetch
224 * the breakpoint, use its callback, touch its counter
225 * while we are in an rcu_read_lock() path.
226 */
227 rcu_read_lock();
228
229 bp = __get_cpu_var(bp_per_reg);
230 if (!bp)
231 goto out;
232 info = counter_arch_bp(bp);
233
234 /*
235 * Return early after invoking user-callback function without restoring
236 * DABR if the breakpoint is from ptrace which always operates in
237 * one-shot mode. The ptrace-ed process will receive the SIGTRAP signal
238 * generated in do_dabr().
239 */
240 if (bp->overflow_handler == ptrace_triggered) {
241 perf_bp_event(bp, regs);
242 rc = NOTIFY_DONE;
243 goto out;
244 }
245
246 /*
247 * Verify if dar lies within the address range occupied by the symbol
248 * being watched to filter extraneous exceptions. If it doesn't,
249 * we still need to single-step the instruction, but we don't
250 * generate an event.
251 */
252 info->extraneous_interrupt = !((bp->attr.bp_addr <= dar) &&
253 (dar - bp->attr.bp_addr < bp->attr.bp_len));
254
255 /* Do not emulate user-space instructions, instead single-step them */
256 if (user_mode(regs)) {
257 bp->ctx->task->thread.last_hit_ubp = bp;
258 regs->msr |= MSR_SE;
259 goto out;
260 }
261
262 stepped = 0;
263 instr = 0;
264 if (!__get_user_inatomic(instr, (unsigned int *) regs->nip))
265 stepped = emulate_step(regs, instr);
266
267 /*
268 * emulate_step() could not execute it. We've failed in reliably
269 * handling the hw-breakpoint. Unregister it and throw a warning
270 * message to let the user know about it.
271 */
272 if (!stepped) {
273 WARN(1, "Unable to handle hardware breakpoint. Breakpoint at "
274 "0x%lx will be disabled.", info->address);
275 perf_event_disable(bp);
276 goto out;
277 }
278 /*
279 * As a policy, the callback is invoked in a 'trigger-after-execute'
280 * fashion
281 */
282 if (!info->extraneous_interrupt)
283 perf_bp_event(bp, regs);
284
285 set_dabr(info->address | info->type | DABR_TRANSLATION);
286out:
287 rcu_read_unlock();
288 return rc;
289}
290
291/*
292 * Handle single-step exceptions following a DABR hit.
293 */
294int __kprobes single_step_dabr_instruction(struct die_args *args)
295{
296 struct pt_regs *regs = args->regs;
297 struct perf_event *bp = NULL;
298 struct arch_hw_breakpoint *bp_info;
299
300 bp = current->thread.last_hit_ubp;
301 /*
302 * Check if we are single-stepping as a result of a
303 * previous HW Breakpoint exception
304 */
305 if (!bp)
306 return NOTIFY_DONE;
307
308 bp_info = counter_arch_bp(bp);
309
310 /*
311 * We shall invoke the user-defined callback function in the single
312 * stepping handler to confirm to 'trigger-after-execute' semantics
313 */
314 if (!bp_info->extraneous_interrupt)
315 perf_bp_event(bp, regs);
316
317 set_dabr(bp_info->address | bp_info->type | DABR_TRANSLATION);
318 current->thread.last_hit_ubp = NULL;
319
320 /*
321 * If the process was being single-stepped by ptrace, let the
322 * other single-step actions occur (e.g. generate SIGTRAP).
323 */
324 if (test_thread_flag(TIF_SINGLESTEP))
325 return NOTIFY_DONE;
326
327 return NOTIFY_STOP;
328}
329
330/*
331 * Handle debug exception notifications.
332 */
333int __kprobes hw_breakpoint_exceptions_notify(
334 struct notifier_block *unused, unsigned long val, void *data)
335{
336 int ret = NOTIFY_DONE;
337
338 switch (val) {
339 case DIE_DABR_MATCH:
340 ret = hw_breakpoint_handler(data);
341 break;
342 case DIE_SSTEP:
343 ret = single_step_dabr_instruction(data);
344 break;
345 }
346
347 return ret;
348}
349
350/*
351 * Release the user breakpoints used by ptrace
352 */
353void flush_ptrace_hw_breakpoint(struct task_struct *tsk)
354{
355 struct thread_struct *t = &tsk->thread;
356
357 unregister_hw_breakpoint(t->ptrace_bps[0]);
358 t->ptrace_bps[0] = NULL;
359}
360
361void hw_breakpoint_pmu_read(struct perf_event *bp)
362{
363 /* TODO */
364}
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index ed31a29c4ff7..de6b70eac51d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -25,6 +25,7 @@
25#include <asm/sections.h> /* _end */ 25#include <asm/sections.h> /* _end */
26#include <asm/prom.h> 26#include <asm/prom.h>
27#include <asm/smp.h> 27#include <asm/smp.h>
28#include <asm/hw_breakpoint.h>
28 29
29int default_machine_kexec_prepare(struct kimage *image) 30int default_machine_kexec_prepare(struct kimage *image)
30{ 31{
@@ -165,6 +166,7 @@ static void kexec_smp_down(void *arg)
165 while(kexec_all_irq_disabled == 0) 166 while(kexec_all_irq_disabled == 0)
166 cpu_relax(); 167 cpu_relax();
167 mb(); /* make sure all irqs are disabled before this */ 168 mb(); /* make sure all irqs are disabled before this */
169 hw_breakpoint_disable();
168 /* 170 /*
169 * Now every CPU has IRQs off, we can clear out any pending 171 * Now every CPU has IRQs off, we can clear out any pending
170 * IPIs and be sure that no more will come in after this. 172 * IPIs and be sure that no more will come in after this.
@@ -180,6 +182,7 @@ static void kexec_prepare_cpus_wait(int wait_state)
180{ 182{
181 int my_cpu, i, notified=-1; 183 int my_cpu, i, notified=-1;
182 184
185 hw_breakpoint_disable();
183 my_cpu = get_cpu(); 186 my_cpu = get_cpu();
184 /* Make sure each CPU has atleast made it to the state we need */ 187 /* Make sure each CPU has atleast made it to the state we need */
185 for_each_online_cpu(i) { 188 for_each_online_cpu(i) {
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 773424df828a..1e78453645be 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -37,6 +37,7 @@
37#include <linux/kernel_stat.h> 37#include <linux/kernel_stat.h>
38#include <linux/personality.h> 38#include <linux/personality.h>
39#include <linux/random.h> 39#include <linux/random.h>
40#include <linux/hw_breakpoint.h>
40 41
41#include <asm/pgtable.h> 42#include <asm/pgtable.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
@@ -462,8 +463,14 @@ struct task_struct *__switch_to(struct task_struct *prev,
462#ifdef CONFIG_PPC_ADV_DEBUG_REGS 463#ifdef CONFIG_PPC_ADV_DEBUG_REGS
463 switch_booke_debug_regs(&new->thread); 464 switch_booke_debug_regs(&new->thread);
464#else 465#else
466/*
467 * For PPC_BOOK3S_64, we use the hw-breakpoint interfaces that would
468 * schedule DABR
469 */
470#ifndef CONFIG_HAVE_HW_BREAKPOINT
465 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) 471 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
466 set_dabr(new->thread.dabr); 472 set_dabr(new->thread.dabr);
473#endif /* CONFIG_HAVE_HW_BREAKPOINT */
467#endif 474#endif
468 475
469 476
@@ -642,7 +649,11 @@ void flush_thread(void)
642{ 649{
643 discard_lazy_cpu_state(); 650 discard_lazy_cpu_state();
644 651
652#ifdef CONFIG_HAVE_HW_BREAKPOINTS
653 flush_ptrace_hw_breakpoint(current);
654#else /* CONFIG_HAVE_HW_BREAKPOINTS */
645 set_debug_reg_defaults(&current->thread); 655 set_debug_reg_defaults(&current->thread);
656#endif /* CONFIG_HAVE_HW_BREAKPOINTS */
646} 657}
647 658
648void 659void
@@ -660,6 +671,9 @@ void prepare_to_copy(struct task_struct *tsk)
660 flush_altivec_to_thread(current); 671 flush_altivec_to_thread(current);
661 flush_vsx_to_thread(current); 672 flush_vsx_to_thread(current);
662 flush_spe_to_thread(current); 673 flush_spe_to_thread(current);
674#ifdef CONFIG_HAVE_HW_BREAKPOINT
675 flush_ptrace_hw_breakpoint(tsk);
676#endif /* CONFIG_HAVE_HW_BREAKPOINT */
663} 677}
664 678
665/* 679/*
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 7a0c0199ea28..11f3cd9c832f 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -32,6 +32,8 @@
32#ifdef CONFIG_PPC32 32#ifdef CONFIG_PPC32
33#include <linux/module.h> 33#include <linux/module.h>
34#endif 34#endif
35#include <linux/hw_breakpoint.h>
36#include <linux/perf_event.h>
35 37
36#include <asm/uaccess.h> 38#include <asm/uaccess.h>
37#include <asm/page.h> 39#include <asm/page.h>
@@ -866,9 +868,34 @@ void user_disable_single_step(struct task_struct *task)
866 clear_tsk_thread_flag(task, TIF_SINGLESTEP); 868 clear_tsk_thread_flag(task, TIF_SINGLESTEP);
867} 869}
868 870
871#ifdef CONFIG_HAVE_HW_BREAKPOINT
872void ptrace_triggered(struct perf_event *bp, int nmi,
873 struct perf_sample_data *data, struct pt_regs *regs)
874{
875 struct perf_event_attr attr;
876
877 /*
878 * Disable the breakpoint request here since ptrace has defined a
879 * one-shot behaviour for breakpoint exceptions in PPC64.
880 * The SIGTRAP signal is generated automatically for us in do_dabr().
881 * We don't have to do anything about that here
882 */
883 attr = bp->attr;
884 attr.disabled = true;
885 modify_user_hw_breakpoint(bp, &attr);
886}
887#endif /* CONFIG_HAVE_HW_BREAKPOINT */
888
869int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, 889int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
870 unsigned long data) 890 unsigned long data)
871{ 891{
892#ifdef CONFIG_HAVE_HW_BREAKPOINT
893 int ret;
894 struct thread_struct *thread = &(task->thread);
895 struct perf_event *bp;
896 struct perf_event_attr attr;
897#endif /* CONFIG_HAVE_HW_BREAKPOINT */
898
872 /* For ppc64 we support one DABR and no IABR's at the moment (ppc64). 899 /* For ppc64 we support one DABR and no IABR's at the moment (ppc64).
873 * For embedded processors we support one DAC and no IAC's at the 900 * For embedded processors we support one DAC and no IAC's at the
874 * moment. 901 * moment.
@@ -896,6 +923,43 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
896 /* Ensure breakpoint translation bit is set */ 923 /* Ensure breakpoint translation bit is set */
897 if (data && !(data & DABR_TRANSLATION)) 924 if (data && !(data & DABR_TRANSLATION))
898 return -EIO; 925 return -EIO;
926#ifdef CONFIG_HAVE_HW_BREAKPOINT
927 bp = thread->ptrace_bps[0];
928 if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) {
929 if (bp) {
930 unregister_hw_breakpoint(bp);
931 thread->ptrace_bps[0] = NULL;
932 }
933 return 0;
934 }
935 if (bp) {
936 attr = bp->attr;
937 attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
938 arch_bp_generic_fields(data &
939 (DABR_DATA_WRITE | DABR_DATA_READ),
940 &attr.bp_type);
941 ret = modify_user_hw_breakpoint(bp, &attr);
942 if (ret)
943 return ret;
944 thread->ptrace_bps[0] = bp;
945 thread->dabr = data;
946 return 0;
947 }
948
949 /* Create a new breakpoint request if one doesn't exist already */
950 hw_breakpoint_init(&attr);
951 attr.bp_addr = data & ~HW_BREAKPOINT_ALIGN;
952 arch_bp_generic_fields(data & (DABR_DATA_WRITE | DABR_DATA_READ),
953 &attr.bp_type);
954
955 thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
956 ptrace_triggered, task);
957 if (IS_ERR(bp)) {
958 thread->ptrace_bps[0] = NULL;
959 return PTR_ERR(bp);
960 }
961
962#endif /* CONFIG_HAVE_HW_BREAKPOINT */
899 963
900 /* Move contents to the DABR register */ 964 /* Move contents to the DABR register */
901 task->thread.dabr = data; 965 task->thread.dabr = data;
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a0afb555a7c9..7109f5b1baa8 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/tracehook.h> 12#include <linux/tracehook.h>
13#include <linux/signal.h> 13#include <linux/signal.h>
14#include <asm/hw_breakpoint.h>
14#include <asm/uaccess.h> 15#include <asm/uaccess.h>
15#include <asm/unistd.h> 16#include <asm/unistd.h>
16 17
@@ -149,6 +150,8 @@ static int do_signal_pending(sigset_t *oldset, struct pt_regs *regs)
149 if (current->thread.dabr) 150 if (current->thread.dabr)
150 set_dabr(current->thread.dabr); 151 set_dabr(current->thread.dabr);
151#endif 152#endif
153 /* Re-enable the breakpoints for the signal stack */
154 thread_change_pc(current, regs);
152 155
153 if (is32) { 156 if (is32) {
154 if (ka.sa.sa_flags & SA_SIGINFO) 157 if (ka.sa.sa_flags & SA_SIGINFO)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 25fc33984c2b..e5fe5a8522a6 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -688,7 +688,7 @@ void RunModeException(struct pt_regs *regs)
688 688
689void __kprobes single_step_exception(struct pt_regs *regs) 689void __kprobes single_step_exception(struct pt_regs *regs)
690{ 690{
691 regs->msr &= ~(MSR_SE | MSR_BE); /* Turn off 'trace' bits */ 691 clear_single_step(regs);
692 692
693 if (notify_die(DIE_SSTEP, "single_step", regs, 5, 693 if (notify_die(DIE_SSTEP, "single_step", regs, 5,
694 5, SIGTRAP) == NOTIFY_STOP) 694 5, SIGTRAP) == NOTIFY_STOP)
@@ -707,10 +707,8 @@ void __kprobes single_step_exception(struct pt_regs *regs)
707 */ 707 */
708static void emulate_single_step(struct pt_regs *regs) 708static void emulate_single_step(struct pt_regs *regs)
709{ 709{
710 if (single_stepping(regs)) { 710 if (single_stepping(regs))
711 clear_single_step(regs); 711 single_step_exception(regs);
712 _exception(SIGTRAP, regs, TRAP_TRACE, 0);
713 }
714} 712}
715 713
716static inline int __parse_fpscr(unsigned long fpscr) 714static inline int __parse_fpscr(unsigned long fpscr)