Pull pnpacpi into release branch
[sfrench/cifs-2.6.git] / arch / mips / kernel / ptrace32.c
index 9a9b049721327cb28fca14dffd8b6bf5f5d47ec1..8704dc0496ea7f2427b4fd111dbbb54397955b0f 100644 (file)
@@ -57,30 +57,16 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
               (unsigned long) data);
 #endif
        lock_kernel();
-       ret = -EPERM;
        if (request == PTRACE_TRACEME) {
-               /* are we already being traced? */
-               if (current->ptrace & PT_PTRACED)
-                       goto out;
-               if ((ret = security_ptrace(current->parent, current)))
-                       goto out;
-               /* set the ptrace bit in the process flags. */
-               current->ptrace |= PT_PTRACED;
-               ret = 0;
+               ret = ptrace_traceme();
                goto out;
        }
-       ret = -ESRCH;
-       read_lock(&tasklist_lock);
-       child = find_task_by_pid(pid);
-       if (child)
-               get_task_struct(child);
-       read_unlock(&tasklist_lock);
-       if (!child)
-               goto out;
 
-       ret = -EPERM;
-       if (pid == 1)           /* you may not mess with init */
-               goto out_tsk;
+       child = ptrace_get_task_struct(pid);
+       if (IS_ERR(child)) {
+               ret = PTR_ERR(child);
+               goto out;
+       }
 
        if (request == PTRACE_ATTACH) {
                ret = ptrace_attach(child);
@@ -102,7 +88,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                ret = -EIO;
                if (copied != sizeof(tmp))
                        break;
-               ret = put_user(tmp, (unsigned int *) (unsigned long) data);
+               ret = put_user(tmp, (unsigned int __user *) (unsigned long) data);
                break;
        }
 
@@ -140,8 +126,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                struct pt_regs *regs;
                unsigned int tmp;
 
-               regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-                      THREAD_SIZE - 32 - sizeof(struct pt_regs));
+               regs = task_pt_regs(child);
                ret = 0;  /* Default return value. */
 
                switch (addr) {
@@ -188,9 +173,21 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        break;
                case FPC_EIR: { /* implementation / version register */
                        unsigned int flags;
+#ifdef CONFIG_MIPS_MT_SMTC
+                       unsigned int irqflags;
+                       unsigned int mtflags;
+#endif /* CONFIG_MIPS_MT_SMTC */
 
-                       if (!cpu_has_fpu)
+                       if (!cpu_has_fpu) {
+                               tmp = 0;
                                break;
+                       }
+
+#ifdef CONFIG_MIPS_MT_SMTC
+                       /* Read-modify-write of Status must be atomic */
+                       local_irq_save(irqflags);
+                       mtflags = dmt();
+#endif /* CONFIG_MIPS_MT_SMTC */
 
                        preempt_disable();
                        if (cpu_has_mipsmt) {
@@ -206,22 +203,25 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                                __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp));
                                write_c0_status(flags);
                        }
+#ifdef CONFIG_MIPS_MT_SMTC
+                       emt(mtflags);
+                       local_irq_restore(irqflags);
+#endif /* CONFIG_MIPS_MT_SMTC */
                        preempt_enable();
                        break;
                }
-               case DSP_BASE ... DSP_BASE + 5:
+               case DSP_BASE ... DSP_BASE + 5: {
+                       dspreg_t *dregs;
+
                        if (!cpu_has_dsp) {
                                tmp = 0;
                                ret = -EIO;
                                goto out_tsk;
                        }
-                       if (child->thread.dsp.used_dsp) {
-                               dspreg_t *dregs = __get_dsp_regs(child);
-                               tmp = (unsigned long) (dregs[addr - DSP_BASE]);
-                       } else {
-                               tmp = -1;       /* DSP registers yet used  */
-                       }
+                       dregs = __get_dsp_regs(child);
+                       tmp = (unsigned long) (dregs[addr - DSP_BASE]);
                        break;
+               }
                case DSP_CONTROL:
                        if (!cpu_has_dsp) {
                                tmp = 0;
@@ -235,7 +235,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        ret = -EIO;
                        goto out_tsk;
                }
-               ret = put_user(tmp, (unsigned *) (unsigned long) data);
+               ret = put_user(tmp, (unsigned __user *) (unsigned long) data);
                break;
        }
 
@@ -277,8 +277,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
        case PTRACE_POKEUSR: {
                struct pt_regs *regs;
                ret = 0;
-               regs = (struct pt_regs *) ((unsigned long) child->thread_info +
-                      THREAD_SIZE - 32 - sizeof(struct pt_regs));
+               regs = task_pt_regs(child);
 
                switch (addr) {
                case 0 ... 31:
@@ -324,15 +323,18 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                        else
                                child->thread.fpu.soft.fcr31 = data;
                        break;
-               case DSP_BASE ... DSP_BASE + 5:
+               case DSP_BASE ... DSP_BASE + 5: {
+                       dspreg_t *dregs;
+
                        if (!cpu_has_dsp) {
                                ret = -EIO;
                                break;
                        }
 
-                       dspreg_t *dregs = __get_dsp_regs(child);
+                       dregs = __get_dsp_regs(child);
                        dregs[addr - DSP_BASE] = data;
                        break;
+               }
                case DSP_CONTROL:
                        if (!cpu_has_dsp) {
                                ret = -EIO;
@@ -395,7 +397,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                break;
 
        case PTRACE_GET_THREAD_AREA:
-               ret = put_user(child->thread_info->tp_value,
+               ret = put_user(task_thread_info(child)->tp_value,
                                (unsigned int __user *) (unsigned long) data);
                break;
 
@@ -409,7 +411,7 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data)
                break;
 
        case PTRACE_GET_THREAD_AREA_3264:
-               ret = put_user(child->thread_info->tp_value,
+               ret = put_user(task_thread_info(child)->tp_value,
                                (unsigned long __user *) (unsigned long) data);
                break;