diff options
Diffstat (limited to 'arch/powerpc/kernel/ptrace.c')
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 129 |
1 files changed, 85 insertions, 44 deletions
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 11f3cd9c832f..cb22024f2b42 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/signal.h> | 29 | #include <linux/signal.h> |
30 | #include <linux/seccomp.h> | 30 | #include <linux/seccomp.h> |
31 | #include <linux/audit.h> | 31 | #include <linux/audit.h> |
32 | #include <trace/syscall.h> | ||
32 | #ifdef CONFIG_PPC32 | 33 | #ifdef CONFIG_PPC32 |
33 | #include <linux/module.h> | 34 | #include <linux/module.h> |
34 | #endif | 35 | #endif |
@@ -40,6 +41,9 @@ | |||
40 | #include <asm/pgtable.h> | 41 | #include <asm/pgtable.h> |
41 | #include <asm/system.h> | 42 | #include <asm/system.h> |
42 | 43 | ||
44 | #define CREATE_TRACE_POINTS | ||
45 | #include <trace/events/syscalls.h> | ||
46 | |||
43 | /* | 47 | /* |
44 | * The parameter save area on the stack is used to store arguments being passed | 48 | * The parameter save area on the stack is used to store arguments being passed |
45 | * to callee function and is located at fixed offset from stack pointer. | 49 | * to callee function and is located at fixed offset from stack pointer. |
@@ -229,12 +233,16 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset, | |||
229 | unsigned int pos, unsigned int count, | 233 | unsigned int pos, unsigned int count, |
230 | void *kbuf, void __user *ubuf) | 234 | void *kbuf, void __user *ubuf) |
231 | { | 235 | { |
232 | int ret; | 236 | int i, ret; |
233 | 237 | ||
234 | if (target->thread.regs == NULL) | 238 | if (target->thread.regs == NULL) |
235 | return -EIO; | 239 | return -EIO; |
236 | 240 | ||
237 | CHECK_FULL_REGS(target->thread.regs); | 241 | if (!FULL_REGS(target->thread.regs)) { |
242 | /* We have a partial register set. Fill 14-31 with bogus values */ | ||
243 | for (i = 14; i < 32; i++) | ||
244 | target->thread.regs->gpr[i] = NV_REG_POISON; | ||
245 | } | ||
238 | 246 | ||
239 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 247 | ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
240 | target->thread.regs, | 248 | target->thread.regs, |
@@ -459,7 +467,7 @@ static int vr_set(struct task_struct *target, const struct user_regset *regset, | |||
459 | #ifdef CONFIG_VSX | 467 | #ifdef CONFIG_VSX |
460 | /* | 468 | /* |
461 | * Currently to set and and get all the vsx state, you need to call | 469 | * Currently to set and and get all the vsx state, you need to call |
462 | * the fp and VMX calls aswell. This only get/sets the lower 32 | 470 | * the fp and VMX calls as well. This only get/sets the lower 32 |
463 | * 128bit VSX registers. | 471 | * 128bit VSX registers. |
464 | */ | 472 | */ |
465 | 473 | ||
@@ -641,11 +649,16 @@ static int gpr32_get(struct task_struct *target, | |||
641 | compat_ulong_t *k = kbuf; | 649 | compat_ulong_t *k = kbuf; |
642 | compat_ulong_t __user *u = ubuf; | 650 | compat_ulong_t __user *u = ubuf; |
643 | compat_ulong_t reg; | 651 | compat_ulong_t reg; |
652 | int i; | ||
644 | 653 | ||
645 | if (target->thread.regs == NULL) | 654 | if (target->thread.regs == NULL) |
646 | return -EIO; | 655 | return -EIO; |
647 | 656 | ||
648 | CHECK_FULL_REGS(target->thread.regs); | 657 | if (!FULL_REGS(target->thread.regs)) { |
658 | /* We have a partial register set. Fill 14-31 with bogus values */ | ||
659 | for (i = 14; i < 32; i++) | ||
660 | target->thread.regs->gpr[i] = NV_REG_POISON; | ||
661 | } | ||
649 | 662 | ||
650 | pos /= sizeof(reg); | 663 | pos /= sizeof(reg); |
651 | count /= sizeof(reg); | 664 | count /= sizeof(reg); |
@@ -924,12 +937,16 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
924 | if (data && !(data & DABR_TRANSLATION)) | 937 | if (data && !(data & DABR_TRANSLATION)) |
925 | return -EIO; | 938 | return -EIO; |
926 | #ifdef CONFIG_HAVE_HW_BREAKPOINT | 939 | #ifdef CONFIG_HAVE_HW_BREAKPOINT |
940 | if (ptrace_get_breakpoints(task) < 0) | ||
941 | return -ESRCH; | ||
942 | |||
927 | bp = thread->ptrace_bps[0]; | 943 | bp = thread->ptrace_bps[0]; |
928 | if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { | 944 | if ((!data) || !(data & (DABR_DATA_WRITE | DABR_DATA_READ))) { |
929 | if (bp) { | 945 | if (bp) { |
930 | unregister_hw_breakpoint(bp); | 946 | unregister_hw_breakpoint(bp); |
931 | thread->ptrace_bps[0] = NULL; | 947 | thread->ptrace_bps[0] = NULL; |
932 | } | 948 | } |
949 | ptrace_put_breakpoints(task); | ||
933 | return 0; | 950 | return 0; |
934 | } | 951 | } |
935 | if (bp) { | 952 | if (bp) { |
@@ -939,9 +956,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
939 | (DABR_DATA_WRITE | DABR_DATA_READ), | 956 | (DABR_DATA_WRITE | DABR_DATA_READ), |
940 | &attr.bp_type); | 957 | &attr.bp_type); |
941 | ret = modify_user_hw_breakpoint(bp, &attr); | 958 | ret = modify_user_hw_breakpoint(bp, &attr); |
942 | if (ret) | 959 | if (ret) { |
960 | ptrace_put_breakpoints(task); | ||
943 | return ret; | 961 | return ret; |
962 | } | ||
944 | thread->ptrace_bps[0] = bp; | 963 | thread->ptrace_bps[0] = bp; |
964 | ptrace_put_breakpoints(task); | ||
945 | thread->dabr = data; | 965 | thread->dabr = data; |
946 | return 0; | 966 | return 0; |
947 | } | 967 | } |
@@ -956,9 +976,12 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
956 | ptrace_triggered, task); | 976 | ptrace_triggered, task); |
957 | if (IS_ERR(bp)) { | 977 | if (IS_ERR(bp)) { |
958 | thread->ptrace_bps[0] = NULL; | 978 | thread->ptrace_bps[0] = NULL; |
979 | ptrace_put_breakpoints(task); | ||
959 | return PTR_ERR(bp); | 980 | return PTR_ERR(bp); |
960 | } | 981 | } |
961 | 982 | ||
983 | ptrace_put_breakpoints(task); | ||
984 | |||
962 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ | 985 | #endif /* CONFIG_HAVE_HW_BREAKPOINT */ |
963 | 986 | ||
964 | /* Move contents to the DABR register */ | 987 | /* Move contents to the DABR register */ |
@@ -1316,6 +1339,10 @@ static int set_dac_range(struct task_struct *child, | |||
1316 | static long ppc_set_hwdebug(struct task_struct *child, | 1339 | static long ppc_set_hwdebug(struct task_struct *child, |
1317 | struct ppc_hw_breakpoint *bp_info) | 1340 | struct ppc_hw_breakpoint *bp_info) |
1318 | { | 1341 | { |
1342 | #ifndef CONFIG_PPC_ADV_DEBUG_REGS | ||
1343 | unsigned long dabr; | ||
1344 | #endif | ||
1345 | |||
1319 | if (bp_info->version != 1) | 1346 | if (bp_info->version != 1) |
1320 | return -ENOTSUPP; | 1347 | return -ENOTSUPP; |
1321 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 1348 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
@@ -1353,11 +1380,10 @@ static long ppc_set_hwdebug(struct task_struct *child, | |||
1353 | /* | 1380 | /* |
1354 | * We only support one data breakpoint | 1381 | * We only support one data breakpoint |
1355 | */ | 1382 | */ |
1356 | if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) || | 1383 | if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || |
1357 | ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) || | 1384 | (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || |
1358 | (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) || | 1385 | bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT || |
1359 | (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) || | 1386 | bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) |
1360 | (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)) | ||
1361 | return -EINVAL; | 1387 | return -EINVAL; |
1362 | 1388 | ||
1363 | if (child->thread.dabr) | 1389 | if (child->thread.dabr) |
@@ -1366,7 +1392,14 @@ static long ppc_set_hwdebug(struct task_struct *child, | |||
1366 | if ((unsigned long)bp_info->addr >= TASK_SIZE) | 1392 | if ((unsigned long)bp_info->addr >= TASK_SIZE) |
1367 | return -EIO; | 1393 | return -EIO; |
1368 | 1394 | ||
1369 | child->thread.dabr = (unsigned long)bp_info->addr; | 1395 | dabr = (unsigned long)bp_info->addr & ~7UL; |
1396 | dabr |= DABR_TRANSLATION; | ||
1397 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) | ||
1398 | dabr |= DABR_DATA_READ; | ||
1399 | if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) | ||
1400 | dabr |= DABR_DATA_WRITE; | ||
1401 | |||
1402 | child->thread.dabr = dabr; | ||
1370 | 1403 | ||
1371 | return 1; | 1404 | return 1; |
1372 | #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ | 1405 | #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ |
@@ -1406,37 +1439,42 @@ static long ppc_del_hwdebug(struct task_struct *child, long addr, long data) | |||
1406 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, | 1439 | * Here are the old "legacy" powerpc specific getregs/setregs ptrace calls, |
1407 | * we mark them as obsolete now, they will be removed in a future version | 1440 | * we mark them as obsolete now, they will be removed in a future version |
1408 | */ | 1441 | */ |
1409 | static long arch_ptrace_old(struct task_struct *child, long request, long addr, | 1442 | static long arch_ptrace_old(struct task_struct *child, long request, |
1410 | long data) | 1443 | unsigned long addr, unsigned long data) |
1411 | { | 1444 | { |
1445 | void __user *datavp = (void __user *) data; | ||
1446 | |||
1412 | switch (request) { | 1447 | switch (request) { |
1413 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ | 1448 | case PPC_PTRACE_GETREGS: /* Get GPRs 0 - 31. */ |
1414 | return copy_regset_to_user(child, &user_ppc_native_view, | 1449 | return copy_regset_to_user(child, &user_ppc_native_view, |
1415 | REGSET_GPR, 0, 32 * sizeof(long), | 1450 | REGSET_GPR, 0, 32 * sizeof(long), |
1416 | (void __user *) data); | 1451 | datavp); |
1417 | 1452 | ||
1418 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ | 1453 | case PPC_PTRACE_SETREGS: /* Set GPRs 0 - 31. */ |
1419 | return copy_regset_from_user(child, &user_ppc_native_view, | 1454 | return copy_regset_from_user(child, &user_ppc_native_view, |
1420 | REGSET_GPR, 0, 32 * sizeof(long), | 1455 | REGSET_GPR, 0, 32 * sizeof(long), |
1421 | (const void __user *) data); | 1456 | datavp); |
1422 | 1457 | ||
1423 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ | 1458 | case PPC_PTRACE_GETFPREGS: /* Get FPRs 0 - 31. */ |
1424 | return copy_regset_to_user(child, &user_ppc_native_view, | 1459 | return copy_regset_to_user(child, &user_ppc_native_view, |
1425 | REGSET_FPR, 0, 32 * sizeof(double), | 1460 | REGSET_FPR, 0, 32 * sizeof(double), |
1426 | (void __user *) data); | 1461 | datavp); |
1427 | 1462 | ||
1428 | case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */ | 1463 | case PPC_PTRACE_SETFPREGS: /* Set FPRs 0 - 31. */ |
1429 | return copy_regset_from_user(child, &user_ppc_native_view, | 1464 | return copy_regset_from_user(child, &user_ppc_native_view, |
1430 | REGSET_FPR, 0, 32 * sizeof(double), | 1465 | REGSET_FPR, 0, 32 * sizeof(double), |
1431 | (const void __user *) data); | 1466 | datavp); |
1432 | } | 1467 | } |
1433 | 1468 | ||
1434 | return -EPERM; | 1469 | return -EPERM; |
1435 | } | 1470 | } |
1436 | 1471 | ||
1437 | long arch_ptrace(struct task_struct *child, long request, long addr, long data) | 1472 | long arch_ptrace(struct task_struct *child, long request, |
1473 | unsigned long addr, unsigned long data) | ||
1438 | { | 1474 | { |
1439 | int ret = -EPERM; | 1475 | int ret = -EPERM; |
1476 | void __user *datavp = (void __user *) data; | ||
1477 | unsigned long __user *datalp = datavp; | ||
1440 | 1478 | ||
1441 | switch (request) { | 1479 | switch (request) { |
1442 | /* read the word at location addr in the USER area. */ | 1480 | /* read the word at location addr in the USER area. */ |
@@ -1446,11 +1484,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1446 | ret = -EIO; | 1484 | ret = -EIO; |
1447 | /* convert to index and check */ | 1485 | /* convert to index and check */ |
1448 | #ifdef CONFIG_PPC32 | 1486 | #ifdef CONFIG_PPC32 |
1449 | index = (unsigned long) addr >> 2; | 1487 | index = addr >> 2; |
1450 | if ((addr & 3) || (index > PT_FPSCR) | 1488 | if ((addr & 3) || (index > PT_FPSCR) |
1451 | || (child->thread.regs == NULL)) | 1489 | || (child->thread.regs == NULL)) |
1452 | #else | 1490 | #else |
1453 | index = (unsigned long) addr >> 3; | 1491 | index = addr >> 3; |
1454 | if ((addr & 7) || (index > PT_FPSCR)) | 1492 | if ((addr & 7) || (index > PT_FPSCR)) |
1455 | #endif | 1493 | #endif |
1456 | break; | 1494 | break; |
@@ -1463,7 +1501,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1463 | tmp = ((unsigned long *)child->thread.fpr) | 1501 | tmp = ((unsigned long *)child->thread.fpr) |
1464 | [TS_FPRWIDTH * (index - PT_FPR0)]; | 1502 | [TS_FPRWIDTH * (index - PT_FPR0)]; |
1465 | } | 1503 | } |
1466 | ret = put_user(tmp,(unsigned long __user *) data); | 1504 | ret = put_user(tmp, datalp); |
1467 | break; | 1505 | break; |
1468 | } | 1506 | } |
1469 | 1507 | ||
@@ -1474,11 +1512,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1474 | ret = -EIO; | 1512 | ret = -EIO; |
1475 | /* convert to index and check */ | 1513 | /* convert to index and check */ |
1476 | #ifdef CONFIG_PPC32 | 1514 | #ifdef CONFIG_PPC32 |
1477 | index = (unsigned long) addr >> 2; | 1515 | index = addr >> 2; |
1478 | if ((addr & 3) || (index > PT_FPSCR) | 1516 | if ((addr & 3) || (index > PT_FPSCR) |
1479 | || (child->thread.regs == NULL)) | 1517 | || (child->thread.regs == NULL)) |
1480 | #else | 1518 | #else |
1481 | index = (unsigned long) addr >> 3; | 1519 | index = addr >> 3; |
1482 | if ((addr & 7) || (index > PT_FPSCR)) | 1520 | if ((addr & 7) || (index > PT_FPSCR)) |
1483 | #endif | 1521 | #endif |
1484 | break; | 1522 | break; |
@@ -1525,11 +1563,11 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1525 | dbginfo.features = 0; | 1563 | dbginfo.features = 0; |
1526 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ | 1564 | #endif /* CONFIG_PPC_ADV_DEBUG_REGS */ |
1527 | 1565 | ||
1528 | if (!access_ok(VERIFY_WRITE, data, | 1566 | if (!access_ok(VERIFY_WRITE, datavp, |
1529 | sizeof(struct ppc_debug_info))) | 1567 | sizeof(struct ppc_debug_info))) |
1530 | return -EFAULT; | 1568 | return -EFAULT; |
1531 | ret = __copy_to_user((struct ppc_debug_info __user *)data, | 1569 | ret = __copy_to_user(datavp, &dbginfo, |
1532 | &dbginfo, sizeof(struct ppc_debug_info)) ? | 1570 | sizeof(struct ppc_debug_info)) ? |
1533 | -EFAULT : 0; | 1571 | -EFAULT : 0; |
1534 | break; | 1572 | break; |
1535 | } | 1573 | } |
@@ -1537,11 +1575,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1537 | case PPC_PTRACE_SETHWDEBUG: { | 1575 | case PPC_PTRACE_SETHWDEBUG: { |
1538 | struct ppc_hw_breakpoint bp_info; | 1576 | struct ppc_hw_breakpoint bp_info; |
1539 | 1577 | ||
1540 | if (!access_ok(VERIFY_READ, data, | 1578 | if (!access_ok(VERIFY_READ, datavp, |
1541 | sizeof(struct ppc_hw_breakpoint))) | 1579 | sizeof(struct ppc_hw_breakpoint))) |
1542 | return -EFAULT; | 1580 | return -EFAULT; |
1543 | ret = __copy_from_user(&bp_info, | 1581 | ret = __copy_from_user(&bp_info, datavp, |
1544 | (struct ppc_hw_breakpoint __user *)data, | ||
1545 | sizeof(struct ppc_hw_breakpoint)) ? | 1582 | sizeof(struct ppc_hw_breakpoint)) ? |
1546 | -EFAULT : 0; | 1583 | -EFAULT : 0; |
1547 | if (!ret) | 1584 | if (!ret) |
@@ -1560,11 +1597,9 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1560 | if (addr > 0) | 1597 | if (addr > 0) |
1561 | break; | 1598 | break; |
1562 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS | 1599 | #ifdef CONFIG_PPC_ADV_DEBUG_REGS |
1563 | ret = put_user(child->thread.dac1, | 1600 | ret = put_user(child->thread.dac1, datalp); |
1564 | (unsigned long __user *)data); | ||
1565 | #else | 1601 | #else |
1566 | ret = put_user(child->thread.dabr, | 1602 | ret = put_user(child->thread.dabr, datalp); |
1567 | (unsigned long __user *)data); | ||
1568 | #endif | 1603 | #endif |
1569 | break; | 1604 | break; |
1570 | } | 1605 | } |
@@ -1580,7 +1615,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1580 | return copy_regset_to_user(child, &user_ppc_native_view, | 1615 | return copy_regset_to_user(child, &user_ppc_native_view, |
1581 | REGSET_GPR, | 1616 | REGSET_GPR, |
1582 | 0, sizeof(struct pt_regs), | 1617 | 0, sizeof(struct pt_regs), |
1583 | (void __user *) data); | 1618 | datavp); |
1584 | 1619 | ||
1585 | #ifdef CONFIG_PPC64 | 1620 | #ifdef CONFIG_PPC64 |
1586 | case PTRACE_SETREGS64: | 1621 | case PTRACE_SETREGS64: |
@@ -1589,19 +1624,19 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1589 | return copy_regset_from_user(child, &user_ppc_native_view, | 1624 | return copy_regset_from_user(child, &user_ppc_native_view, |
1590 | REGSET_GPR, | 1625 | REGSET_GPR, |
1591 | 0, sizeof(struct pt_regs), | 1626 | 0, sizeof(struct pt_regs), |
1592 | (const void __user *) data); | 1627 | datavp); |
1593 | 1628 | ||
1594 | case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ | 1629 | case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */ |
1595 | return copy_regset_to_user(child, &user_ppc_native_view, | 1630 | return copy_regset_to_user(child, &user_ppc_native_view, |
1596 | REGSET_FPR, | 1631 | REGSET_FPR, |
1597 | 0, sizeof(elf_fpregset_t), | 1632 | 0, sizeof(elf_fpregset_t), |
1598 | (void __user *) data); | 1633 | datavp); |
1599 | 1634 | ||
1600 | case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ | 1635 | case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */ |
1601 | return copy_regset_from_user(child, &user_ppc_native_view, | 1636 | return copy_regset_from_user(child, &user_ppc_native_view, |
1602 | REGSET_FPR, | 1637 | REGSET_FPR, |
1603 | 0, sizeof(elf_fpregset_t), | 1638 | 0, sizeof(elf_fpregset_t), |
1604 | (const void __user *) data); | 1639 | datavp); |
1605 | 1640 | ||
1606 | #ifdef CONFIG_ALTIVEC | 1641 | #ifdef CONFIG_ALTIVEC |
1607 | case PTRACE_GETVRREGS: | 1642 | case PTRACE_GETVRREGS: |
@@ -1609,40 +1644,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
1609 | REGSET_VMX, | 1644 | REGSET_VMX, |
1610 | 0, (33 * sizeof(vector128) + | 1645 | 0, (33 * sizeof(vector128) + |
1611 | sizeof(u32)), | 1646 | sizeof(u32)), |
1612 | (void __user *) data); | 1647 | datavp); |
1613 | 1648 | ||
1614 | case PTRACE_SETVRREGS: | 1649 | case PTRACE_SETVRREGS: |
1615 | return copy_regset_from_user(child, &user_ppc_native_view, | 1650 | return copy_regset_from_user(child, &user_ppc_native_view, |
1616 | REGSET_VMX, | 1651 | REGSET_VMX, |
1617 | 0, (33 * sizeof(vector128) + | 1652 | 0, (33 * sizeof(vector128) + |
1618 | sizeof(u32)), | 1653 | sizeof(u32)), |
1619 | (const void __user *) data); | 1654 | datavp); |
1620 | #endif | 1655 | #endif |
1621 | #ifdef CONFIG_VSX | 1656 | #ifdef CONFIG_VSX |
1622 | case PTRACE_GETVSRREGS: | 1657 | case PTRACE_GETVSRREGS: |
1623 | return copy_regset_to_user(child, &user_ppc_native_view, | 1658 | return copy_regset_to_user(child, &user_ppc_native_view, |
1624 | REGSET_VSX, | 1659 | REGSET_VSX, |
1625 | 0, 32 * sizeof(double), | 1660 | 0, 32 * sizeof(double), |
1626 | (void __user *) data); | 1661 | datavp); |
1627 | 1662 | ||
1628 | case PTRACE_SETVSRREGS: | 1663 | case PTRACE_SETVSRREGS: |
1629 | return copy_regset_from_user(child, &user_ppc_native_view, | 1664 | return copy_regset_from_user(child, &user_ppc_native_view, |
1630 | REGSET_VSX, | 1665 | REGSET_VSX, |
1631 | 0, 32 * sizeof(double), | 1666 | 0, 32 * sizeof(double), |
1632 | (const void __user *) data); | 1667 | datavp); |
1633 | #endif | 1668 | #endif |
1634 | #ifdef CONFIG_SPE | 1669 | #ifdef CONFIG_SPE |
1635 | case PTRACE_GETEVRREGS: | 1670 | case PTRACE_GETEVRREGS: |
1636 | /* Get the child spe register state. */ | 1671 | /* Get the child spe register state. */ |
1637 | return copy_regset_to_user(child, &user_ppc_native_view, | 1672 | return copy_regset_to_user(child, &user_ppc_native_view, |
1638 | REGSET_SPE, 0, 35 * sizeof(u32), | 1673 | REGSET_SPE, 0, 35 * sizeof(u32), |
1639 | (void __user *) data); | 1674 | datavp); |
1640 | 1675 | ||
1641 | case PTRACE_SETEVRREGS: | 1676 | case PTRACE_SETEVRREGS: |
1642 | /* Set the child spe register state. */ | 1677 | /* Set the child spe register state. */ |
1643 | return copy_regset_from_user(child, &user_ppc_native_view, | 1678 | return copy_regset_from_user(child, &user_ppc_native_view, |
1644 | REGSET_SPE, 0, 35 * sizeof(u32), | 1679 | REGSET_SPE, 0, 35 * sizeof(u32), |
1645 | (const void __user *) data); | 1680 | datavp); |
1646 | #endif | 1681 | #endif |
1647 | 1682 | ||
1648 | /* Old reverse args ptrace callss */ | 1683 | /* Old reverse args ptrace callss */ |
@@ -1679,9 +1714,12 @@ long do_syscall_trace_enter(struct pt_regs *regs) | |||
1679 | */ | 1714 | */ |
1680 | ret = -1L; | 1715 | ret = -1L; |
1681 | 1716 | ||
1717 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
1718 | trace_sys_enter(regs, regs->gpr[0]); | ||
1719 | |||
1682 | if (unlikely(current->audit_context)) { | 1720 | if (unlikely(current->audit_context)) { |
1683 | #ifdef CONFIG_PPC64 | 1721 | #ifdef CONFIG_PPC64 |
1684 | if (!test_thread_flag(TIF_32BIT)) | 1722 | if (!is_32bit_task()) |
1685 | audit_syscall_entry(AUDIT_ARCH_PPC64, | 1723 | audit_syscall_entry(AUDIT_ARCH_PPC64, |
1686 | regs->gpr[0], | 1724 | regs->gpr[0], |
1687 | regs->gpr[3], regs->gpr[4], | 1725 | regs->gpr[3], regs->gpr[4], |
@@ -1707,6 +1745,9 @@ void do_syscall_trace_leave(struct pt_regs *regs) | |||
1707 | audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, | 1745 | audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, |
1708 | regs->result); | 1746 | regs->result); |
1709 | 1747 | ||
1748 | if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) | ||
1749 | trace_sys_exit(regs, regs->result); | ||
1750 | |||
1710 | step = test_thread_flag(TIF_SINGLESTEP); | 1751 | step = test_thread_flag(TIF_SINGLESTEP); |
1711 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) | 1752 | if (step || test_thread_flag(TIF_SYSCALL_TRACE)) |
1712 | tracehook_report_syscall_exit(regs, step); | 1753 | tracehook_report_syscall_exit(regs, step); |