diff options
41 files changed, 1370 insertions, 2349 deletions
diff --git a/arch/arc/kernel/ptrace.c b/arch/arc/kernel/ptrace.c index f49a054a1016..883391977fdf 100644 --- a/arch/arc/kernel/ptrace.c +++ b/arch/arc/kernel/ptrace.c @@ -18,88 +18,61 @@ static struct callee_regs *task_callee_regs(struct task_struct *tsk) static int genregs_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { const struct pt_regs *ptregs = task_pt_regs(target); const struct callee_regs *cregs = task_callee_regs(target); - int ret = 0; unsigned int stop_pc_val; -#define REG_O_CHUNK(START, END, PTR) \ - if (!ret) \ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \ - offsetof(struct user_regs_struct, START), \ - offsetof(struct user_regs_struct, END)); - -#define REG_O_ONE(LOC, PTR) \ - if (!ret) \ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, PTR, \ - offsetof(struct user_regs_struct, LOC), \ - offsetof(struct user_regs_struct, LOC) + 4); - -#define REG_O_ZERO(LOC) \ - if (!ret) \ - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, \ - offsetof(struct user_regs_struct, LOC), \ - offsetof(struct user_regs_struct, LOC) + 4); - - REG_O_ZERO(pad); - REG_O_ONE(scratch.bta, &ptregs->bta); - REG_O_ONE(scratch.lp_start, &ptregs->lp_start); - REG_O_ONE(scratch.lp_end, &ptregs->lp_end); - REG_O_ONE(scratch.lp_count, &ptregs->lp_count); - REG_O_ONE(scratch.status32, &ptregs->status32); - REG_O_ONE(scratch.ret, &ptregs->ret); - REG_O_ONE(scratch.blink, &ptregs->blink); - REG_O_ONE(scratch.fp, &ptregs->fp); - REG_O_ONE(scratch.gp, &ptregs->r26); - REG_O_ONE(scratch.r12, &ptregs->r12); - REG_O_ONE(scratch.r11, &ptregs->r11); - REG_O_ONE(scratch.r10, &ptregs->r10); - REG_O_ONE(scratch.r9, &ptregs->r9); - REG_O_ONE(scratch.r8, &ptregs->r8); - REG_O_ONE(scratch.r7, &ptregs->r7); - REG_O_ONE(scratch.r6, &ptregs->r6); - REG_O_ONE(scratch.r5, &ptregs->r5); - REG_O_ONE(scratch.r4, &ptregs->r4); - REG_O_ONE(scratch.r3, &ptregs->r3); - REG_O_ONE(scratch.r2, &ptregs->r2); - REG_O_ONE(scratch.r1, &ptregs->r1); - REG_O_ONE(scratch.r0, &ptregs->r0); - REG_O_ONE(scratch.sp, &ptregs->sp); - - REG_O_ZERO(pad2); - - REG_O_ONE(callee.r25, &cregs->r25); - REG_O_ONE(callee.r24, &cregs->r24); - REG_O_ONE(callee.r23, &cregs->r23); - REG_O_ONE(callee.r22, &cregs->r22); - REG_O_ONE(callee.r21, &cregs->r21); - REG_O_ONE(callee.r20, &cregs->r20); - REG_O_ONE(callee.r19, &cregs->r19); - REG_O_ONE(callee.r18, &cregs->r18); - REG_O_ONE(callee.r17, &cregs->r17); - REG_O_ONE(callee.r16, &cregs->r16); - REG_O_ONE(callee.r15, &cregs->r15); - REG_O_ONE(callee.r14, &cregs->r14); - REG_O_ONE(callee.r13, &cregs->r13); - - REG_O_ONE(efa, &target->thread.fault_address); - - if (!ret) { - if (in_brkpt_trap(ptregs)) { - stop_pc_val = target->thread.fault_address; - pr_debug("\t\tstop_pc (brk-pt)\n"); - } else { - stop_pc_val = ptregs->ret; - pr_debug("\t\tstop_pc (others)\n"); - } - - REG_O_ONE(stop_pc, &stop_pc_val); + membuf_zero(&to, 4); // pad + membuf_store(&to, ptregs->bta); + membuf_store(&to, ptregs->lp_start); + membuf_store(&to, ptregs->lp_end); + membuf_store(&to, ptregs->lp_count); + membuf_store(&to, ptregs->status32); + membuf_store(&to, ptregs->ret); + membuf_store(&to, ptregs->blink); + membuf_store(&to, ptregs->fp); + membuf_store(&to, ptregs->r26); // gp + membuf_store(&to, ptregs->r12); + membuf_store(&to, ptregs->r11); + membuf_store(&to, ptregs->r10); + membuf_store(&to, ptregs->r9); + membuf_store(&to, ptregs->r8); + membuf_store(&to, ptregs->r7); + membuf_store(&to, ptregs->r6); + membuf_store(&to, ptregs->r5); + membuf_store(&to, ptregs->r4); + membuf_store(&to, ptregs->r3); + membuf_store(&to, ptregs->r2); + membuf_store(&to, ptregs->r1); + membuf_store(&to, ptregs->r0); + membuf_store(&to, ptregs->sp); + membuf_zero(&to, 4); // pad2 + membuf_store(&to, cregs->r25); + membuf_store(&to, cregs->r24); + membuf_store(&to, cregs->r23); + membuf_store(&to, cregs->r22); + membuf_store(&to, cregs->r21); + membuf_store(&to, cregs->r20); + membuf_store(&to, cregs->r19); + membuf_store(&to, cregs->r18); + membuf_store(&to, cregs->r17); + membuf_store(&to, cregs->r16); + membuf_store(&to, cregs->r15); + membuf_store(&to, cregs->r14); + membuf_store(&to, cregs->r13); + membuf_store(&to, target->thread.fault_address); // efa + + if (in_brkpt_trap(ptregs)) { + stop_pc_val = target->thread.fault_address; + pr_debug("\t\tstop_pc (brk-pt)\n"); + } else { + stop_pc_val = ptregs->ret; + pr_debug("\t\tstop_pc (others)\n"); } - return ret; + return membuf_store(&to, stop_pc_val); // stop_pc } static int genregs_set(struct task_struct *target, @@ -184,25 +157,20 @@ static int genregs_set(struct task_struct *target, #ifdef CONFIG_ISA_ARCV2 static int arcv2regs_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { const struct pt_regs *regs = task_pt_regs(target); - int ret, copy_sz; if (IS_ENABLED(CONFIG_ARC_HAS_ACCL_REGS)) - copy_sz = sizeof(struct user_regs_arcv2); - else - copy_sz = 4; /* r30 only */ + /* + * itemized copy not needed like above as layout of regs (r30,r58,r59) + * is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2) + */ + return membuf_write(&to, ®s->r30, sizeof(struct user_regs_arcv2)); - /* - * itemized copy not needed like above as layout of regs (r30,r58,r59) - * is exactly same in kernel (pt_regs) and userspace (user_regs_arcv2) - */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, ®s->r30, - 0, copy_sz); - return ret; + membuf_write(&to, ®s->r30, 4); /* r30 only */ + return membuf_zero(&to, sizeof(struct user_regs_arcv2) - 4); } static int arcv2regs_set(struct task_struct *target, @@ -237,7 +205,7 @@ static const struct user_regset arc_regsets[] = { .n = ELF_NGREG, .size = sizeof(unsigned long), .align = sizeof(unsigned long), - .get = genregs_get, + .regset_get = genregs_get, .set = genregs_set, }, #ifdef CONFIG_ISA_ARCV2 @@ -246,7 +214,7 @@ static const struct user_regset arc_regsets[] = { .n = ELF_ARCV2REG, .size = sizeof(unsigned long), .align = sizeof(unsigned long), - .get = arcv2regs_get, + .regset_get = arcv2regs_get, .set = arcv2regs_set, }, #endif diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index d0f7c8896c96..2771e682220b 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -569,14 +569,9 @@ out: static int gpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - struct pt_regs *regs = task_pt_regs(target); - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - regs, - 0, sizeof(*regs)); + return membuf_write(&to, task_pt_regs(target), sizeof(struct pt_regs)); } static int gpr_set(struct task_struct *target, @@ -602,12 +597,10 @@ static int gpr_set(struct task_struct *target, static int fpa_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &task_thread_info(target)->fpstate, - 0, sizeof(struct user_fp)); + return membuf_write(&to, &task_thread_info(target)->fpstate, + sizeof(struct user_fp)); } static int fpa_set(struct task_struct *target, @@ -642,41 +635,20 @@ static int fpa_set(struct task_struct *target, * vfp_set() ignores this chunk * * 1 word for the FPSCR - * - * The bounds-checking logic built into user_regset_copyout and friends - * means that we can make a simple sequence of calls to map the relevant data - * to/from the specified slice of the user regset structure. */ static int vfp_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; struct thread_info *thread = task_thread_info(target); struct vfp_hard_struct const *vfp = &thread->vfpstate.hard; - const size_t user_fpregs_offset = offsetof(struct user_vfp, fpregs); const size_t user_fpscr_offset = offsetof(struct user_vfp, fpscr); vfp_sync_hwstate(thread); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &vfp->fpregs, - user_fpregs_offset, - user_fpregs_offset + sizeof(vfp->fpregs)); - if (ret) - return ret; - - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - user_fpregs_offset + sizeof(vfp->fpregs), - user_fpscr_offset); - if (ret) - return ret; - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &vfp->fpscr, - user_fpscr_offset, - user_fpscr_offset + sizeof(vfp->fpscr)); + membuf_write(&to, vfp->fpregs, sizeof(vfp->fpregs)); + membuf_zero(&to, user_fpscr_offset - sizeof(vfp->fpregs)); + return membuf_store(&to, vfp->fpscr); } /* @@ -739,7 +711,7 @@ static const struct user_regset arm_regsets[] = { .n = ELF_NGREG, .size = sizeof(u32), .align = sizeof(u32), - .get = gpr_get, + .regset_get = gpr_get, .set = gpr_set }, [REGSET_FPR] = { @@ -751,7 +723,7 @@ static const struct user_regset arm_regsets[] = { .n = sizeof(struct user_fp) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = fpa_get, + .regset_get = fpa_get, .set = fpa_set }, #ifdef CONFIG_VFP @@ -764,7 +736,7 @@ static const struct user_regset arm_regsets[] = { .n = ARM_VFPREGS_SIZE / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = vfp_get, + .regset_get = vfp_get, .set = vfp_set }, #endif /* CONFIG_VFP */ diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 1e02e98e68dd..d8ebfd813e28 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -474,11 +474,10 @@ static int ptrace_hbp_set_addr(unsigned int note_type, static int hw_break_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { unsigned int note_type = regset->core_note_type; - int ret, idx = 0, offset, limit; + int ret, idx = 0; u32 info, ctrl; u64 addr; @@ -487,49 +486,21 @@ static int hw_break_get(struct task_struct *target, if (ret) return ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &info, 0, - sizeof(info)); - if (ret) - return ret; - - /* Pad */ - offset = offsetof(struct user_hwdebug_state, pad); - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, offset, - offset + PTRACE_HBP_PAD_SZ); - if (ret) - return ret; - + membuf_write(&to, &info, sizeof(info)); + membuf_zero(&to, sizeof(u32)); /* (address, ctrl) registers */ - offset = offsetof(struct user_hwdebug_state, dbg_regs); - limit = regset->n * regset->size; - while (count && offset < limit) { + while (to.left) { ret = ptrace_hbp_get_addr(note_type, target, idx, &addr); if (ret) return ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &addr, - offset, offset + PTRACE_HBP_ADDR_SZ); - if (ret) - return ret; - offset += PTRACE_HBP_ADDR_SZ; - ret = ptrace_hbp_get_ctrl(note_type, target, idx, &ctrl); if (ret) return ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &ctrl, - offset, offset + PTRACE_HBP_CTRL_SZ); - if (ret) - return ret; - offset += PTRACE_HBP_CTRL_SZ; - - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - offset, - offset + PTRACE_HBP_PAD_SZ); - if (ret) - return ret; - offset += PTRACE_HBP_PAD_SZ; + membuf_store(&to, addr); + membuf_store(&to, ctrl); + membuf_zero(&to, sizeof(u32)); idx++; } - return 0; } @@ -589,11 +560,10 @@ static int hw_break_set(struct task_struct *target, static int gpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { struct user_pt_regs *uregs = &task_pt_regs(target)->user_regs; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, -1); + return membuf_write(&to, uregs, sizeof(*uregs)); } static int gpr_set(struct task_struct *target, const struct user_regset *regset, @@ -626,8 +596,7 @@ static int fpr_active(struct task_struct *target, const struct user_regset *regs */ static int __fpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf, unsigned int start_pos) + struct membuf to) { struct user_fpsimd_state *uregs; @@ -635,13 +604,11 @@ static int __fpr_get(struct task_struct *target, uregs = &target->thread.uw.fpsimd_state; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, - start_pos, start_pos + sizeof(*uregs)); + return membuf_write(&to, uregs, sizeof(*uregs)); } static int fpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { if (!system_supports_fpsimd()) return -EINVAL; @@ -649,7 +616,7 @@ static int fpr_get(struct task_struct *target, const struct user_regset *regset, if (target == current) fpsimd_preserve_current_state(); - return __fpr_get(target, regset, pos, count, kbuf, ubuf, 0); + return __fpr_get(target, regset, to); } static int __fpr_set(struct task_struct *target, @@ -699,15 +666,12 @@ static int fpr_set(struct task_struct *target, const struct user_regset *regset, } static int tls_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - unsigned long *tls = &target->thread.uw.tp_value; - if (target == current) tls_preserve_current_state(); - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, tls, 0, -1); + return membuf_store(&to, target->thread.uw.tp_value); } static int tls_set(struct task_struct *target, const struct user_regset *regset, @@ -727,13 +691,9 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset, static int system_call_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - int syscallno = task_pt_regs(target)->syscallno; - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &syscallno, 0, -1); + return membuf_store(&to, task_pt_regs(target)->syscallno); } static int system_call_set(struct task_struct *target, @@ -780,24 +740,10 @@ static unsigned int sve_size_from_header(struct user_sve_header const *header) return ALIGN(header->size, SVE_VQ_BYTES); } -static unsigned int sve_get_size(struct task_struct *target, - const struct user_regset *regset) -{ - struct user_sve_header header; - - if (!system_supports_sve()) - return 0; - - sve_init_header_from_task(&header, target); - return sve_size_from_header(&header); -} - static int sve_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { - int ret; struct user_sve_header header; unsigned int vq; unsigned long start, end; @@ -809,10 +755,7 @@ static int sve_get(struct task_struct *target, sve_init_header_from_task(&header, target); vq = sve_vq_from_vl(header.vl); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &header, - 0, sizeof(header)); - if (ret) - return ret; + membuf_write(&to, &header, sizeof(header)); if (target == current) fpsimd_preserve_current_state(); @@ -821,26 +764,18 @@ static int sve_get(struct task_struct *target, BUILD_BUG_ON(SVE_PT_FPSIMD_OFFSET != sizeof(header)); if ((header.flags & SVE_PT_REGS_MASK) == SVE_PT_REGS_FPSIMD) - return __fpr_get(target, regset, pos, count, kbuf, ubuf, - SVE_PT_FPSIMD_OFFSET); + return __fpr_get(target, regset, to); /* Otherwise: full SVE case */ BUILD_BUG_ON(SVE_PT_SVE_OFFSET != sizeof(header)); start = SVE_PT_SVE_OFFSET; end = SVE_PT_SVE_FFR_OFFSET(vq) + SVE_PT_SVE_FFR_SIZE(vq); - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - target->thread.sve_state, - start, end); - if (ret) - return ret; + membuf_write(&to, target->thread.sve_state, end - start); start = end; end = SVE_PT_SVE_FPSR_OFFSET(vq); - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - start, end); - if (ret) - return ret; + membuf_zero(&to, end - start); /* * Copy fpsr, and fpcr which must follow contiguously in @@ -848,16 +783,11 @@ static int sve_get(struct task_struct *target, */ start = end; end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.uw.fpsimd_state.fpsr, - start, end); - if (ret) - return ret; + membuf_write(&to, &target->thread.uw.fpsimd_state.fpsr, end - start); start = end; end = sve_size_from_header(&header); - return user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - start, end); + return membuf_zero(&to, end - start); } static int sve_set(struct task_struct *target, @@ -961,8 +891,7 @@ out: #ifdef CONFIG_ARM64_PTR_AUTH static int pac_mask_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { /* * The PAC bits can differ across data and instruction pointers @@ -978,7 +907,7 @@ static int pac_mask_get(struct task_struct *target, if (!system_supports_address_auth()) return -EINVAL; - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &uregs, 0, -1); + return membuf_write(&to, &uregs, sizeof(uregs)); } #ifdef CONFIG_CHECKPOINT_RESTORE @@ -1017,8 +946,7 @@ static void pac_address_keys_from_user(struct ptrauth_keys_user *keys, static int pac_address_keys_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { struct ptrauth_keys_user *keys = &target->thread.keys_user; struct user_pac_address_keys user_keys; @@ -1028,8 +956,7 @@ static int pac_address_keys_get(struct task_struct *target, pac_address_keys_to_user(&user_keys, keys); - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &user_keys, 0, -1); + return membuf_write(&to, &user_keys, sizeof(user_keys)); } static int pac_address_keys_set(struct task_struct *target, @@ -1068,8 +995,7 @@ static void pac_generic_keys_from_user(struct ptrauth_keys_user *keys, static int pac_generic_keys_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { struct ptrauth_keys_user *keys = &target->thread.keys_user; struct user_pac_generic_keys user_keys; @@ -1079,8 +1005,7 @@ static int pac_generic_keys_get(struct task_struct *target, pac_generic_keys_to_user(&user_keys, keys); - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &user_keys, 0, -1); + return membuf_write(&to, &user_keys, sizeof(user_keys)); } static int pac_generic_keys_set(struct task_struct *target, @@ -1134,7 +1059,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_pt_regs) / sizeof(u64), .size = sizeof(u64), .align = sizeof(u64), - .get = gpr_get, + .regset_get = gpr_get, .set = gpr_set }, [REGSET_FPR] = { @@ -1147,7 +1072,7 @@ static const struct user_regset aarch64_regsets[] = { .size = sizeof(u32), .align = sizeof(u32), .active = fpr_active, - .get = fpr_get, + .regset_get = fpr_get, .set = fpr_set }, [REGSET_TLS] = { @@ -1155,7 +1080,7 @@ static const struct user_regset aarch64_regsets[] = { .n = 1, .size = sizeof(void *), .align = sizeof(void *), - .get = tls_get, + .regset_get = tls_get, .set = tls_set, }, #ifdef CONFIG_HAVE_HW_BREAKPOINT @@ -1164,7 +1089,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_hwdebug_state) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = hw_break_get, + .regset_get = hw_break_get, .set = hw_break_set, }, [REGSET_HW_WATCH] = { @@ -1172,7 +1097,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_hwdebug_state) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = hw_break_get, + .regset_get = hw_break_get, .set = hw_break_set, }, #endif @@ -1181,7 +1106,7 @@ static const struct user_regset aarch64_regsets[] = { .n = 1, .size = sizeof(int), .align = sizeof(int), - .get = system_call_get, + .regset_get = system_call_get, .set = system_call_set, }, #ifdef CONFIG_ARM64_SVE @@ -1191,9 +1116,8 @@ static const struct user_regset aarch64_regsets[] = { SVE_VQ_BYTES), .size = SVE_VQ_BYTES, .align = SVE_VQ_BYTES, - .get = sve_get, + .regset_get = sve_get, .set = sve_set, - .get_size = sve_get_size, }, #endif #ifdef CONFIG_ARM64_PTR_AUTH @@ -1202,7 +1126,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_pac_mask) / sizeof(u64), .size = sizeof(u64), .align = sizeof(u64), - .get = pac_mask_get, + .regset_get = pac_mask_get, /* this cannot be set dynamically */ }, #ifdef CONFIG_CHECKPOINT_RESTORE @@ -1211,7 +1135,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_pac_address_keys) / sizeof(__uint128_t), .size = sizeof(__uint128_t), .align = sizeof(__uint128_t), - .get = pac_address_keys_get, + .regset_get = pac_address_keys_get, .set = pac_address_keys_set, }, [REGSET_PACG_KEYS] = { @@ -1219,7 +1143,7 @@ static const struct user_regset aarch64_regsets[] = { .n = sizeof(struct user_pac_generic_keys) / sizeof(__uint128_t), .size = sizeof(__uint128_t), .align = sizeof(__uint128_t), - .get = pac_generic_keys_get, + .regset_get = pac_generic_keys_get, .set = pac_generic_keys_set, }, #endif @@ -1237,57 +1161,31 @@ enum compat_regset { REGSET_COMPAT_VFP, }; -static int compat_gpr_get(struct task_struct *target, - const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) +static inline compat_ulong_t compat_get_user_reg(struct task_struct *task, int idx) { - int ret = 0; - unsigned int i, start, num_regs; + struct pt_regs *regs = task_pt_regs(task); - /* Calculate the number of AArch32 registers contained in count */ - num_regs = count / regset->size; - - /* Convert pos into an register number */ - start = pos / regset->size; - - if (start + num_regs > regset->n) - return -EIO; - - for (i = 0; i < num_regs; ++i) { - unsigned int idx = start + i; - compat_ulong_t reg; - - switch (idx) { - case 15: - reg = task_pt_regs(target)->pc; - break; - case 16: - reg = task_pt_regs(target)->pstate; - reg = pstate_to_compat_psr(reg); - break; - case 17: - reg = task_pt_regs(target)->orig_x0; - break; - default: - reg = task_pt_regs(target)->regs[idx]; - } - - if (kbuf) { - memcpy(kbuf, ®, sizeof(reg)); - kbuf += sizeof(reg); - } else { - ret = copy_to_user(ubuf, ®, sizeof(reg)); - if (ret) { - ret = -EFAULT; - break; - } - - ubuf += sizeof(reg); - } + switch (idx) { + case 15: + return regs->pc; + case 16: + return pstate_to_compat_p |