summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/riscv/include/asm/kvm_host.h2
-rw-r--r--arch/riscv/kvm/main.c2
-rw-r--r--arch/riscv/kvm/vcpu.c11
3 files changed, 15 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index ba5e53e7962b..a30600579231 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -290,6 +290,8 @@ static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {}
static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {}
+void kvm_riscv_clear_former_vcpu(void);
+
int kvm_riscv_setup_default_irq_routing(struct kvm *kvm, u32 lines);
void __kvm_riscv_unpriv_trap(void);
diff --git a/arch/riscv/kvm/main.c b/arch/riscv/kvm/main.c
index 0924c75100a2..350e4f097d6e 100644
--- a/arch/riscv/kvm/main.c
+++ b/arch/riscv/kvm/main.c
@@ -69,6 +69,8 @@ void kvm_arch_disable_virtualization_cpu(void)
csr_write(CSR_HEDELEG, 0);
csr_write(CSR_HIDELEG, 0);
+ kvm_riscv_clear_former_vcpu();
+
kvm_riscv_nacl_disable();
}
diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c
index 56dc0af2f9db..1b4416b20665 100644
--- a/arch/riscv/kvm/vcpu.c
+++ b/arch/riscv/kvm/vcpu.c
@@ -26,6 +26,17 @@
static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_former_vcpu);
+void kvm_riscv_clear_former_vcpu(void)
+{
+ /*
+ * Clear the per-CPU former VCPU pointer because hypervisor CSR state
+ * will be lost. This ensures that the next VCPU entry will properly
+ * restore all CSRs instead of incorrectly skipping CSR restoration
+ * via the fast-path optimization.
+ */
+ __this_cpu_write(kvm_former_vcpu, NULL);
+}
+
const struct kvm_stats_desc kvm_vcpu_stats_desc[] = {
KVM_GENERIC_VCPU_STATS(),
STATS_DESC_COUNTER(VCPU, ecall_exit_stat),