Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

riscv: signal: abstract header saving for setup_sigcontext

The function save_v_state() served two purposes. First, it saved
extension context into the signal stack. Then, it constructed the
extension header if there was no fault. The second part is independent
of the extension itself. As a result, we can pull that part out, so
future extensions may reuse it. This patch adds arch_ext_list and makes
setup_sigcontext() go through all possible extensions' save() callback.
The callback returns a positive value indicating the size of the
successfully saved extension. Then the kernel proceeds to construct the
header for that extension. The kernel skips an extension if it does
not exist, or if the saving fails for some reasons. The error code is
propagated out on the later case.

This patch does not introduce any functional changes.

Signed-off-by: Andy Chiu <andybnac@gmail.com>
Link: https://patch.msgid.link/20251112-v5_user_cfi_series-v23-16-b55691eacf4f@rivosinc.com
Signed-off-by: Paul Walmsley <pjw@kernel.org>

authored by

Andy Chiu and committed by
Paul Walmsley
818d78ba 8f0b4cce

+44 -21
+3
arch/riscv/include/asm/vector.h
··· 424 424 #define riscv_v_thread_free(tsk) do {} while (0) 425 425 #define riscv_v_setup_ctx_cache() do {} while (0) 426 426 #define riscv_v_thread_alloc(tsk) do {} while (0) 427 + #define get_cpu_vector_context() do {} while (0) 428 + #define put_cpu_vector_context() do {} while (0) 429 + #define riscv_v_vstate_set_restore(task, regs) do {} while (0) 427 430 428 431 #endif /* CONFIG_RISCV_ISA_V */ 429 432
+41 -21
arch/riscv/kernel/signal.c
··· 68 68 #define restore_fp_state(task, regs) (0) 69 69 #endif 70 70 71 - #ifdef CONFIG_RISCV_ISA_V 72 - 73 - static long save_v_state(struct pt_regs *regs, void __user **sc_vec) 71 + static long save_v_state(struct pt_regs *regs, void __user *sc_vec) 74 72 { 75 - struct __riscv_ctx_hdr __user *hdr; 76 73 struct __sc_riscv_v_state __user *state; 77 74 void __user *datap; 78 75 long err; 79 76 80 - hdr = *sc_vec; 81 - /* Place state to the user's signal context space after the hdr */ 82 - state = (struct __sc_riscv_v_state __user *)(hdr + 1); 77 + if (!IS_ENABLED(CONFIG_RISCV_ISA_V) || 78 + !((has_vector() || has_xtheadvector()) && 79 + riscv_v_vstate_query(regs))) 80 + return 0; 81 + 82 + /* Place state to the user's signal context space */ 83 + state = (struct __sc_riscv_v_state __user *)sc_vec; 83 84 /* Point datap right after the end of __sc_riscv_v_state */ 84 85 datap = state + 1; 85 86 ··· 98 97 err |= __put_user((__force void *)datap, &state->v_state.datap); 99 98 /* Copy the whole vector content to user space datap. */ 100 99 err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize); 101 - /* Copy magic to the user space after saving all vector conetext */ 102 - err |= __put_user(RISCV_V_MAGIC, &hdr->magic); 103 - err |= __put_user(riscv_v_sc_size, &hdr->size); 104 100 if (unlikely(err)) 105 - return err; 101 + return -EFAULT; 106 102 107 - /* Only progress the sv_vec if everything has done successfully */ 108 - *sc_vec += riscv_v_sc_size; 109 - return 0; 103 + /* Only return the size if everything has done successfully */ 104 + return riscv_v_sc_size; 110 105 } 111 106 112 107 /* ··· 139 142 */ 140 143 return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize); 141 144 } 142 - #else 143 - #define save_v_state(task, regs) (0) 144 - #define __restore_v_state(task, regs) (0) 145 - #endif 145 + 146 + struct arch_ext_priv { 147 + __u32 magic; 148 + long (*save)(struct pt_regs *regs, void __user *sc_vec); 149 + }; 150 + 151 + struct arch_ext_priv arch_ext_list[] = { 152 + { 153 + .magic = RISCV_V_MAGIC, 154 + .save = &save_v_state, 155 + }, 156 + }; 157 + 158 + const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list); 146 159 147 160 static long restore_sigcontext(struct pt_regs *regs, 148 161 struct sigcontext __user *sc) ··· 277 270 { 278 271 struct sigcontext __user *sc = &frame->uc.uc_mcontext; 279 272 struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr; 280 - long err; 273 + struct arch_ext_priv *arch_ext; 274 + long err, i, ext_size; 281 275 282 276 /* sc_regs is structured the same as the start of pt_regs */ 283 277 err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs)); ··· 286 278 if (has_fpu()) 287 279 err |= save_fp_state(regs, &sc->sc_fpregs); 288 280 /* Save the vector state. */ 289 - if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs)) 290 - err |= save_v_state(regs, (void __user **)&sc_ext_ptr); 281 + for (i = 0; i < nr_arch_exts; i++) { 282 + arch_ext = &arch_ext_list[i]; 283 + if (!arch_ext->save) 284 + continue; 285 + 286 + ext_size = arch_ext->save(regs, sc_ext_ptr + 1); 287 + if (ext_size <= 0) { 288 + err |= ext_size; 289 + } else { 290 + err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic); 291 + err |= __put_user(ext_size, &sc_ext_ptr->size); 292 + sc_ext_ptr = (void *)sc_ext_ptr + ext_size; 293 + } 294 + } 291 295 /* Write zero to fp-reserved space and check it on restore_sigcontext */ 292 296 err |= __put_user(0, &sc->sc_extdesc.reserved); 293 297 /* And put END __riscv_ctx_hdr at the end. */