[PATCH 12/16] riscv: kvm: Add emulated test csr
Charlie Jenkins via B4 Relay
devnull+thecharlesjenkins.gmail.com at kernel.org
Tue Apr 7 21:46:00 PDT 2026
From: Charlie Jenkins <thecharlesjenkins at gmail.com>
To test the riscv kvm implementation of emulated CSRs, add support to
emulate the vsscratch csr when CONFIG_RISCV_KVM_TEST_CSR is set.
Signed-off-by: Charlie Jenkins <thecharlesjenkins at gmail.com>
---
arch/riscv/Kconfig.debug | 1 +
arch/riscv/include/asm/kvm_host.h | 10 ++++++++++
arch/riscv/include/asm/kvm_vcpu_test_csr.h | 15 +++++++++++++++
arch/riscv/kvm/Kconfig.debug | 16 ++++++++++++++++
arch/riscv/kvm/Makefile | 1 +
arch/riscv/kvm/vcpu_insn.c | 5 +++++
arch/riscv/kvm/vcpu_test_csr.c | 21 +++++++++++++++++++++
7 files changed, 69 insertions(+)
diff --git a/arch/riscv/Kconfig.debug b/arch/riscv/Kconfig.debug
index eafe17ebf710..be202267da6d 100644
--- a/arch/riscv/Kconfig.debug
+++ b/arch/riscv/Kconfig.debug
@@ -1 +1,2 @@
source "arch/riscv/kernel/tests/Kconfig.debug"
+source "arch/riscv/kvm/Kconfig.debug"
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 24585304c02b..709a1c18ce22 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -183,6 +183,12 @@ struct kvm_vcpu_reset_state {
unsigned long a1;
};
+#ifdef CONFIG_RISCV_KVM_TEST_CSR
+struct kvm_test_csr {
+ unsigned long val;
+};
+#endif
+
struct kvm_vcpu_arch {
/* VCPU ran at least once */
bool ran_atleast_once;
@@ -278,6 +284,10 @@ struct kvm_vcpu_arch {
gpa_t shmem;
u64 last_steal;
} sta;
+
+#ifdef CONFIG_RISCV_KVM_TEST_CSR
+ struct kvm_test_csr test_csr;
+#endif
};
/*
diff --git a/arch/riscv/include/asm/kvm_vcpu_test_csr.h b/arch/riscv/include/asm/kvm_vcpu_test_csr.h
new file mode 100644
index 000000000000..a844fccaafc3
--- /dev/null
+++ b/arch/riscv/include/asm/kvm_vcpu_test_csr.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __KVM_VCPU_RISCV_TEST_CSR_H
+#define __KVM_VCPU_RISCV_TEST_CSR_H
+
+#include <asm/kvm_vcpu_insn.h>
+
+#define KVM_RISCV_VCPU_TEST_CSR_FUNCS \
+ {.base = CSR_VSSCRATCH, .count = 1, .func = kvm_riscv_vcpu_test_csr },
+
+int kvm_riscv_vcpu_test_csr(struct kvm_vcpu *vcpu, unsigned int csr_num,
+ unsigned long *val, unsigned long new_val,
+ unsigned long wr_mask);
+
+#endif /* !__KVM_VCPU_RISCV_TEST_CSR_H */
diff --git a/arch/riscv/kvm/Kconfig.debug b/arch/riscv/kvm/Kconfig.debug
new file mode 100644
index 000000000000..dc76e02120a3
--- /dev/null
+++ b/arch/riscv/kvm/Kconfig.debug
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menu "arch/riscv/kvm testing"
+
+config RISCV_KVM_TEST_CSR
+ bool "Test KVM CSR emulation"
+ depends on KVM
+ default n
+ help
+ Enable this option to enable the emulation of a test hypervisor csr.
+ The KVM test csr is the vsscratch register. Once this is enabled,
+ reading/writing to the vsscratch register will trap into the host
+ supervisor and reflect the change.
+
+ If unsure, say N.
+
+endmenu # "arch/riscv/kvm testing"
diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
index 3b8afb038b35..02fd27ff33eb 100644
--- a/arch/riscv/kvm/Makefile
+++ b/arch/riscv/kvm/Makefile
@@ -36,6 +36,7 @@ kvm-y += vcpu_sbi_sta.o
kvm-y += vcpu_sbi_system.o
kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o
kvm-y += vcpu_switch.o
+kvm-$(CONFIG_RISCV_KVM_TEST_CSR) += vcpu_test_csr.o
kvm-y += vcpu_timer.o
kvm-y += vcpu_vector.o
kvm-y += vm.o
diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c
index 1d8741d02242..c5a70de4a579 100644
--- a/arch/riscv/kvm/vcpu_insn.c
+++ b/arch/riscv/kvm/vcpu_insn.c
@@ -10,6 +10,8 @@
#include <asm/cpufeature.h>
#include <asm/insn.h>
+#include <asm/kvm_vcpu_test_csr.h>
+
struct insn_func {
unsigned long mask;
unsigned long match;
@@ -112,6 +114,9 @@ static int seed_csr_rmw(struct kvm_vcpu *vcpu, unsigned int csr_num,
static const struct csr_func csr_funcs[] = {
KVM_RISCV_VCPU_AIA_CSR_FUNCS
KVM_RISCV_VCPU_HPMCOUNTER_CSR_FUNCS
+#ifdef CONFIG_RISCV_KVM_TEST_CSR
+ KVM_RISCV_VCPU_TEST_CSR_FUNCS
+#endif
{ .base = CSR_SEED, .count = 1, .func = seed_csr_rmw },
};
diff --git a/arch/riscv/kvm/vcpu_test_csr.c b/arch/riscv/kvm/vcpu_test_csr.c
new file mode 100644
index 000000000000..b8aa503cdaba
--- /dev/null
+++ b/arch/riscv/kvm/vcpu_test_csr.c
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kvm_host.h>
+#include <asm/kvm_vcpu_insn.h>
+#include <asm/kvm_vcpu_test_csr.h>
+
+#define vcpu_to_test_csr(vcpu) (&(vcpu)->arch.test_csr)
+
+int kvm_riscv_vcpu_test_csr(struct kvm_vcpu *vcpu, unsigned int csr_num,
+ unsigned long *val, unsigned long new_val,
+ unsigned long wr_mask)
+{
+ struct kvm_test_csr *test_csr = vcpu_to_test_csr(vcpu);
+
+ *val = test_csr->val;
+
+ if (wr_mask)
+ test_csr->val = (test_csr->val & ~wr_mask) | (new_val & wr_mask);
+
+ return KVM_INSN_CONTINUE_NEXT_SEPC;
+}
--
2.52.0
More information about the linux-riscv
mailing list