aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/powerpc/ptrace.txt16
-rw-r--r--arch/powerpc/kernel/ptrace.c77
2 files changed, 6 insertions, 87 deletions
diff --git a/Documentation/powerpc/ptrace.txt b/Documentation/powerpc/ptrace.txt
index f2a7a3919772..f4a5499b7bc6 100644
--- a/Documentation/powerpc/ptrace.txt
+++ b/Documentation/powerpc/ptrace.txt
@@ -127,22 +127,6 @@ Some examples of using the structure to:
127 p.addr2 = (uint64_t) end_range; 127 p.addr2 = (uint64_t) end_range;
128 p.condition_value = 0; 128 p.condition_value = 0;
129 129
130- set a watchpoint in server processors (BookS)
131
132 p.version = 1;
133 p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW;
134 p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE;
135 or
136 p.addr_mode = PPC_BREAKPOINT_MODE_EXACT;
137
138 p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE;
139 p.addr = (uint64_t) begin_range;
140 /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where
141 * addr2 - addr <= 8 Bytes.
142 */
143 p.addr2 = (uint64_t) end_range;
144 p.condition_value = 0;
145
1463. PTRACE_DELHWDEBUG 1303. PTRACE_DELHWDEBUG
147 131
148Takes an integer which identifies an existing breakpoint or watchpoint 132Takes an integer which identifies an existing breakpoint or watchpoint
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index 8643ac890235..ac3cb008fb31 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -1336,12 +1336,6 @@ static int set_dac_range(struct task_struct *child,
1336static long ppc_set_hwdebug(struct task_struct *child, 1336static long ppc_set_hwdebug(struct task_struct *child,
1337 struct ppc_hw_breakpoint *bp_info) 1337 struct ppc_hw_breakpoint *bp_info)
1338{ 1338{
1339#ifdef CONFIG_HAVE_HW_BREAKPOINT
1340 int len = 0;
1341 struct thread_struct *thread = &(child->thread);
1342 struct perf_event *bp;
1343 struct perf_event_attr attr;
1344#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1345#ifndef CONFIG_PPC_ADV_DEBUG_REGS 1339#ifndef CONFIG_PPC_ADV_DEBUG_REGS
1346 unsigned long dabr; 1340 unsigned long dabr;
1347#endif 1341#endif
@@ -1385,9 +1379,13 @@ static long ppc_set_hwdebug(struct task_struct *child,
1385 */ 1379 */
1386 if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || 1380 if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 ||
1387 (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || 1381 (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 ||
1382 bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT ||
1388 bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) 1383 bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)
1389 return -EINVAL; 1384 return -EINVAL;
1390 1385
1386 if (child->thread.dabr)
1387 return -ENOSPC;
1388
1391 if ((unsigned long)bp_info->addr >= TASK_SIZE) 1389 if ((unsigned long)bp_info->addr >= TASK_SIZE)
1392 return -EIO; 1390 return -EIO;
1393 1391
@@ -1397,63 +1395,15 @@ static long ppc_set_hwdebug(struct task_struct *child,
1397 dabr |= DABR_DATA_READ; 1395 dabr |= DABR_DATA_READ;
1398 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) 1396 if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE)
1399 dabr |= DABR_DATA_WRITE; 1397 dabr |= DABR_DATA_WRITE;
1400#ifdef CONFIG_HAVE_HW_BREAKPOINT
1401 if (ptrace_get_breakpoints(child) < 0)
1402 return -ESRCH;
1403
1404 /*
1405 * Check if the request is for 'range' breakpoints. We can
1406 * support it if range < 8 bytes.
1407 */
1408 if (bp_info->addr_mode == PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE) {
1409 len = bp_info->addr2 - bp_info->addr;
1410 } else if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) {
1411 ptrace_put_breakpoints(child);
1412 return -EINVAL;
1413 }
1414 bp = thread->ptrace_bps[0];
1415 if (bp) {
1416 ptrace_put_breakpoints(child);
1417 return -ENOSPC;
1418 }
1419
1420 /* Create a new breakpoint request if one doesn't exist already */
1421 hw_breakpoint_init(&attr);
1422 attr.bp_addr = (unsigned long)bp_info->addr & ~HW_BREAKPOINT_ALIGN;
1423 attr.bp_len = len;
1424 arch_bp_generic_fields(dabr & (DABR_DATA_WRITE | DABR_DATA_READ),
1425 &attr.bp_type);
1426
1427 thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr,
1428 ptrace_triggered, NULL, child);
1429 if (IS_ERR(bp)) {
1430 thread->ptrace_bps[0] = NULL;
1431 ptrace_put_breakpoints(child);
1432 return PTR_ERR(bp);
1433 }
1434
1435 ptrace_put_breakpoints(child);
1436 return 1;
1437#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1438
1439 if (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT)
1440 return -EINVAL;
1441
1442 if (child->thread.dabr)
1443 return -ENOSPC;
1444 1398
1445 child->thread.dabr = dabr; 1399 child->thread.dabr = dabr;
1400
1446 return 1; 1401 return 1;
1447#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ 1402#endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */
1448} 1403}
1449 1404
1450static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) 1405static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
1451{ 1406{
1452#ifdef CONFIG_HAVE_HW_BREAKPOINT
1453 int ret = 0;
1454 struct thread_struct *thread = &(child->thread);
1455 struct perf_event *bp;
1456#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1457#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1407#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1458 int rc; 1408 int rc;
1459 1409
@@ -1473,25 +1423,10 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data)
1473#else 1423#else
1474 if (data != 1) 1424 if (data != 1)
1475 return -EINVAL; 1425 return -EINVAL;
1476
1477#ifdef CONFIG_HAVE_HW_BREAKPOINT
1478 if (ptrace_get_breakpoints(child) < 0)
1479 return -ESRCH;
1480
1481 bp = thread->ptrace_bps[0];
1482 if (bp) {
1483 unregister_hw_breakpoint(bp);
1484 thread->ptrace_bps[0] = NULL;
1485 } else
1486 ret = -ENOENT;
1487 ptrace_put_breakpoints(child);
1488 return ret;
1489#else /* CONFIG_HAVE_HW_BREAKPOINT */
1490 if (child->thread.dabr == 0) 1426 if (child->thread.dabr == 0)
1491 return -ENOENT; 1427 return -ENOENT;
1492 1428
1493 child->thread.dabr = 0; 1429 child->thread.dabr = 0;
1494#endif /* CONFIG_HAVE_HW_BREAKPOINT */
1495 1430
1496 return 0; 1431 return 0;
1497#endif 1432#endif
@@ -1598,7 +1533,7 @@ long arch_ptrace(struct task_struct *child, long request,
1598 dbginfo.data_bp_alignment = 4; 1533 dbginfo.data_bp_alignment = 4;
1599#endif 1534#endif
1600 dbginfo.sizeof_condition = 0; 1535 dbginfo.sizeof_condition = 0;
1601 dbginfo.features = PPC_DEBUG_FEATURE_DATA_BP_RANGE; 1536 dbginfo.features = 0;
1602#endif /* CONFIG_PPC_ADV_DEBUG_REGS */ 1537#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
1603 1538
1604 if (!access_ok(VERIFY_WRITE, datavp, 1539 if (!access_ok(VERIFY_WRITE, datavp,