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.c26
1 files changed, 23 insertions, 3 deletions
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 907464ee7273..575a8f657b31 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