[RFC PATCH v8 19/21] riscv: Allocate space for vector registers in start_thread()

From: Greentime Hu
Date: Wed Sep 08 2021 - 13:46:52 EST


It allocates memory space for vector registers in start_thread() instead of
allocating in vstate_restore() in this patch. We can allocate memory here
so that it will be more readable.

Co-developed-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Vincent Chen <vincent.chen@xxxxxxxxxx>
Signed-off-by: Greentime Hu <greentime.hu@xxxxxxxxxx>
---
arch/riscv/include/asm/switch_to.h | 7 +------
arch/riscv/kernel/process.c | 15 +++++++++++++--
2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/arch/riscv/include/asm/switch_to.h b/arch/riscv/include/asm/switch_to.h
index de0573dad78f..b48c9c974564 100644
--- a/arch/riscv/include/asm/switch_to.h
+++ b/arch/riscv/include/asm/switch_to.h
@@ -103,12 +103,6 @@ static inline void vstate_restore(struct task_struct *task,
{
if ((regs->status & SR_VS) != SR_VS_OFF) {
struct __riscv_v_state *vstate = &(task->thread.vstate);
-
- /* Allocate space for vector registers. */
- if (!vstate->datap) {
- vstate->datap = kzalloc(riscv_vsize, GFP_ATOMIC);
- vstate->size = riscv_vsize;
- }
__vstate_restore(vstate, vstate->datap);
__vstate_clean(regs);
}
@@ -127,6 +121,7 @@ static inline void __switch_to_vector(struct task_struct *prev,

#else
#define has_vector false
+#define riscv_vsize (0)
#define vstate_save(task, regs) do { } while (0)
#define vstate_restore(task, regs) do { } while (0)
#define __switch_to_vector(__prev, __next) do { } while (0)
diff --git a/arch/riscv/kernel/process.c b/arch/riscv/kernel/process.c
index 0b86e9e531c9..05ff5f934e7e 100644
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -97,7 +97,16 @@ void start_thread(struct pt_regs *regs, unsigned long pc,
}

if (has_vector) {
+ struct __riscv_v_state *vstate = &(current->thread.vstate);
+
+ /* Enable vector and allocate memory for vector registers. */
+ if (!vstate->datap) {
+ vstate->datap = kzalloc(riscv_vsize, GFP_KERNEL);
+ if (WARN_ON(!vstate->datap))
+ return;
+ }
regs->status |= SR_VS_INITIAL;
+
/*
* Restore the initial value to the vector register
* before starting the user program.
@@ -121,9 +130,11 @@ void flush_thread(void)
memset(&current->thread.fstate, 0, sizeof(current->thread.fstate));
#endif
#ifdef CONFIG_VECTOR
- /* Reset vector state */
+ /* Reset vector state and keep datap pointer. */
vstate_off(current, task_pt_regs(current));
- memset(&current->thread.vstate, 0, sizeof(current->thread.vstate));
+ memset(&current->thread.vstate, 0, RISCV_V_STATE_DATAP);
+ if (current->thread.vstate.datap)
+ memset(current->thread.vstate.datap, 0, riscv_vsize);
#endif
}

--
2.31.1