diff options
Diffstat (limited to 'arch/ia64/kernel/ptrace.c')
-rw-r--r-- | arch/ia64/kernel/ptrace.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c index 9e730c7bf0cd..4c1d2f5442b3 100644 --- a/arch/ia64/kernel/ptrace.c +++ b/arch/ia64/kernel/ptrace.c | |||
@@ -635,11 +635,17 @@ ia64_flush_fph (struct task_struct *task) | |||
635 | { | 635 | { |
636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); | 636 | struct ia64_psr *psr = ia64_psr(ia64_task_regs(task)); |
637 | 637 | ||
638 | /* | ||
639 | * Prevent migrating this task while | ||
640 | * we're fiddling with the FPU state | ||
641 | */ | ||
642 | preempt_disable(); | ||
638 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { | 643 | if (ia64_is_local_fpu_owner(task) && psr->mfh) { |
639 | psr->mfh = 0; | 644 | psr->mfh = 0; |
640 | task->thread.flags |= IA64_THREAD_FPH_VALID; | 645 | task->thread.flags |= IA64_THREAD_FPH_VALID; |
641 | ia64_save_fpu(&task->thread.fph[0]); | 646 | ia64_save_fpu(&task->thread.fph[0]); |
642 | } | 647 | } |
648 | preempt_enable(); | ||
643 | } | 649 | } |
644 | 650 | ||
645 | /* | 651 | /* |
@@ -692,16 +698,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs *pt, | |||
692 | unsigned long cfm) | 698 | unsigned long cfm) |
693 | { | 699 | { |
694 | struct unw_frame_info info, prev_info; | 700 | struct unw_frame_info info, prev_info; |
695 | unsigned long ip, pr; | 701 | unsigned long ip, sp, pr; |
696 | 702 | ||
697 | unw_init_from_blocked_task(&info, child); | 703 | unw_init_from_blocked_task(&info, child); |
698 | while (1) { | 704 | while (1) { |
699 | prev_info = info; | 705 | prev_info = info; |
700 | if (unw_unwind(&info) < 0) | 706 | if (unw_unwind(&info) < 0) |
701 | return; | 707 | return; |
702 | if (unw_get_rp(&info, &ip) < 0) | 708 | |
709 | unw_get_sp(&info, &sp); | ||
710 | if ((long)((unsigned long)child + IA64_STK_OFFSET - sp) | ||
711 | < IA64_PT_REGS_SIZE) { | ||
712 | dprintk("ptrace.%s: ran off the top of the kernel " | ||
713 | "stack\n", __FUNCTION__); | ||
714 | return; | ||
715 | } | ||
716 | if (unw_get_pr (&prev_info, &pr) < 0) { | ||
717 | unw_get_rp(&prev_info, &ip); | ||
718 | dprintk("ptrace.%s: failed to read " | ||
719 | "predicate register (ip=0x%lx)\n", | ||
720 | __FUNCTION__, ip); | ||
703 | return; | 721 | return; |
704 | if (ip < FIXADDR_USER_END) | 722 | } |
723 | if (unw_is_intr_frame(&info) | ||
724 | && (pr & (1UL << PRED_USER_STACK))) | ||
705 | break; | 725 | break; |
706 | } | 726 | } |
707 | 727 | ||
@@ -1616,20 +1636,25 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3, | |||
1616 | long arg4, long arg5, long arg6, long arg7, | 1636 | long arg4, long arg5, long arg6, long arg7, |
1617 | struct pt_regs regs) | 1637 | struct pt_regs regs) |
1618 | { | 1638 | { |
1619 | long syscall; | 1639 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
1640 | && (current->ptrace & PT_PTRACED)) | ||
1641 | syscall_trace(); | ||
1620 | 1642 | ||
1621 | if (unlikely(current->audit_context)) { | 1643 | if (unlikely(current->audit_context)) { |
1622 | if (IS_IA32_PROCESS(®s)) | 1644 | long syscall; |
1645 | int arch; | ||
1646 | |||
1647 | if (IS_IA32_PROCESS(®s)) { | ||
1623 | syscall = regs.r1; | 1648 | syscall = regs.r1; |
1624 | else | 1649 | arch = AUDIT_ARCH_I386; |
1650 | } else { | ||
1625 | syscall = regs.r15; | 1651 | syscall = regs.r15; |
1652 | arch = AUDIT_ARCH_IA64; | ||
1653 | } | ||
1626 | 1654 | ||
1627 | audit_syscall_entry(current, syscall, arg0, arg1, arg2, arg3); | 1655 | audit_syscall_entry(current, arch, syscall, arg0, arg1, arg2, arg3); |
1628 | } | 1656 | } |
1629 | 1657 | ||
1630 | if (test_thread_flag(TIF_SYSCALL_TRACE) | ||
1631 | && (current->ptrace & PT_PTRACED)) | ||
1632 | syscall_trace(); | ||
1633 | } | 1658 | } |
1634 | 1659 | ||
1635 | /* "asmlinkage" so the input arguments are preserved... */ | 1660 | /* "asmlinkage" so the input arguments are preserved... */ |
@@ -1640,7 +1665,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3, | |||
1640 | struct pt_regs regs) | 1665 | struct pt_regs regs) |
1641 | { | 1666 | { |
1642 | if (unlikely(current->audit_context)) | 1667 | if (unlikely(current->audit_context)) |
1643 | audit_syscall_exit(current, regs.r8); | 1668 | audit_syscall_exit(current, AUDITSC_RESULT(regs.r10), regs.r8); |
1644 | 1669 | ||
1645 | if (test_thread_flag(TIF_SYSCALL_TRACE) | 1670 | if (test_thread_flag(TIF_SYSCALL_TRACE) |
1646 | && (current->ptrace & PT_PTRACED)) | 1671 | && (current->ptrace & PT_PTRACED)) |