Skip to content

Commit 818d78b

Browse files
AndybnACTPaul Walmsley
authored andcommitted
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>
1 parent 8f0b4cc commit 818d78b

2 files changed

Lines changed: 44 additions & 21 deletions

File tree

arch/riscv/include/asm/vector.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,9 @@ static inline bool riscv_v_vstate_ctrl_user_allowed(void) { return false; }
424424
#define riscv_v_thread_free(tsk) do {} while (0)
425425
#define riscv_v_setup_ctx_cache() do {} while (0)
426426
#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)
427430

428431
#endif /* CONFIG_RISCV_ISA_V */
429432

arch/riscv/kernel/signal.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,18 +68,19 @@ static long save_fp_state(struct pt_regs *regs,
6868
#define restore_fp_state(task, regs) (0)
6969
#endif
7070

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)
7472
{
75-
struct __riscv_ctx_hdr __user *hdr;
7673
struct __sc_riscv_v_state __user *state;
7774
void __user *datap;
7875
long err;
7976

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;
8384
/* Point datap right after the end of __sc_riscv_v_state */
8485
datap = state + 1;
8586

@@ -97,15 +98,11 @@ static long save_v_state(struct pt_regs *regs, void __user **sc_vec)
9798
err |= __put_user((__force void *)datap, &state->v_state.datap);
9899
/* Copy the whole vector content to user space datap. */
99100
err |= __copy_to_user(datap, current->thread.vstate.datap, riscv_v_vsize);
100-
/* Copy magic to the user space after saving all vector conetext */
101-
err |= __put_user(RISCV_V_MAGIC, &hdr->magic);
102-
err |= __put_user(riscv_v_sc_size, &hdr->size);
103101
if (unlikely(err))
104-
return err;
102+
return -EFAULT;
105103

106-
/* Only progress the sv_vec if everything has done successfully */
107-
*sc_vec += riscv_v_sc_size;
108-
return 0;
104+
/* Only return the size if everything has done successfully */
105+
return riscv_v_sc_size;
109106
}
110107

111108
/*
@@ -142,10 +139,20 @@ static long __restore_v_state(struct pt_regs *regs, void __user *sc_vec)
142139
*/
143140
return copy_from_user(current->thread.vstate.datap, datap, riscv_v_vsize);
144141
}
145-
#else
146-
#define save_v_state(task, regs) (0)
147-
#define __restore_v_state(task, regs) (0)
148-
#endif
142+
143+
struct arch_ext_priv {
144+
__u32 magic;
145+
long (*save)(struct pt_regs *regs, void __user *sc_vec);
146+
};
147+
148+
struct arch_ext_priv arch_ext_list[] = {
149+
{
150+
.magic = RISCV_V_MAGIC,
151+
.save = &save_v_state,
152+
},
153+
};
154+
155+
const size_t nr_arch_exts = ARRAY_SIZE(arch_ext_list);
149156

150157
static long restore_sigcontext(struct pt_regs *regs,
151158
struct sigcontext __user *sc)
@@ -270,16 +277,29 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
270277
{
271278
struct sigcontext __user *sc = &frame->uc.uc_mcontext;
272279
struct __riscv_ctx_hdr __user *sc_ext_ptr = &sc->sc_extdesc.hdr;
273-
long err;
280+
struct arch_ext_priv *arch_ext;
281+
long err, i, ext_size;
274282

275283
/* sc_regs is structured the same as the start of pt_regs */
276284
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
277285
/* Save the floating-point state. */
278286
if (has_fpu())
279287
err |= save_fp_state(regs, &sc->sc_fpregs);
280288
/* Save the vector state. */
281-
if ((has_vector() || has_xtheadvector()) && riscv_v_vstate_query(regs))
282-
err |= save_v_state(regs, (void __user **)&sc_ext_ptr);
289+
for (i = 0; i < nr_arch_exts; i++) {
290+
arch_ext = &arch_ext_list[i];
291+
if (!arch_ext->save)
292+
continue;
293+
294+
ext_size = arch_ext->save(regs, sc_ext_ptr + 1);
295+
if (ext_size <= 0) {
296+
err |= ext_size;
297+
} else {
298+
err |= __put_user(arch_ext->magic, &sc_ext_ptr->magic);
299+
err |= __put_user(ext_size, &sc_ext_ptr->size);
300+
sc_ext_ptr = (void *)sc_ext_ptr + ext_size;
301+
}
302+
}
283303
/* Write zero to fp-reserved space and check it on restore_sigcontext */
284304
err |= __put_user(0, &sc->sc_extdesc.reserved);
285305
/* And put END __riscv_ctx_hdr at the end. */

0 commit comments

Comments
 (0)