Skip to content

Commit a45ceda

Browse files
AndybnACTpalmer-dabbelt
authored andcommitted
riscv: signal: check fp-reserved words unconditionally
In order to let kernel/user locate and identify an extension context on the existing sigframe, we are going to utilize reserved space of fp and encode the information there. And since the sigcontext has already preserved a space for fp context w or w/o CONFIG_FPU, we move those reserved words checking/setting routine back into generic code. This commit also undone an additional logical change carried by the refactor commit 007f5c3 ("Refactor FPU code in signal setup/return procedures"). Originally we did not restore fp context if restoring of gpr have failed. And it was fine on the other side. In such way the kernel could keep the regfiles intact, and potentially react at the failing point of restore. Signed-off-by: Andy Chiu <[email protected]> Acked-by: Conor Dooley <[email protected]> Acked-by: Heiko Stuebner <[email protected]> Tested-by: Heiko Stuebner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 0c59922 commit a45ceda

File tree

1 file changed

+28
-27
lines changed

1 file changed

+28
-27
lines changed

arch/riscv/kernel/signal.c

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -40,47 +40,23 @@ static long restore_fp_state(struct pt_regs *regs,
4040
{
4141
long err;
4242
struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
43-
size_t i;
4443

4544
err = __copy_from_user(&current->thread.fstate, state, sizeof(*state));
4645
if (unlikely(err))
4746
return err;
4847

4948
fstate_restore(current, regs);
50-
51-
/* We support no other extension state at this time. */
52-
for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
53-
u32 value;
54-
55-
err = __get_user(value, &sc_fpregs->q.reserved[i]);
56-
if (unlikely(err))
57-
break;
58-
if (value != 0)
59-
return -EINVAL;
60-
}
61-
62-
return err;
49+
return 0;
6350
}
6451

6552
static long save_fp_state(struct pt_regs *regs,
6653
union __riscv_fp_state __user *sc_fpregs)
6754
{
6855
long err;
6956
struct __riscv_d_ext_state __user *state = &sc_fpregs->d;
70-
size_t i;
7157

7258
fstate_save(current, regs);
7359
err = __copy_to_user(state, &current->thread.fstate, sizeof(*state));
74-
if (unlikely(err))
75-
return err;
76-
77-
/* We support no other extension state at this time. */
78-
for (i = 0; i < ARRAY_SIZE(sc_fpregs->q.reserved); i++) {
79-
err = __put_user(0, &sc_fpregs->q.reserved[i]);
80-
if (unlikely(err))
81-
break;
82-
}
83-
8460
return err;
8561
}
8662
#else
@@ -92,11 +68,30 @@ static long restore_sigcontext(struct pt_regs *regs,
9268
struct sigcontext __user *sc)
9369
{
9470
long err;
71+
size_t i;
72+
9573
/* sc_regs is structured the same as the start of pt_regs */
9674
err = __copy_from_user(regs, &sc->sc_regs, sizeof(sc->sc_regs));
75+
if (unlikely(err))
76+
return err;
77+
9778
/* Restore the floating-point state. */
98-
if (has_fpu())
99-
err |= restore_fp_state(regs, &sc->sc_fpregs);
79+
if (has_fpu()) {
80+
err = restore_fp_state(regs, &sc->sc_fpregs);
81+
if (unlikely(err))
82+
return err;
83+
}
84+
85+
/* We support no other extension state at this time. */
86+
for (i = 0; i < ARRAY_SIZE(sc->sc_fpregs.q.reserved); i++) {
87+
u32 value;
88+
89+
err = __get_user(value, &sc->sc_fpregs.q.reserved[i]);
90+
if (unlikely(err))
91+
break;
92+
if (value != 0)
93+
return -EINVAL;
94+
}
10095
return err;
10196
}
10297

@@ -147,11 +142,17 @@ static long setup_sigcontext(struct rt_sigframe __user *frame,
147142
{
148143
struct sigcontext __user *sc = &frame->uc.uc_mcontext;
149144
long err;
145+
size_t i;
146+
150147
/* sc_regs is structured the same as the start of pt_regs */
151148
err = __copy_to_user(&sc->sc_regs, regs, sizeof(sc->sc_regs));
152149
/* Save the floating-point state. */
153150
if (has_fpu())
154151
err |= save_fp_state(regs, &sc->sc_fpregs);
152+
/* We support no other extension state at this time. */
153+
for (i = 0; i < ARRAY_SIZE(sc->sc_fpregs.q.reserved); i++)
154+
err |= __put_user(0, &sc->sc_fpregs.q.reserved[i]);
155+
155156
return err;
156157
}
157158

0 commit comments

Comments
 (0)