Loading arch/sparc/kernel/ptrace_64.c +136 −39 Original line number Diff line number Diff line Loading @@ -258,7 +258,7 @@ static int genregs64_get(struct task_struct *target, ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u64)); if (!ret && count && pos < (32 * sizeof(u64))) { if (!ret && count) { struct reg_window window; if (regwindow64_get(target, regs, &window)) Loading Loading @@ -506,6 +506,57 @@ static const struct user_regset sparc64_regsets[] = { }, }; static int getregs64_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 = task_pt_regs(target); int ret; if (target == current) flushw_user(); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs + 1, 0, 15 * sizeof(u64)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 15 * sizeof(u64), 16 * sizeof(u64)); if (!ret) { /* TSTATE, TPC, TNPC */ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->tstate, 16 * sizeof(u64), 19 * sizeof(u64)); } if (!ret) { unsigned long y = regs->y; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &y, 19 * sizeof(u64), 20 * sizeof(u64)); } return ret; } static const struct user_regset ptrace64_regsets[] = { /* Format is: * G1 --> G7 * O0 --> O7 * 0 * TSTATE, TPC, TNPC, Y */ [REGSET_GENERAL] = { .n = 20, .size = sizeof(u64), .get = getregs64_get, }, }; static const struct user_regset_view ptrace64_view = { .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets) }; static const struct user_regset_view user_sparc64_view = { .name = "sparc64", .e_machine = EM_SPARCV9, .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets) Loading Loading @@ -533,7 +584,7 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 16; count--) *k++ = regs->u_regs[pos++]; if (count && pos < 32) { if (count) { if (get_from_target(target, regs->u_regs[UREG_I6], uregs, sizeof(uregs))) return -EFAULT; Loading @@ -545,7 +596,7 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 16; count--) if (put_user((compat_ulong_t) regs->u_regs[pos++], u++)) return -EFAULT; if (count && pos < 32) { if (count) { if (get_from_target(target, regs->u_regs[UREG_I6], uregs, sizeof(uregs))) return -EFAULT; Loading Loading @@ -840,6 +891,76 @@ static const struct user_regset sparc32_regsets[] = { }, }; static int getregs_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 = task_pt_regs(target); u32 uregs[19]; int i; if (target == current) flushw_user(); uregs[0] = tstate_to_psr(regs->tstate); uregs[1] = regs->tpc; uregs[2] = regs->tnpc; uregs[3] = regs->y; for (i = 1; i < 16; i++) uregs[3 + i] = regs->u_regs[i]; return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, 19 * sizeof(u32)); } static int getfpregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const unsigned long *fpregs = task_thread_info(target)->fpregs; unsigned long fprs; compat_ulong_t fsr; int ret = 0; if (target == current) save_and_clear_fpu(); fprs = task_thread_info(target)->fpsaved[0]; if (fprs & FPRS_FEF) { fsr = task_thread_info(target)->xfsr[0]; } else { fsr = 0; } ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, fpregs, 0, 32 * sizeof(u32)); if (!ret) ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fsr, 32 * sizeof(u32), 33 * sizeof(u32)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 33 * sizeof(u32), 68 * sizeof(u32)); return ret; } static const struct user_regset ptrace32_regsets[] = { [REGSET_GENERAL] = { .n = 19, .size = sizeof(u32), .get = getregs_get, }, [REGSET_FP] = { .n = 68, .size = sizeof(u32), .get = getfpregs_get, }, }; static const struct user_regset_view ptrace32_view = { .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets) }; static const struct user_regset_view user_sparc32_view = { .name = "sparc", .e_machine = EM_SPARC, .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets) Loading Loading @@ -889,15 +1010,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; case PTRACE_GETREGS: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), &pregs->psr); if (!ret) ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u32), 15 * sizeof(u32), &pregs->u_regs[0]); ret = copy_regset_to_user(child, &ptrace32_view, REGSET_GENERAL, 0, 19 * sizeof(u32), pregs); break; case PTRACE_SETREGS: Loading @@ -913,22 +1029,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; case PTRACE_GETFPREGS: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), &fps->regs[0]); if (!ret) ret = copy_regset_to_user(child, view, REGSET_FP, 33 * sizeof(u32), 1 * sizeof(u32), &fps->fsr); if (!ret) { if (__put_user(0, &fps->flags) || __put_user(0, &fps->extra) || __put_user(0, &fps->fpqd) || clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) ret = -EFAULT; } ret = copy_regset_to_user(child, &ptrace32_view, REGSET_FP, 0, 68 * sizeof(u32), fps); break; case PTRACE_SETFPREGS: Loading Loading @@ -999,17 +1103,10 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_GETREGS64: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } ret = copy_regset_to_user(child, &ptrace64_view, REGSET_GENERAL, 0, 19 * sizeof(u64), pregs); break; case PTRACE_SETREGS64: Loading Loading
arch/sparc/kernel/ptrace_64.c +136 −39 Original line number Diff line number Diff line Loading @@ -258,7 +258,7 @@ static int genregs64_get(struct task_struct *target, ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs, 0, 16 * sizeof(u64)); if (!ret && count && pos < (32 * sizeof(u64))) { if (!ret && count) { struct reg_window window; if (regwindow64_get(target, regs, &window)) Loading Loading @@ -506,6 +506,57 @@ static const struct user_regset sparc64_regsets[] = { }, }; static int getregs64_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 = task_pt_regs(target); int ret; if (target == current) flushw_user(); ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs->u_regs + 1, 0, 15 * sizeof(u64)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 15 * sizeof(u64), 16 * sizeof(u64)); if (!ret) { /* TSTATE, TPC, TNPC */ ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->tstate, 16 * sizeof(u64), 19 * sizeof(u64)); } if (!ret) { unsigned long y = regs->y; ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &y, 19 * sizeof(u64), 20 * sizeof(u64)); } return ret; } static const struct user_regset ptrace64_regsets[] = { /* Format is: * G1 --> G7 * O0 --> O7 * 0 * TSTATE, TPC, TNPC, Y */ [REGSET_GENERAL] = { .n = 20, .size = sizeof(u64), .get = getregs64_get, }, }; static const struct user_regset_view ptrace64_view = { .regsets = ptrace64_regsets, .n = ARRAY_SIZE(ptrace64_regsets) }; static const struct user_regset_view user_sparc64_view = { .name = "sparc64", .e_machine = EM_SPARCV9, .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets) Loading Loading @@ -533,7 +584,7 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 16; count--) *k++ = regs->u_regs[pos++]; if (count && pos < 32) { if (count) { if (get_from_target(target, regs->u_regs[UREG_I6], uregs, sizeof(uregs))) return -EFAULT; Loading @@ -545,7 +596,7 @@ static int genregs32_get(struct task_struct *target, for (; count > 0 && pos < 16; count--) if (put_user((compat_ulong_t) regs->u_regs[pos++], u++)) return -EFAULT; if (count && pos < 32) { if (count) { if (get_from_target(target, regs->u_regs[UREG_I6], uregs, sizeof(uregs))) return -EFAULT; Loading Loading @@ -840,6 +891,76 @@ static const struct user_regset sparc32_regsets[] = { }, }; static int getregs_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 = task_pt_regs(target); u32 uregs[19]; int i; if (target == current) flushw_user(); uregs[0] = tstate_to_psr(regs->tstate); uregs[1] = regs->tpc; uregs[2] = regs->tnpc; uregs[3] = regs->y; for (i = 1; i < 16; i++) uregs[3 + i] = regs->u_regs[i]; return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, 19 * sizeof(u32)); } static int getfpregs_get(struct task_struct *target, const struct user_regset *regset, unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf) { const unsigned long *fpregs = task_thread_info(target)->fpregs; unsigned long fprs; compat_ulong_t fsr; int ret = 0; if (target == current) save_and_clear_fpu(); fprs = task_thread_info(target)->fpsaved[0]; if (fprs & FPRS_FEF) { fsr = task_thread_info(target)->xfsr[0]; } else { fsr = 0; } ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, fpregs, 0, 32 * sizeof(u32)); if (!ret) ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &fsr, 32 * sizeof(u32), 33 * sizeof(u32)); if (!ret) ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, 33 * sizeof(u32), 68 * sizeof(u32)); return ret; } static const struct user_regset ptrace32_regsets[] = { [REGSET_GENERAL] = { .n = 19, .size = sizeof(u32), .get = getregs_get, }, [REGSET_FP] = { .n = 68, .size = sizeof(u32), .get = getfpregs_get, }, }; static const struct user_regset_view ptrace32_view = { .regsets = ptrace32_regsets, .n = ARRAY_SIZE(ptrace32_regsets) }; static const struct user_regset_view user_sparc32_view = { .name = "sparc", .e_machine = EM_SPARC, .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets) Loading Loading @@ -889,15 +1010,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; case PTRACE_GETREGS: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u32), 4 * sizeof(u32), &pregs->psr); if (!ret) ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u32), 15 * sizeof(u32), &pregs->u_regs[0]); ret = copy_regset_to_user(child, &ptrace32_view, REGSET_GENERAL, 0, 19 * sizeof(u32), pregs); break; case PTRACE_SETREGS: Loading @@ -913,22 +1029,10 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, break; case PTRACE_GETFPREGS: ret = copy_regset_to_user(child, view, REGSET_FP, 0 * sizeof(u32), 32 * sizeof(u32), &fps->regs[0]); if (!ret) ret = copy_regset_to_user(child, view, REGSET_FP, 33 * sizeof(u32), 1 * sizeof(u32), &fps->fsr); if (!ret) { if (__put_user(0, &fps->flags) || __put_user(0, &fps->extra) || __put_user(0, &fps->fpqd) || clear_user(&fps->fpq[0], 32 * sizeof(unsigned int))) ret = -EFAULT; } ret = copy_regset_to_user(child, &ptrace32_view, REGSET_FP, 0, 68 * sizeof(u32), fps); break; case PTRACE_SETFPREGS: Loading Loading @@ -999,17 +1103,10 @@ long arch_ptrace(struct task_struct *child, long request, break; case PTRACE_GETREGS64: ret = copy_regset_to_user(child, view, REGSET_GENERAL, 1 * sizeof(u64), 15 * sizeof(u64), &pregs->u_regs[0]); if (!ret) { /* XXX doesn't handle 'y' register correctly XXX */ ret = copy_regset_to_user(child, view, REGSET_GENERAL, 32 * sizeof(u64), 4 * sizeof(u64), &pregs->tstate); } ret = copy_regset_to_user(child, &ptrace64_view, REGSET_GENERAL, 0, 19 * sizeof(u64), pregs); break; case PTRACE_SETREGS64: Loading