aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2010-11-27 09:24:53 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2010-12-08 23:35:31 -0500
commit4dfbf290aeb9d63a058d9d8237203b0b72bfbbe3 (patch)
tree8619b01893ddc4222738ae2aada3605f56f2bd4a /arch/powerpc
parent364a1246522f99cbe58040e99af007ada31034ed (diff)
powerpc: Fix PPC_PTRACE_SETHWDEBUG on PPC_BOOK3S
Properly set the DABR_TRANSLATION/DABR_DATA_READ/DABR_DATA_READ bits in the dabr when setting the debug register via PPC_PTRACE_SETHWDEBUG. Also don't reject trigger type of PPC_BREAKPOINT_TRIGGER_READ. Signed-off-by: Andreas Schwab <schwab@linux-m68k.org> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/kernel/ptrace.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index a9b32967cff6..906536998291 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1316,6 +1316,10 @@ static int set_dac_range(struct task_struct *child,
1316static long ppc_set_hwdebug(struct task_struct *child, 1316static long ppc_set_hwdebug(struct task_struct *child,
1317 struct ppc_hw_breakpoint *bp_info) 1317 struct ppc_hw_breakpoint *bp_info)
1318{ 1318{
1319#ifndef CONFIG_PPC_ADV_DEBUG_REGS
1320 unsigned long dabr;
1321#endif
1322
1319 if (bp_info->version != 1) 1323 if (bp_info->version != 1)
1320 return -ENOTSUPP; 1324 return -ENOTSUPP;
1321#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1325#ifdef CONFIG_PPC_ADV_DEBUG_REGS
@@ -1353,11 +1357,10 @@ static long ppc_set_hwdebug(struct task_struct *child,
1353 /* 1357 /*
1354 * We only support one data breakpoint 1358 * We only support one data breakpoint
1355 */ 1359 */
1356 if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) || 1360 if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
1357 ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) || 1361 (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
1358 (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) || 1362 bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
1359 (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) || 1363 bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
1360 (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE))
1361 return -EINVAL; 1364 return -EINVAL;
1362 1365
1363 if (child->thread.dabr) 1366 if (child->thread.dabr)
@@ -1366,7 +1369,14 @@ static long ppc_set_hwdebug(struct task_struct *child,
1366 if ((unsigned long)bp_info->addr >= TASK_SIZE) 1369 if ((unsigned long)bp_info->addr >= TASK_SIZE)
1367 return -EIO; 1370 return -EIO;
1368 1371
1369 child->thread.dabr = (unsigned long)bp_info->addr; 1372 dabr = (unsigned long)bp_info->addr & ~7UL;
1373 dabr |= DABR_TRANSLATION;
1374 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ)
1375 dabr |= DABR_DATA_READ;
1376 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
1377 dabr |= DABR_DATA_WRITE;
1378
1379 child->thread.dabr = dabr;
1370 1380
1371 return 1; 1381 return 1;
1372#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ 1382#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */