]> err.no Git - linux-2.6/blobdiff - arch/xtensa/kernel/ptrace.c
[POWERPC] fsl_elbc_nand: factor out localbus defines
[linux-2.6] / arch / xtensa / kernel / ptrace.c
index f6669d605125a6d6d824b07308dbf6fc48675a92..9486882ef0afa8318fca682d24ff3c382c18997b 100644 (file)
@@ -43,32 +43,29 @@ int ptrace_getregs(struct task_struct *child, void __user *uregs)
 {
        struct pt_regs *regs = task_pt_regs(child);
        xtensa_gregset_t __user *gregset = uregs;
-       unsigned long wb = regs->windowbase;
-       unsigned long ws = regs->windowstart;
        unsigned long wm = regs->wmask;
-       int ret = 0;
-       int live, last;
+       unsigned long wb = regs->windowbase;
+       int live, i;
 
        if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
                return -EIO;
 
-       /* Norm windowstart to a windowbase of 0. */
-
-       ws = ((ws>>wb) | (ws<<(WSBITS-wb))) & ((1<<WSBITS)-1);
-
-       ret |= __put_user(regs->pc, &gregset->pc);
-       ret |= __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
-       ret |= __put_user(regs->lbeg, &gregset->lbeg);
-       ret |= __put_user(regs->lend, &gregset->lend);
-       ret |= __put_user(regs->lcount, &gregset->lcount);
-       ret |= __put_user(ws, &gregset->windowstart);
+       __put_user(regs->pc, &gregset->pc);
+       __put_user(regs->ps & ~(1 << PS_EXCM_BIT), &gregset->ps);
+       __put_user(regs->lbeg, &gregset->lbeg);
+       __put_user(regs->lend, &gregset->lend);
+       __put_user(regs->lcount, &gregset->lcount);
+       __put_user(regs->windowstart, &gregset->windowstart);
+       __put_user(regs->windowbase, &gregset->windowbase);
 
        live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
-       last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
-       ret |= __copy_to_user(gregset->a, regs->areg, live * 4);
-       ret |= __copy_to_user(gregset->a + last, regs->areg + last, (wm>>4)*16);
 
-       return ret ? -EFAULT : 0;
+       for (i = 0; i < live; i++)
+               __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
+       for (i = XCHAL_NUM_AREGS - (wm >> 4) * 4; i < XCHAL_NUM_AREGS; i++)
+               __put_user(regs->areg[i],gregset->a+((wb*4+i)%XCHAL_NUM_AREGS));
+
+       return 0;
 }
 
 int ptrace_setregs(struct task_struct *child, void __user *uregs)
@@ -76,28 +73,35 @@ int ptrace_setregs(struct task_struct *child, void __user *uregs)
        struct pt_regs *regs = task_pt_regs(child);
        xtensa_gregset_t *gregset = uregs;
        const unsigned long ps_mask = PS_CALLINC_MASK | PS_OWB_MASK;
-       unsigned long wm = regs->wmask;
        unsigned long ps;
-       int ret = 0;
-       int live, last;
+       unsigned long wb;
 
        if (!access_ok(VERIFY_WRITE, uregs, sizeof(xtensa_gregset_t)))
                return -EIO;
 
-       ret |= __get_user(regs->pc, &gregset->pc);
-       ret |= __get_user(ps, &gregset->ps);
-       ret |= __get_user(regs->lbeg, &gregset->lbeg);
-       ret |= __get_user(regs->lend, &gregset->lend);
-       ret |= __get_user(regs->lcount, &gregset->lcount);
+       __get_user(regs->pc, &gregset->pc);
+       __get_user(ps, &gregset->ps);
+       __get_user(regs->lbeg, &gregset->lbeg);
+       __get_user(regs->lend, &gregset->lend);
+       __get_user(regs->lcount, &gregset->lcount);
+       __get_user(regs->windowstart, &gregset->windowstart);
+       __get_user(wb, &gregset->windowbase);
 
        regs->ps = (regs->ps & ~ps_mask) | (ps & ps_mask) | (1 << PS_EXCM_BIT);
 
-       live = (wm & 2) ? 4 : (wm & 4) ? 8 : (wm & 8) ? 12 : 16;
-       last = XCHAL_NUM_AREGS - (wm >> 4) * 4;
-       ret |= __copy_from_user(regs->areg, gregset->a, live * 4);
-       ret |= __copy_from_user(regs->areg+last, gregset->a+last, (wm>>4)*16);
+       if (wb >= XCHAL_NUM_AREGS / 4)
+               return -EFAULT;
 
-       return ret ? -EFAULT : 0;
+       regs->windowbase = wb;
+
+       if (wb != 0 &&  __copy_from_user(regs->areg + XCHAL_NUM_AREGS - wb * 4,
+                                        gregset->a, wb * 16))
+               return -EFAULT;
+
+       if (__copy_from_user(regs->areg, gregset->a + wb*4, (WSBITS-wb) * 16))
+               return -EFAULT;
+
+       return 0;
 }