aboutsummaryrefslogtreecommitdiffstats
path: root/arch/ia64/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/ia64/kernel/ptrace.c')
-rw-r--r--arch/ia64/kernel/ptrace.c47
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(&regs)) 1644 long syscall;
1645 int arch;
1646
1647 if (IS_IA32_PROCESS(&regs)) {
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))