aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/hw_breakpoint.c12
-rw-r--r--arch/powerpc/kernel/process.c14
-rw-r--r--arch/powerpc/kernel/ptrace.c3
-rw-r--r--arch/powerpc/kernel/signal.c2
4 files changed, 17 insertions, 14 deletions
diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c
index 6767445ecb45..6891d79ecef6 100644
--- a/arch/powerpc/kernel/hw_breakpoint.c
+++ b/arch/powerpc/kernel/hw_breakpoint.c
@@ -73,7 +73,7 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
73 * If so, DABR will be populated in single_step_dabr_instruction(). 73 * If so, DABR will be populated in single_step_dabr_instruction().
74 */ 74 */
75 if (current->thread.last_hit_ubp != bp) 75 if (current->thread.last_hit_ubp != bp)
76 set_dabr(info->address | info->type | DABR_TRANSLATION); 76 set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
77 77
78 return 0; 78 return 0;
79} 79}
@@ -97,7 +97,7 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
97 } 97 }
98 98
99 *slot = NULL; 99 *slot = NULL;
100 set_dabr(0); 100 set_dabr(0, 0);
101} 101}
102 102
103/* 103/*
@@ -197,7 +197,7 @@ void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs)
197 197
198 info = counter_arch_bp(tsk->thread.last_hit_ubp); 198 info = counter_arch_bp(tsk->thread.last_hit_ubp);
199 regs->msr &= ~MSR_SE; 199 regs->msr &= ~MSR_SE;
200 set_dabr(info->address | info->type | DABR_TRANSLATION); 200 set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
201 tsk->thread.last_hit_ubp = NULL; 201 tsk->thread.last_hit_ubp = NULL;
202} 202}
203 203
@@ -215,7 +215,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
215 unsigned long dar = regs->dar; 215 unsigned long dar = regs->dar;
216 216
217 /* Disable breakpoints during exception handling */ 217 /* Disable breakpoints during exception handling */
218 set_dabr(0); 218 set_dabr(0, 0);
219 219
220 /* 220 /*
221 * The counter may be concurrently released but that can only 221 * The counter may be concurrently released but that can only
@@ -281,7 +281,7 @@ int __kprobes hw_breakpoint_handler(struct die_args *args)
281 if (!info->extraneous_interrupt) 281 if (!info->extraneous_interrupt)
282 perf_bp_event(bp, regs); 282 perf_bp_event(bp, regs);
283 283
284 set_dabr(info->address | info->type | DABR_TRANSLATION); 284 set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
285out: 285out:
286 rcu_read_unlock(); 286 rcu_read_unlock();
287 return rc; 287 return rc;
@@ -313,7 +313,7 @@ int __kprobes single_step_dabr_instruction(struct die_args *args)
313 if (!info->extraneous_interrupt) 313 if (!info->extraneous_interrupt)
314 perf_bp_event(bp, regs); 314 perf_bp_event(bp, regs);
315 315
316 set_dabr(info->address | info->type | DABR_TRANSLATION); 316 set_dabr(info->address | info->type | DABR_TRANSLATION, DABRX_ALL);
317 current->thread.last_hit_ubp = NULL; 317 current->thread.last_hit_ubp = NULL;
318 318
319 /* 319 /*
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 2e743de545d0..50e504c29bb9 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -285,7 +285,7 @@ void do_dabr(struct pt_regs *regs, unsigned long address,
285 return; 285 return;
286 286
287 /* Clear the DABR */ 287 /* Clear the DABR */
288 set_dabr(0); 288 set_dabr(0, 0);
289 289
290 /* Deliver the signal to userspace */ 290 /* Deliver the signal to userspace */
291 info.si_signo = SIGTRAP; 291 info.si_signo = SIGTRAP;
@@ -366,18 +366,19 @@ static void set_debug_reg_defaults(struct thread_struct *thread)
366{ 366{
367 if (thread->dabr) { 367 if (thread->dabr) {
368 thread->dabr = 0; 368 thread->dabr = 0;
369 set_dabr(0); 369 thread->dabrx = 0;
370 set_dabr(0, 0);
370 } 371 }
371} 372}
372#endif /* !CONFIG_HAVE_HW_BREAKPOINT */ 373#endif /* !CONFIG_HAVE_HW_BREAKPOINT */
373#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ 374#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
374 375
375int set_dabr(unsigned long dabr) 376int set_dabr(unsigned long dabr, unsigned long dabrx)
376{ 377{
377 __get_cpu_var(current_dabr) = dabr; 378 __get_cpu_var(current_dabr) = dabr;
378 379
379 if (ppc_md.set_dabr) 380 if (ppc_md.set_dabr)
380 return ppc_md.set_dabr(dabr); 381 return ppc_md.set_dabr(dabr, dabrx);
381 382
382 /* XXX should we have a CPU_FTR_HAS_DABR ? */ 383 /* XXX should we have a CPU_FTR_HAS_DABR ? */
383#ifdef CONFIG_PPC_ADV_DEBUG_REGS 384#ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -387,9 +388,8 @@ int set_dabr(unsigned long dabr)
387#endif 388#endif
388#elif defined(CONFIG_PPC_BOOK3S) 389#elif defined(CONFIG_PPC_BOOK3S)
389 mtspr(SPRN_DABR, dabr); 390 mtspr(SPRN_DABR, dabr);
391 mtspr(SPRN_DABRX, dabrx);
390#endif 392#endif
391
392
393 return 0; 393 return 0;
394} 394}
395 395
@@ -482,7 +482,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
482 */ 482 */
483#ifndef CONFIG_HAVE_HW_BREAKPOINT 483#ifndef CONFIG_HAVE_HW_BREAKPOINT
484 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) 484 if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
485 set_dabr(new->thread.dabr); 485 set_dabr(new->thread.dabr, new->thread.dabrx);
486#endif /* CONFIG_HAVE_HW_BREAKPOINT */ 486#endif /* CONFIG_HAVE_HW_BREAKPOINT */
487#endif 487#endif
488 488
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index c10fc28b9092..79d8e56470df 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -960,6 +960,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
960 thread->ptrace_bps[0] = bp; 960 thread->ptrace_bps[0] = bp;
961 ptrace_put_breakpoints(task); 961 ptrace_put_breakpoints(task);
962 thread->dabr = data; 962 thread->dabr = data;
963 thread->dabrx = DABRX_ALL;
963 return 0; 964 return 0;
964 } 965 }
965 966
@@ -983,6 +984,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr,
983 984
984 /* Move contents to the DABR register */ 985 /* Move contents to the DABR register */
985 task->thread.dabr = data; 986 task->thread.dabr = data;
987 task->thread.dabrx = DABRX_ALL;
986#else /* CONFIG_PPC_ADV_DEBUG_REGS */ 988#else /* CONFIG_PPC_ADV_DEBUG_REGS */
987 /* As described above, it was assumed 3 bits were passed with the data 989 /* As described above, it was assumed 3 bits were passed with the data
988 * address, but we will assume only the mode bits will be passed 990 * address, but we will assume only the mode bits will be passed
@@ -1397,6 +1399,7 @@ static long ppc_set_hwdebug(struct task_struct *child,
1397 dabr |= DABR_DATA_WRITE; 1399 dabr |= DABR_DATA_WRITE;
1398 1400
1399 child->thread.dabr = dabr; 1401 child->thread.dabr = dabr;
1402 child->thread.dabrx = DABRX_ALL;
1400 1403
1401 return 1; 1404 return 1;
1402#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ 1405#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 29be2712e560..a2dc75793bd5 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -131,7 +131,7 @@ static int do_signal(struct pt_regs *regs)
131 * triggered inside the kernel. 131 * triggered inside the kernel.
132 */ 132 */
133 if (current->thread.dabr) 133 if (current->thread.dabr)
134 set_dabr(current->thread.dabr); 134 set_dabr(current->thread.dabr, current->thread.dabrx);
135#endif 135#endif
136 /* Re-enable the breakpoints for the signal stack */ 136 /* Re-enable the breakpoints for the signal stack */
137 thread_change_pc(current, regs); 137 thread_change_pc(current, regs);