]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/ia64/kernel/ptrace.c
Merge branch 'for-2.6.25' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus...
[linux-2.6-omap-h63xx.git] / arch / ia64 / kernel / ptrace.c
index aa705e46b974d4d47aa4b9066bd2a017ec9b8c1b..2e96f17b2f3b9e2c0b905deddcc02df21c88517d 100644 (file)
@@ -607,7 +607,7 @@ find_thread_for_addr (struct task_struct *child, unsigned long addr)
         */
        list_for_each_safe(this, next, &current->children) {
                p = list_entry(this, struct task_struct, sibling);
-               if (p->mm != mm)
+               if (p->tgid != child->tgid)
                        continue;
                if (thread_matches(p, addr)) {
                        child = p;
@@ -951,10 +951,14 @@ access_uarea (struct task_struct *child, unsigned long addr,
                        return 0;
 
                      case PT_CR_IPSR:
-                       if (write_access)
-                               pt->cr_ipsr = ((*data & IPSR_MASK)
+                       if (write_access) {
+                               unsigned long tmp = *data;
+                               /* psr.ri==3 is a reserved value: SDM 2:25 */
+                               if ((tmp & IA64_PSR_RI) == IA64_PSR_RI)
+                                       tmp &= ~IA64_PSR_RI;
+                               pt->cr_ipsr = ((tmp & IPSR_MASK)
                                               | (pt->cr_ipsr & ~IPSR_MASK));
-                       else
+                       else
                                *data = (pt->cr_ipsr & IPSR_MASK);
                        return 0;
 
@@ -1405,6 +1409,7 @@ ptrace_disable (struct task_struct *child)
        struct ia64_psr *child_psr = ia64_psr(task_pt_regs(child));
 
        /* make sure the single step/taken-branch trap bits are not set: */
+       clear_tsk_thread_flag(child, TIF_SINGLESTEP);
        child_psr->ss = 0;
        child_psr->tb = 0;
 }
@@ -1525,6 +1530,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
                 * Make sure the single step/taken-branch trap bits
                 * are not set:
                 */
+               clear_tsk_thread_flag(child, TIF_SINGLESTEP);
                ia64_psr(pt)->ss = 0;
                ia64_psr(pt)->tb = 0;
 
@@ -1556,6 +1562,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
                        goto out_tsk;
 
                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
+               set_tsk_thread_flag(child, TIF_SINGLESTEP);
                if (request == PTRACE_SINGLESTEP) {
                        ia64_psr(pt)->ss = 1;
                } else {
@@ -1595,13 +1602,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data)
 }
 
 
-void
+static void
 syscall_trace (void)
 {
-       if (!test_thread_flag(TIF_SYSCALL_TRACE))
-               return;
-       if (!(current->ptrace & PT_PTRACED))
-               return;
        /*
         * The 0x80 provides a way for the tracing parent to
         * distinguish between a syscall stop and SIGTRAP delivery.
@@ -1664,7 +1667,8 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
                audit_syscall_exit(success, result);
        }
 
-       if (test_thread_flag(TIF_SYSCALL_TRACE)
+       if ((test_thread_flag(TIF_SYSCALL_TRACE)
+           || test_thread_flag(TIF_SINGLESTEP))
            && (current->ptrace & PT_PTRACED))
                syscall_trace();
 }