diff options
author | Andreas Schwab <schwab@linux-m68k.org> | 2010-11-27 09:24:53 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-12-08 23:35:31 -0500 |
commit | 4dfbf290aeb9d63a058d9d8237203b0b72bfbbe3 (patch) | |
tree | 8619b01893ddc4222738ae2aada3605f56f2bd4a /arch/powerpc/kernel/ptrace.c | |
parent | 364a1246522f99cbe58040e99af007ada31034ed (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/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 22 |
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, | |||
1316 | static long ppc_set_hwdebug(struct task_struct *child, | 1316 | static 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 */ |