|
@@ -1336,12 +1336,6 @@ static int set_dac_range(struct task_struct *child,
|
|
|
static long ppc_set_hwdebug(struct task_struct *child,
|
|
|
struct ppc_hw_breakpoint *bp_info)
|
|
|
{
|
|
|
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
|
|
- int len = 0;
|
|
|
- struct thread_struct *thread = &(child->thread);
|
|
|
- struct perf_event *bp;
|
|
|
- struct perf_event_attr attr;
|
|
|
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
|
|
#ifndef CONFIG_PPC_ADV_DEBUG_REGS
|
|
|
unsigned long dabr;
|
|
|
#endif
|
|
@@ -1385,9 +1379,13 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|
|
*/
|
|
|
if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
|
|
|
(bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
|
|
|
+ bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
|
|
|
bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
|
|
|
return -EINVAL;
|
|
|
|
|
|
+ if (child->thread.dabr)
|
|
|
+ return -ENOSPC;
|
|
|
+
|
|
|
if ((unsigned long)bp_info->addr >= TASK_SIZE)
|
|
|
return -EIO;
|
|
|
|
|
@@ -1397,63 +1395,15 @@ static long ppc_set_hwdebug(struct task_struct *child,
|
|
|
dabr |= DABR_DATA_READ;
|
|
|
if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
|
|
|
dabr |= DABR_DATA_WRITE;
|
|
|
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
|
|
- if (ptrace_get_breakpoints(child) < 0)
|
|
|
- return -ESRCH;
|
|
|
-
|
|
|
- /*
|
|
|
- * Check if the request is for 'range' breakpoints. We can
|
|
|
- * support it if range < 8 bytes.
|
|
|
- */
|
|
|
- if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
|
|
|
- len = bp_info->addr2 - bp_info->addr;
|
|
|
- } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
|
|
|
- ptrace_put_breakpoints(child);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- bp = thread->ptrace_bps[0];
|
|
|
- if (bp) {
|
|
|
- ptrace_put_breakpoints(child);
|
|
|
- return -ENOSPC;
|
|
|
- }
|
|
|
-
|
|
|
- /* Create a new breakpoint request if one doesn't exist already */
|
|
|
- hw_breakpoint_init(&attr);
|
|
|
- attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
|
|
|
- attr.bp_len = len;
|
|
|
- arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
|
|
|
- &attr.bp_type);
|
|
|
-
|
|
|
- thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
|
|
|
- ptrace_triggered, NULL, child);
|
|
|
- if (IS_ERR(bp)) {
|
|
|
- thread->ptrace_bps[0] = NULL;
|
|
|
- ptrace_put_breakpoints(child);
|
|
|
- return PTR_ERR(bp);
|
|
|
- }
|
|
|
-
|
|
|
- ptrace_put_breakpoints(child);
|
|
|
- return 1;
|
|
|
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
|
|
-
|
|
|
- if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
|
|
|
- return -EINVAL;
|
|
|
-
|
|
|
- if (child->thread.dabr)
|
|
|
- return -ENOSPC;
|
|
|
|
|
|
child->thread.dabr = dabr;
|
|
|
+
|
|
|
return 1;
|
|
|
#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
|
|
|
}
|
|
|
|
|
|
static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
|
|
|
{
|
|
|
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
|
|
- int ret = 0;
|
|
|
- struct thread_struct *thread = &(child->thread);
|
|
|
- struct perf_event *bp;
|
|
|
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
|
|
#ifdef CONFIG_PPC_ADV_DEBUG_REGS
|
|
|
int rc;
|
|
|
|
|
@@ -1473,25 +1423,10 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
|
|
|
#else
|
|
|
if (data != 1)
|
|
|
return -EINVAL;
|
|
|
-
|
|
|
-#ifdef CONFIG_HAVE_HW_BREAKPOINT
|
|
|
- if (ptrace_get_breakpoints(child) < 0)
|
|
|
- return -ESRCH;
|
|
|
-
|
|
|
- bp = thread->ptrace_bps[0];
|
|
|
- if (bp) {
|
|
|
- unregister_hw_breakpoint(bp);
|
|
|
- thread->ptrace_bps[0] = NULL;
|
|
|
- } else
|
|
|
- ret = -ENOENT;
|
|
|
- ptrace_put_breakpoints(child);
|
|
|
- return ret;
|
|
|
-#else /* CONFIG_HAVE_HW_BREAKPOINT */
|
|
|
if (child->thread.dabr == 0)
|
|
|
return -ENOENT;
|
|
|
|
|
|
child->thread.dabr = 0;
|
|
|
-#endif /* CONFIG_HAVE_HW_BREAKPOINT */
|
|
|
|
|
|
return 0;
|
|
|
#endif
|
|
@@ -1598,7 +1533,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
|
|
dbginfo.data_bp_alignment = 4;
|
|
|
#endif
|
|
|
dbginfo.sizeof_condition = 0;
|
|
|
- dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE;
|
|
|
+ dbginfo.features = 0;
|
|
|
#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
|
|
|
|
|
|
if (!access_ok(VERIFY_WRITE, datavp,
|