[PATCH v5 3/7] riscv: vector: refactor vector context operations
Andy Chiu
tchiu at tenstorrent.com
Mon Aug 10 10:22:30 PDT 2026
Lift riscv_v_{enable,disable} out of __*vstate_{save,restore,discard} so
that we can reuse some functions without repeatedly turning on/off
vector.
Also, refactor and document about the user context save in preempt_v to
make code more readable.
Signed-off-by: Andy Chiu <tchiu at tenstorrent.com>
---
Changelog v5:
- rebase on top of the kvm fix[1]
Changelog v4:
- fix an unused variable warning (Olof)
Changelog v3:
- new patch since v3
---
arch/riscv/include/asm/kvm_vcpu_vector.h | 8 ++++++--
arch/riscv/include/asm/vector.h | 15 ++++++++-------
arch/riscv/kernel/kernel_mode_vector.c | 4 ++++
arch/riscv/kvm/vcpu.c | 2 +-
arch/riscv/kvm/vcpu_vector.c | 6 +++---
5 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/arch/riscv/include/asm/kvm_vcpu_vector.h b/arch/riscv/include/asm/kvm_vcpu_vector.h
index 6371d5ea5392..f6aba7ade694 100644
--- a/arch/riscv/include/asm/kvm_vcpu_vector.h
+++ b/arch/riscv/include/asm/kvm_vcpu_vector.h
@@ -16,14 +16,18 @@
#include <asm/vector.h>
#include <asm/kvm_host.h>
-static __always_inline void __kvm_riscv_vector_save(struct kvm_cpu_context *context)
+static __always_inline void kvm_riscv_vector_save(struct kvm_cpu_context *context)
{
+ riscv_v_enable();
__riscv_v_vstate_save(&context->vector, context->vector.datap);
+ riscv_v_disable();
}
-static __always_inline void __kvm_riscv_vector_restore(struct kvm_cpu_context *context)
+static __always_inline void kvm_riscv_vector_restore(struct kvm_cpu_context *context)
{
+ riscv_v_enable();
__riscv_v_vstate_restore(&context->vector, context->vector.datap);
+ riscv_v_disable();
}
void kvm_riscv_vcpu_vector_reset(struct kvm_vcpu *vcpu);
diff --git a/arch/riscv/include/asm/vector.h b/arch/riscv/include/asm/vector.h
index fccf9edb4e6a..e7f9fce5ab43 100644
--- a/arch/riscv/include/asm/vector.h
+++ b/arch/riscv/include/asm/vector.h
@@ -203,7 +203,6 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
{
unsigned long vl;
- riscv_v_enable();
__vstate_csr_save(save_to);
if (has_xtheadvector()) {
asm volatile (
@@ -232,7 +231,6 @@ static inline void __riscv_v_vstate_save(struct __riscv_v_ext_state *save_to,
".option pop\n\t"
: "=&r" (vl) : "r" (datap) : "memory");
}
- riscv_v_disable();
}
static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_from,
@@ -240,7 +238,6 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
{
unsigned long vl;
- riscv_v_enable();
if (has_xtheadvector()) {
asm volatile (
"mv t0, %0\n\t"
@@ -269,14 +266,12 @@ static inline void __riscv_v_vstate_restore(struct __riscv_v_ext_state *restore_
: "=&r" (vl) : "r" (datap) : "memory");
}
__vstate_csr_restore(restore_from);
- riscv_v_disable();
}
static inline void __riscv_v_vstate_discard(void)
{
unsigned long vl, vtype_inval = 1UL << (BITS_PER_LONG - 1);
- riscv_v_enable();
if (has_xtheadvector())
asm volatile (THEAD_VSETVLI_T4X0E8M8D1 : : : "t4");
else
@@ -296,14 +291,14 @@ static inline void __riscv_v_vstate_discard(void)
"vsetvl %0, x0, %1\n\t"
".option pop\n\t"
: "=&r" (vl) : "r" (vtype_inval));
-
- riscv_v_disable();
}
static inline void riscv_v_vstate_discard(struct pt_regs *regs)
{
if (riscv_v_vstate_query(regs)) {
+ riscv_v_enable();
__riscv_v_vstate_discard();
+ riscv_v_disable();
__riscv_v_vstate_dirty(regs);
}
}
@@ -312,7 +307,9 @@ static inline void riscv_v_vstate_save(struct __riscv_v_ext_state *vstate,
struct pt_regs *regs)
{
if (__riscv_v_vstate_check(regs->status, DIRTY)) {
+ riscv_v_enable();
__riscv_v_vstate_save(vstate, vstate->datap);
+ riscv_v_disable();
__riscv_v_vstate_clean(regs);
}
}
@@ -321,7 +318,9 @@ static inline void riscv_v_vstate_restore(struct __riscv_v_ext_state *vstate,
struct pt_regs *regs)
{
if (riscv_v_vstate_query(regs)) {
+ riscv_v_enable();
__riscv_v_vstate_restore(vstate, vstate->datap);
+ riscv_v_disable();
__riscv_v_vstate_clean(regs);
}
}
@@ -382,8 +381,10 @@ static inline void __switch_to_vector(struct task_struct *prev,
prev->thread.riscv_v_flags |= RISCV_PREEMPT_V_IN_SCHEDULE;
}
if (riscv_preempt_v_dirty(prev)) {
+ riscv_v_enable();
__riscv_v_vstate_save(&prev->thread.kernel_vstate,
prev->thread.kernel_vstate.datap);
+ riscv_v_disable();
riscv_preempt_v_clear_dirty(prev);
}
} else {
diff --git a/arch/riscv/kernel/kernel_mode_vector.c b/arch/riscv/kernel/kernel_mode_vector.c
index 5ad93ddf6a10..369a0756d059 100644
--- a/arch/riscv/kernel/kernel_mode_vector.c
+++ b/arch/riscv/kernel/kernel_mode_vector.c
@@ -171,7 +171,9 @@ static int riscv_v_start_kernel_context(void)
WARN_ON(riscv_v_ctx_get_depth() == 0);
get_cpu_vector_context();
if (riscv_preempt_v_dirty(current)) {
+ riscv_v_enable();
__riscv_v_vstate_save(kvstate, kvstate->datap);
+ riscv_v_disable();
riscv_preempt_v_clear_dirty(current);
}
riscv_preempt_v_set_restore(current);
@@ -215,7 +217,9 @@ asmlinkage void riscv_v_context_nesting_end(struct pt_regs *regs)
depth = riscv_v_ctx_get_depth();
if (depth == 0) {
if (riscv_preempt_v_restore(current)) {
+ riscv_v_enable();
__riscv_v_vstate_restore(vstate, vstate->datap);
+ riscv_v_disable();
__riscv_v_vstate_clean(regs);
riscv_preempt_v_reset_flags();
}
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index e2651808e1d3..3d2566647029 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -773,7 +773,7 @@ static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu,
if (current->thread.riscv_v_flags & RISCV_V_VCPU_NEED_RESTORE) {
current->thread.riscv_v_flags &= ~RISCV_V_VCPU_NEED_RESTORE;
current->thread.riscv_v_flags |= RISCV_V_VCPU_CTX;
- __kvm_riscv_vector_restore(gcntx);
+ kvm_riscv_vector_restore(gcntx);
gcntx->sstatus = (gcntx->sstatus & ~SR_VS) | SR_VS_CLEAN;
}
diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
index ef2eee6ec308..6cfa5c0c7e6c 100644
--- a/arch/riscv/kvm/vcpu_vector.c
+++ b/arch/riscv/kvm/vcpu_vector.c
@@ -46,7 +46,7 @@ void kvm_riscv_vcpu_guest_vector_save(struct kvm_cpu_context *cntx,
{
if ((cntx->sstatus & SR_VS) == SR_VS_DIRTY) {
if (riscv_isa_extension_available(isa, v))
- __kvm_riscv_vector_save(cntx);
+ kvm_riscv_vector_save(cntx);
kvm_riscv_vcpu_vector_clean(cntx);
}
}
@@ -64,13 +64,13 @@ void kvm_riscv_vcpu_host_vector_save(struct kvm_cpu_context *cntx)
{
/* No need to check host sstatus as it can be modified outside */
if (!kvm_riscv_isa_check_host(V))
- __kvm_riscv_vector_save(cntx);
+ kvm_riscv_vector_save(cntx);
}
void kvm_riscv_vcpu_host_vector_restore(struct kvm_cpu_context *cntx)
{
if (!kvm_riscv_isa_check_host(V))
- __kvm_riscv_vector_restore(cntx);
+ kvm_riscv_vector_restore(cntx);
riscv_v_flags_set(riscv_v_flags() & ~(RISCV_V_VCPU_CTX | RISCV_V_VCPU_NEED_RESTORE));
}
--
2.43.0
More information about the kvm-riscv
mailing list