]> err.no Git - linux-2.6/commitdiff
[IA64] Correct convert_to_non_syscall()
authorDavid Mosberger-Tang <davidm@hpl.hp.com>
Tue, 10 May 2005 18:35:00 +0000 (11:35 -0700)
committerTony Luck <tony.luck@intel.com>
Tue, 17 May 2005 19:33:15 +0000 (12:33 -0700)
convert_to_non_syscall() has the same problem that unwind_to_user()
used to have.  Fix it likewise.

Signed-off-by: David Mosberger-Tang <davidm@hpl.hp.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
arch/ia64/kernel/ptrace.c

index 907464ee7273221468afa4c59cc811042ed2fd11..08c8a5eb25abc307c49bbc01ac34d6ad6e8e7bdb 100644 (file)
@@ -692,16 +692,30 @@ convert_to_non_syscall (struct task_struct *child, struct pt_regs  *pt,
                        unsigned long cfm)
 {
        struct unw_frame_info info, prev_info;
-       unsigned long ip, pr;
+       unsigned long ip, sp, pr;
 
        unw_init_from_blocked_task(&info, child);
        while (1) {
                prev_info = info;
                if (unw_unwind(&info) < 0)
                        return;
-               if (unw_get_rp(&info, &ip) < 0)
+
+               unw_get_sp(&info, &sp);
+               if ((long)((unsigned long)child + IA64_STK_OFFSET - sp)
+                   < IA64_PT_REGS_SIZE) {
+                       dprintk("ptrace.%s: ran off the top of the kernel "
+                               "stack\n", __FUNCTION__);
+                       return;
+               }
+               if (unw_get_pr (&prev_info, &pr) < 0) {
+                       unw_get_rp(&prev_info, &ip);
+                       dprintk("ptrace.%s: failed to read "
+                               "predicate register (ip=0x%lx)\n",
+                               __FUNCTION__, ip);
                        return;
-               if (ip < FIXADDR_USER_END)
+               }
+               if (unw_is_intr_frame(&info)
+                   && (pr & (1UL << PRED_USER_STACK)))
                        break;
        }