Loading arch/sparc/kernel/ptrace_32.c +98 −130 Original line number Diff line number Diff line Loading @@ -46,82 +46,79 @@ enum sparc_regset { REGSET_FP, }; static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) static int regwindow32_get(struct task_struct *target, const struct pt_regs *regs, u32 *uregs) { const struct pt_regs *regs = target->thread.kregs; unsigned long __user *reg_window; unsigned long *k = kbuf; unsigned long __user *u = ubuf; unsigned long reg; if (target == current) flush_user_windows(); pos /= sizeof(reg); count /= sizeof(reg); unsigned long reg_window = regs->u_regs[UREG_I6]; int size = 16 * sizeof(u32); if (kbuf) { for (; count > 0 && pos < 16; count--) *k++ = regs->u_regs[pos++]; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(*k++, ®_window[pos++])) if (target == current) { if (copy_from_user(uregs, (void __user *)reg_window, size)) return -EFAULT; } } else { for (; count > 0 && pos < 16; count--) { if (put_user(regs->u_regs[pos++], u++)) if (access_process_vm(target, reg_window, uregs, size, FOLL_FORCE) != size) return -EFAULT; } return 0; } static int regwindow32_set(struct task_struct *target, const struct pt_regs *regs, u32 *uregs) { unsigned long reg_window = regs->u_regs[UREG_I6]; int size = 16 * sizeof(u32); reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(reg, ®_window[pos++]) || put_user(reg, u++)) if (target == current) { if (copy_to_user((void __user *)reg_window, uregs, size)) return -EFAULT; } else { if (access_process_vm(target, reg_window, uregs, size, FOLL_FORCE | FOLL_WRITE) != size) return -EFAULT; } return 0; } while (count > 0) { switch (pos) { case 32: /* PSR */ reg = regs->psr; break; case 33: /* PC */ reg = regs->pc; break; case 34: /* NPC */ reg = regs->npc; break; case 35: /* Y */ reg = regs->y; break; case 36: /* WIM */ case 37: /* TBR */ reg = 0; break; default: goto finish; } if (kbuf) *k++ = reg; else if (put_user(reg, u++)) static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = target->thread.kregs; u32 uregs[16]; int ret; if (target == current) flush_user_windows(); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u32)); if (ret || !count) return ret; if (pos < 32 * sizeof(u32)) { if (regwindow32_get(target, regs, uregs)) return -EFAULT; pos++; count--; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 16 * sizeof(u32), 32 * sizeof(u32)); if (ret || !count) return ret; } finish: pos *= sizeof(reg); count *= sizeof(reg); return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 38 * sizeof(reg), -1); uregs[0] = regs->psr; uregs[1] = regs->pc; uregs[2] = regs->npc; uregs[3] = regs->y; uregs[4] = 0; /* WIM */ uregs[5] = 0; /* TBR */ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 32 * sizeof(u32), 38 * sizeof(u32)); } static int genregs32_set(struct task_struct *target, Loading @@ -130,82 +127,53 @@ static int genregs32_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { struct pt_regs *regs = target->thread.kregs; unsigned long __user *reg_window; const unsigned long *k = kbuf; const unsigned long __user *u = ubuf; unsigned long reg; u32 uregs[16]; u32 psr; int ret; if (target == current) flush_user_windows(); pos /= sizeof(reg); count /= sizeof(reg); if (kbuf) { for (; count > 0 && pos < 16; count--) regs->u_regs[pos++] = *k++; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (put_user(*k++, ®_window[pos++])) return -EFAULT; } } else { for (; count > 0 && pos < 16; count--) { if (get_user(reg, u++)) return -EFAULT; regs->u_regs[pos++] = reg; } ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u32)); if (ret || !count) return ret; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(reg, u++) || put_user(reg, ®_window[pos++])) if (pos < 32 * sizeof(u32)) { if (regwindow32_get(target, regs, uregs)) return -EFAULT; } } while (count > 0) { unsigned long psr; if (kbuf) reg = *k++; else if (get_user(reg, u++)) ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 16 * sizeof(u32), 32 * sizeof(u32)); if (ret) return ret; if (regwindow32_set(target, regs, uregs)) return -EFAULT; switch (pos) { case 32: /* PSR */ psr = regs->psr; psr &= ~(PSR_ICC | PSR_SYSCALL); psr |= (reg & (PSR_ICC | PSR_SYSCALL)); regs->psr = psr; break; case 33: /* PC */ regs->pc = reg; break; case 34: /* NPC */ regs->npc = reg; break; case 35: /* Y */ regs->y = reg; break; case 36: /* WIM */ case 37: /* TBR */ break; default: goto finish; if (!count) return 0; } pos++; count--; } finish: pos *= sizeof(reg); count *= sizeof(reg); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &psr, 32 * sizeof(u32), 33 * sizeof(u32)); if (ret) return ret; regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) | (psr & (PSR_ICC | PSR_SYSCALL)); if (!count) return 0; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->pc, 33 * sizeof(u32), 34 * sizeof(u32)); if (ret || !count) return ret; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->y, 34 * sizeof(u32), 35 * sizeof(u32)); if (ret || !count) return ret; return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 38 * sizeof(reg), -1); 35 * sizeof(u32), 38 * sizeof(u32)); } static int fpregs32_get(struct task_struct *target, Loading arch/sparc/kernel/ptrace_64.c +3 −14 Original line number Diff line number Diff line Loading @@ -572,19 +572,13 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) ®_window[pos], ®_window[pos++], ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) return -EFAULT; if (access_process_vm(target, (unsigned long) u, ®, sizeof(reg), FOLL_FORCE | FOLL_WRITE) != sizeof(reg)) if (put_user(reg, u++)) return -EFAULT; pos++; u++; } } } Loading Loading @@ -684,12 +678,7 @@ static int genregs32_set(struct task_struct *target, } } else { for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) u, ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) if (get_user(reg, u++)) return -EFAULT; if (access_process_vm(target, (unsigned long) Loading Loading
arch/sparc/kernel/ptrace_32.c +98 −130 Original line number Diff line number Diff line Loading @@ -46,82 +46,79 @@ enum sparc_regset { REGSET_FP, }; static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) static int regwindow32_get(struct task_struct *target, const struct pt_regs *regs, u32 *uregs) { const struct pt_regs *regs = target->thread.kregs; unsigned long __user *reg_window; unsigned long *k = kbuf; unsigned long __user *u = ubuf; unsigned long reg; if (target == current) flush_user_windows(); pos /= sizeof(reg); count /= sizeof(reg); unsigned long reg_window = regs->u_regs[UREG_I6]; int size = 16 * sizeof(u32); if (kbuf) { for (; count > 0 && pos < 16; count--) *k++ = regs->u_regs[pos++]; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(*k++, ®_window[pos++])) if (target == current) { if (copy_from_user(uregs, (void __user *)reg_window, size)) return -EFAULT; } } else { for (; count > 0 && pos < 16; count--) { if (put_user(regs->u_regs[pos++], u++)) if (access_process_vm(target, reg_window, uregs, size, FOLL_FORCE) != size) return -EFAULT; } return 0; } static int regwindow32_set(struct task_struct *target, const struct pt_regs *regs, u32 *uregs) { unsigned long reg_window = regs->u_regs[UREG_I6]; int size = 16 * sizeof(u32); reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(reg, ®_window[pos++]) || put_user(reg, u++)) if (target == current) { if (copy_to_user((void __user *)reg_window, uregs, size)) return -EFAULT; } else { if (access_process_vm(target, reg_window, uregs, size, FOLL_FORCE | FOLL_WRITE) != size) return -EFAULT; } return 0; } while (count > 0) { switch (pos) { case 32: /* PSR */ reg = regs->psr; break; case 33: /* PC */ reg = regs->pc; break; case 34: /* NPC */ reg = regs->npc; break; case 35: /* Y */ reg = regs->y; break; case 36: /* WIM */ case 37: /* TBR */ reg = 0; break; default: goto finish; } if (kbuf) *k++ = reg; else if (put_user(reg, u++)) static int genregs32_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const struct pt_regs *regs = target->thread.kregs; u32 uregs[16]; int ret; if (target == current) flush_user_windows(); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u32)); if (ret || !count) return ret; if (pos < 32 * sizeof(u32)) { if (regwindow32_get(target, regs, uregs)) return -EFAULT; pos++; count--; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 16 * sizeof(u32), 32 * sizeof(u32)); if (ret || !count) return ret; } finish: pos *= sizeof(reg); count *= sizeof(reg); return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 38 * sizeof(reg), -1); uregs[0] = regs->psr; uregs[1] = regs->pc; uregs[2] = regs->npc; uregs[3] = regs->y; uregs[4] = 0; /* WIM */ uregs[5] = 0; /* TBR */ return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 32 * sizeof(u32), 38 * sizeof(u32)); } static int genregs32_set(struct task_struct *target, Loading @@ -130,82 +127,53 @@ static int genregs32_set(struct task_struct *target, const void *kbuf, const void __user *ubuf) { struct pt_regs *regs = target->thread.kregs; unsigned long __user *reg_window; const unsigned long *k = kbuf; const unsigned long __user *u = ubuf; unsigned long reg; u32 uregs[16]; u32 psr; int ret; if (target == current) flush_user_windows(); pos /= sizeof(reg); count /= sizeof(reg); if (kbuf) { for (; count > 0 && pos < 16; count--) regs->u_regs[pos++] = *k++; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (put_user(*k++, ®_window[pos++])) return -EFAULT; } } else { for (; count > 0 && pos < 16; count--) { if (get_user(reg, u++)) return -EFAULT; regs->u_regs[pos++] = reg; } ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u32)); if (ret || !count) return ret; reg_window = (unsigned long __user *) regs->u_regs[UREG_I6]; reg_window -= 16; for (; count > 0 && pos < 32; count--) { if (get_user(reg, u++) || put_user(reg, ®_window[pos++])) if (pos < 32 * sizeof(u32)) { if (regwindow32_get(target, regs, uregs)) return -EFAULT; } } while (count > 0) { unsigned long psr; if (kbuf) reg = *k++; else if (get_user(reg, u++)) ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 16 * sizeof(u32), 32 * sizeof(u32)); if (ret) return ret; if (regwindow32_set(target, regs, uregs)) return -EFAULT; switch (pos) { case 32: /* PSR */ psr = regs->psr; psr &= ~(PSR_ICC | PSR_SYSCALL); psr |= (reg & (PSR_ICC | PSR_SYSCALL)); regs->psr = psr; break; case 33: /* PC */ regs->pc = reg; break; case 34: /* NPC */ regs->npc = reg; break; case 35: /* Y */ regs->y = reg; break; case 36: /* WIM */ case 37: /* TBR */ break; default: goto finish; if (!count) return 0; } pos++; count--; } finish: pos *= sizeof(reg); count *= sizeof(reg); ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &psr, 32 * sizeof(u32), 33 * sizeof(u32)); if (ret) return ret; regs->psr = (regs->psr & ~(PSR_ICC | PSR_SYSCALL)) | (psr & (PSR_ICC | PSR_SYSCALL)); if (!count) return 0; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->pc, 33 * sizeof(u32), 34 * sizeof(u32)); if (ret || !count) return ret; ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, ®s->y, 34 * sizeof(u32), 35 * sizeof(u32)); if (ret || !count) return ret; return user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, 38 * sizeof(reg), -1); 35 * sizeof(u32), 38 * sizeof(u32)); } static int fpregs32_get(struct task_struct *target, Loading
arch/sparc/kernel/ptrace_64.c +3 −14 Original line number Diff line number Diff line Loading @@ -572,19 +572,13 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) ®_window[pos], ®_window[pos++], ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) return -EFAULT; if (access_process_vm(target, (unsigned long) u, ®, sizeof(reg), FOLL_FORCE | FOLL_WRITE) != sizeof(reg)) if (put_user(reg, u++)) return -EFAULT; pos++; u++; } } } Loading Loading @@ -684,12 +678,7 @@ static int genregs32_set(struct task_struct *target, } } else { for (; count > 0 && pos < 32; count--) { if (access_process_vm(target, (unsigned long) u, ®, sizeof(reg), FOLL_FORCE) != sizeof(reg)) if (get_user(reg, u++)) return -EFAULT; if (access_process_vm(target, (unsigned long) Loading