[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260120080013.2153519-6-anup.patel@oss.qualcomm.com>
Date: Tue, 20 Jan 2026 13:29:51 +0530
From: Anup Patel <anup.patel@....qualcomm.com>
To: Paolo Bonzini <pbonzini@...hat.com>, Atish Patra <atish.patra@...ux.dev>
Cc: Palmer Dabbelt <palmer@...belt.com>, Paul Walmsley <pjw@...nel.org>,
Alexandre Ghiti <alex@...ti.fr>, Shuah Khan <shuah@...nel.org>,
Anup Patel <anup@...infault.org>,
Andrew Jones <andrew.jones@....qualcomm.com>,
kvm-riscv@...ts.infradead.org, kvm@...r.kernel.org,
linux-riscv@...ts.infradead.org, linux-kernel@...r.kernel.org,
linux-kselftest@...r.kernel.org,
Anup Patel <anup.patel@....qualcomm.com>
Subject: [PATCH 05/27] RISC-V: KVM: Factor-out ISA checks into separate sources
The KVM ISA extension related checks are not VCPU specific and
should be factored out of vcpu_onereg.c into separate sources.
Signed-off-by: Anup Patel <anup.patel@....qualcomm.com>
---
arch/riscv/include/asm/kvm_host.h | 4 -
arch/riscv/include/asm/kvm_isa.h | 20 +++
arch/riscv/kvm/Makefile | 1 +
arch/riscv/kvm/aia_device.c | 1 +
arch/riscv/kvm/isa.c | 251 +++++++++++++++++++++++++++++
arch/riscv/kvm/vcpu_fp.c | 1 +
arch/riscv/kvm/vcpu_onereg.c | 257 +-----------------------------
arch/riscv/kvm/vcpu_pmu.c | 3 +-
arch/riscv/kvm/vcpu_timer.c | 1 +
arch/riscv/kvm/vcpu_vector.c | 1 +
10 files changed, 286 insertions(+), 254 deletions(-)
create mode 100644 arch/riscv/include/asm/kvm_isa.h
create mode 100644 arch/riscv/kvm/isa.c
diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h
index 47a350c25555..24585304c02b 100644
--- a/arch/riscv/include/asm/kvm_host.h
+++ b/arch/riscv/include/asm/kvm_host.h
@@ -308,10 +308,6 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run,
void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch);
-int __kvm_riscv_isa_check_host(unsigned long kvm_ext, unsigned long *guest_ext);
-#define kvm_riscv_isa_check_host(ext) \
- __kvm_riscv_isa_check_host(KVM_RISCV_ISA_EXT_##ext, NULL)
-
void kvm_riscv_vcpu_setup_isa(struct kvm_vcpu *vcpu);
unsigned long kvm_riscv_vcpu_num_regs(struct kvm_vcpu *vcpu);
int kvm_riscv_vcpu_copy_reg_indices(struct kvm_vcpu *vcpu,
diff --git a/arch/riscv/include/asm/kvm_isa.h b/arch/riscv/include/asm/kvm_isa.h
new file mode 100644
index 000000000000..bc4b956d5f17
--- /dev/null
+++ b/arch/riscv/include/asm/kvm_isa.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2026 Qualcomm Technologies, Inc.
+ */
+
+#ifndef __KVM_RISCV_ISA_H
+#define __KVM_RISCV_ISA_H
+
+#include <linux/types.h>
+
+unsigned long kvm_riscv_base2isa_ext(unsigned long base_ext);
+
+int __kvm_riscv_isa_check_host(unsigned long ext, unsigned long *base_ext);
+#define kvm_riscv_isa_check_host(ext) \
+ __kvm_riscv_isa_check_host(KVM_RISCV_ISA_EXT_##ext, NULL)
+
+bool kvm_riscv_isa_enable_allowed(unsigned long ext);
+bool kvm_riscv_isa_disable_allowed(unsigned long ext);
+
+#endif
diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile
index 3b8afb038b35..07eab96189e7 100644
--- a/arch/riscv/kvm/Makefile
+++ b/arch/riscv/kvm/Makefile
@@ -15,6 +15,7 @@ kvm-y += aia_aplic.o
kvm-y += aia_device.o
kvm-y += aia_imsic.o
kvm-y += gstage.o
+kvm-y += isa.o
kvm-y += main.o
kvm-y += mmu.o
kvm-y += nacl.o
diff --git a/arch/riscv/kvm/aia_device.c b/arch/riscv/kvm/aia_device.c
index 4cecab9bf102..77629b7eac09 100644
--- a/arch/riscv/kvm/aia_device.c
+++ b/arch/riscv/kvm/aia_device.c
@@ -12,6 +12,7 @@
#include <linux/kvm_host.h>
#include <linux/uaccess.h>
#include <linux/cpufeature.h>
+#include <asm/kvm_isa.h>
static int aia_create(struct kvm_device *dev, u32 type)
{
diff --git a/arch/riscv/kvm/isa.c b/arch/riscv/kvm/isa.c
new file mode 100644
index 000000000000..e860f6d79bb0
--- /dev/null
+++ b/arch/riscv/kvm/isa.c
@@ -0,0 +1,251 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026 Qualcomm Technologies, Inc.
+ */
+
+#include <linux/errno.h>
+#include <linux/kvm_host.h>
+#include <linux/cpufeature.h>
+#include <linux/pgtable.h>
+#include <asm/kvm_isa.h>
+#include <asm/vector.h>
+
+#define KVM_ISA_EXT_ARR(ext) \
+[KVM_RISCV_ISA_EXT_##ext] = RISCV_ISA_EXT_##ext
+
+/* Mapping between KVM ISA Extension ID & guest ISA extension ID */
+static const unsigned long kvm_isa_ext_arr[] = {
+ /* Single letter extensions (alphabetically sorted) */
+ [KVM_RISCV_ISA_EXT_A] = RISCV_ISA_EXT_a,
+ [KVM_RISCV_ISA_EXT_C] = RISCV_ISA_EXT_c,
+ [KVM_RISCV_ISA_EXT_D] = RISCV_ISA_EXT_d,
+ [KVM_RISCV_ISA_EXT_F] = RISCV_ISA_EXT_f,
+ [KVM_RISCV_ISA_EXT_H] = RISCV_ISA_EXT_h,
+ [KVM_RISCV_ISA_EXT_I] = RISCV_ISA_EXT_i,
+ [KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m,
+ [KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_v,
+ /* Multi letter extensions (alphabetically sorted) */
+ KVM_ISA_EXT_ARR(SMNPM),
+ KVM_ISA_EXT_ARR(SMSTATEEN),
+ KVM_ISA_EXT_ARR(SSAIA),
+ KVM_ISA_EXT_ARR(SSCOFPMF),
+ KVM_ISA_EXT_ARR(SSNPM),
+ KVM_ISA_EXT_ARR(SSTC),
+ KVM_ISA_EXT_ARR(SVADE),
+ KVM_ISA_EXT_ARR(SVADU),
+ KVM_ISA_EXT_ARR(SVINVAL),
+ KVM_ISA_EXT_ARR(SVNAPOT),
+ KVM_ISA_EXT_ARR(SVPBMT),
+ KVM_ISA_EXT_ARR(SVVPTC),
+ KVM_ISA_EXT_ARR(ZAAMO),
+ KVM_ISA_EXT_ARR(ZABHA),
+ KVM_ISA_EXT_ARR(ZACAS),
+ KVM_ISA_EXT_ARR(ZALASR),
+ KVM_ISA_EXT_ARR(ZALRSC),
+ KVM_ISA_EXT_ARR(ZAWRS),
+ KVM_ISA_EXT_ARR(ZBA),
+ KVM_ISA_EXT_ARR(ZBB),
+ KVM_ISA_EXT_ARR(ZBC),
+ KVM_ISA_EXT_ARR(ZBKB),
+ KVM_ISA_EXT_ARR(ZBKC),
+ KVM_ISA_EXT_ARR(ZBKX),
+ KVM_ISA_EXT_ARR(ZBS),
+ KVM_ISA_EXT_ARR(ZCA),
+ KVM_ISA_EXT_ARR(ZCB),
+ KVM_ISA_EXT_ARR(ZCD),
+ KVM_ISA_EXT_ARR(ZCF),
+ KVM_ISA_EXT_ARR(ZCLSD),
+ KVM_ISA_EXT_ARR(ZCMOP),
+ KVM_ISA_EXT_ARR(ZFA),
+ KVM_ISA_EXT_ARR(ZFBFMIN),
+ KVM_ISA_EXT_ARR(ZFH),
+ KVM_ISA_EXT_ARR(ZFHMIN),
+ KVM_ISA_EXT_ARR(ZICBOM),
+ KVM_ISA_EXT_ARR(ZICBOP),
+ KVM_ISA_EXT_ARR(ZICBOZ),
+ KVM_ISA_EXT_ARR(ZICCRSE),
+ KVM_ISA_EXT_ARR(ZICNTR),
+ KVM_ISA_EXT_ARR(ZICOND),
+ KVM_ISA_EXT_ARR(ZICSR),
+ KVM_ISA_EXT_ARR(ZIFENCEI),
+ KVM_ISA_EXT_ARR(ZIHINTNTL),
+ KVM_ISA_EXT_ARR(ZIHINTPAUSE),
+ KVM_ISA_EXT_ARR(ZIHPM),
+ KVM_ISA_EXT_ARR(ZILSD),
+ KVM_ISA_EXT_ARR(ZIMOP),
+ KVM_ISA_EXT_ARR(ZKND),
+ KVM_ISA_EXT_ARR(ZKNE),
+ KVM_ISA_EXT_ARR(ZKNH),
+ KVM_ISA_EXT_ARR(ZKR),
+ KVM_ISA_EXT_ARR(ZKSED),
+ KVM_ISA_EXT_ARR(ZKSH),
+ KVM_ISA_EXT_ARR(ZKT),
+ KVM_ISA_EXT_ARR(ZTSO),
+ KVM_ISA_EXT_ARR(ZVBB),
+ KVM_ISA_EXT_ARR(ZVBC),
+ KVM_ISA_EXT_ARR(ZVFBFMIN),
+ KVM_ISA_EXT_ARR(ZVFBFWMA),
+ KVM_ISA_EXT_ARR(ZVFH),
+ KVM_ISA_EXT_ARR(ZVFHMIN),
+ KVM_ISA_EXT_ARR(ZVKB),
+ KVM_ISA_EXT_ARR(ZVKG),
+ KVM_ISA_EXT_ARR(ZVKNED),
+ KVM_ISA_EXT_ARR(ZVKNHA),
+ KVM_ISA_EXT_ARR(ZVKNHB),
+ KVM_ISA_EXT_ARR(ZVKSED),
+ KVM_ISA_EXT_ARR(ZVKSH),
+ KVM_ISA_EXT_ARR(ZVKT),
+};
+
+unsigned long kvm_riscv_base2isa_ext(unsigned long base_ext)
+{
+ unsigned long i;
+
+ for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) {
+ if (kvm_isa_ext_arr[i] == base_ext)
+ return i;
+ }
+
+ return KVM_RISCV_ISA_EXT_MAX;
+}
+
+int __kvm_riscv_isa_check_host(unsigned long ext, unsigned long *base_ext)
+{
+ unsigned long host_ext;
+
+ if (ext >= KVM_RISCV_ISA_EXT_MAX ||
+ ext >= ARRAY_SIZE(kvm_isa_ext_arr))
+ return -ENOENT;
+
+ switch (kvm_isa_ext_arr[ext]) {
+ case RISCV_ISA_EXT_SMNPM:
+ /*
+ * Pointer masking effective in (H)S-mode is provided by the
+ * Smnpm extension, so that extension is reported to the guest,
+ * even though the CSR bits for configuring VS-mode pointer
+ * masking on the host side are part of the Ssnpm extension.
+ */
+ host_ext = RISCV_ISA_EXT_SSNPM;
+ break;
+ default:
+ host_ext = kvm_isa_ext_arr[ext];
+ break;
+ }
+
+ if (!__riscv_isa_extension_available(NULL, host_ext))
+ return -ENOENT;
+
+ if (base_ext)
+ *base_ext = kvm_isa_ext_arr[ext];
+
+ return 0;
+}
+
+bool kvm_riscv_isa_enable_allowed(unsigned long ext)
+{
+ switch (ext) {
+ case KVM_RISCV_ISA_EXT_H:
+ return false;
+ case KVM_RISCV_ISA_EXT_SSCOFPMF:
+ /* Sscofpmf depends on interrupt filtering defined in ssaia */
+ return !kvm_riscv_isa_check_host(SSAIA);
+ case KVM_RISCV_ISA_EXT_SVADU:
+ /*
+ * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero.
+ * Guest OS can use Svadu only when host OS enable Svadu.
+ */
+ return arch_has_hw_pte_young();
+ case KVM_RISCV_ISA_EXT_V:
+ return riscv_v_vstate_ctrl_user_allowed();
+ default:
+ break;
+ }
+
+ return true;
+}
+
+bool kvm_riscv_isa_disable_allowed(unsigned long ext)
+{
+ switch (ext) {
+ /* Extensions which don't have any mechanism to disable */
+ case KVM_RISCV_ISA_EXT_A:
+ case KVM_RISCV_ISA_EXT_C:
+ case KVM_RISCV_ISA_EXT_I:
+ case KVM_RISCV_ISA_EXT_M:
+ /* There is not architectural config bit to disable sscofpmf completely */
+ case KVM_RISCV_ISA_EXT_SSCOFPMF:
+ case KVM_RISCV_ISA_EXT_SSNPM:
+ case KVM_RISCV_ISA_EXT_SSTC:
+ case KVM_RISCV_ISA_EXT_SVINVAL:
+ case KVM_RISCV_ISA_EXT_SVNAPOT:
+ case KVM_RISCV_ISA_EXT_SVVPTC:
+ case KVM_RISCV_ISA_EXT_ZAAMO:
+ case KVM_RISCV_ISA_EXT_ZABHA:
+ case KVM_RISCV_ISA_EXT_ZACAS:
+ case KVM_RISCV_ISA_EXT_ZALASR:
+ case KVM_RISCV_ISA_EXT_ZALRSC:
+ case KVM_RISCV_ISA_EXT_ZAWRS:
+ case KVM_RISCV_ISA_EXT_ZBA:
+ case KVM_RISCV_ISA_EXT_ZBB:
+ case KVM_RISCV_ISA_EXT_ZBC:
+ case KVM_RISCV_ISA_EXT_ZBKB:
+ case KVM_RISCV_ISA_EXT_ZBKC:
+ case KVM_RISCV_ISA_EXT_ZBKX:
+ case KVM_RISCV_ISA_EXT_ZBS:
+ case KVM_RISCV_ISA_EXT_ZCA:
+ case KVM_RISCV_ISA_EXT_ZCB:
+ case KVM_RISCV_ISA_EXT_ZCD:
+ case KVM_RISCV_ISA_EXT_ZCF:
+ case KVM_RISCV_ISA_EXT_ZCMOP:
+ case KVM_RISCV_ISA_EXT_ZFA:
+ case KVM_RISCV_ISA_EXT_ZFBFMIN:
+ case KVM_RISCV_ISA_EXT_ZFH:
+ case KVM_RISCV_ISA_EXT_ZFHMIN:
+ case KVM_RISCV_ISA_EXT_ZICBOP:
+ case KVM_RISCV_ISA_EXT_ZICCRSE:
+ case KVM_RISCV_ISA_EXT_ZICNTR:
+ case KVM_RISCV_ISA_EXT_ZICOND:
+ case KVM_RISCV_ISA_EXT_ZICSR:
+ case KVM_RISCV_ISA_EXT_ZIFENCEI:
+ case KVM_RISCV_ISA_EXT_ZIHINTNTL:
+ case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
+ case KVM_RISCV_ISA_EXT_ZIHPM:
+ case KVM_RISCV_ISA_EXT_ZIMOP:
+ case KVM_RISCV_ISA_EXT_ZKND:
+ case KVM_RISCV_ISA_EXT_ZKNE:
+ case KVM_RISCV_ISA_EXT_ZKNH:
+ case KVM_RISCV_ISA_EXT_ZKR:
+ case KVM_RISCV_ISA_EXT_ZKSED:
+ case KVM_RISCV_ISA_EXT_ZKSH:
+ case KVM_RISCV_ISA_EXT_ZKT:
+ case KVM_RISCV_ISA_EXT_ZTSO:
+ case KVM_RISCV_ISA_EXT_ZVBB:
+ case KVM_RISCV_ISA_EXT_ZVBC:
+ case KVM_RISCV_ISA_EXT_ZVFBFMIN:
+ case KVM_RISCV_ISA_EXT_ZVFBFWMA:
+ case KVM_RISCV_ISA_EXT_ZVFH:
+ case KVM_RISCV_ISA_EXT_ZVFHMIN:
+ case KVM_RISCV_ISA_EXT_ZVKB:
+ case KVM_RISCV_ISA_EXT_ZVKG:
+ case KVM_RISCV_ISA_EXT_ZVKNED:
+ case KVM_RISCV_ISA_EXT_ZVKNHA:
+ case KVM_RISCV_ISA_EXT_ZVKNHB:
+ case KVM_RISCV_ISA_EXT_ZVKSED:
+ case KVM_RISCV_ISA_EXT_ZVKSH:
+ case KVM_RISCV_ISA_EXT_ZVKT:
+ return false;
+ /* Extensions which can be disabled using Smstateen */
+ case KVM_RISCV_ISA_EXT_SSAIA:
+ return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN);
+ case KVM_RISCV_ISA_EXT_SVADE:
+ /*
+ * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero.
+ * Svade can't be disabled unless we support Svadu.
+ */
+ return arch_has_hw_pte_young();
+ default:
+ break;
+ }
+
+ return true;
+}
diff --git a/arch/riscv/kvm/vcpu_fp.c b/arch/riscv/kvm/vcpu_fp.c
index 32ab5938a2ec..49ad7446d2bb 100644
--- a/arch/riscv/kvm/vcpu_fp.c
+++ b/arch/riscv/kvm/vcpu_fp.c
@@ -12,6 +12,7 @@
#include <linux/kvm_host.h>
#include <linux/uaccess.h>
#include <asm/cpufeature.h>
+#include <asm/kvm_isa.h>
#ifdef CONFIG_FPU
void kvm_riscv_vcpu_fp_reset(struct kvm_vcpu *vcpu)
diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c
index f0f8c293d950..6b16eee2c833 100644
--- a/arch/riscv/kvm/vcpu_onereg.c
+++ b/arch/riscv/kvm/vcpu_onereg.c
@@ -14,260 +14,19 @@
#include <linux/kvm_host.h>
#include <asm/cacheflush.h>
#include <asm/cpufeature.h>
+#include <asm/kvm_isa.h>
#include <asm/kvm_vcpu_vector.h>
-#include <asm/pgtable.h>
-#include <asm/vector.h>
#define KVM_RISCV_BASE_ISA_MASK GENMASK(25, 0)
-#define KVM_ISA_EXT_ARR(ext) \
-[KVM_RISCV_ISA_EXT_##ext] = RISCV_ISA_EXT_##ext
-
-/* Mapping between KVM ISA Extension ID & guest ISA extension ID */
-static const unsigned long kvm_isa_ext_arr[] = {
- /* Single letter extensions (alphabetically sorted) */
- [KVM_RISCV_ISA_EXT_A] = RISCV_ISA_EXT_a,
- [KVM_RISCV_ISA_EXT_C] = RISCV_ISA_EXT_c,
- [KVM_RISCV_ISA_EXT_D] = RISCV_ISA_EXT_d,
- [KVM_RISCV_ISA_EXT_F] = RISCV_ISA_EXT_f,
- [KVM_RISCV_ISA_EXT_H] = RISCV_ISA_EXT_h,
- [KVM_RISCV_ISA_EXT_I] = RISCV_ISA_EXT_i,
- [KVM_RISCV_ISA_EXT_M] = RISCV_ISA_EXT_m,
- [KVM_RISCV_ISA_EXT_V] = RISCV_ISA_EXT_v,
- /* Multi letter extensions (alphabetically sorted) */
- KVM_ISA_EXT_ARR(SMNPM),
- KVM_ISA_EXT_ARR(SMSTATEEN),
- KVM_ISA_EXT_ARR(SSAIA),
- KVM_ISA_EXT_ARR(SSCOFPMF),
- KVM_ISA_EXT_ARR(SSNPM),
- KVM_ISA_EXT_ARR(SSTC),
- KVM_ISA_EXT_ARR(SVADE),
- KVM_ISA_EXT_ARR(SVADU),
- KVM_ISA_EXT_ARR(SVINVAL),
- KVM_ISA_EXT_ARR(SVNAPOT),
- KVM_ISA_EXT_ARR(SVPBMT),
- KVM_ISA_EXT_ARR(SVVPTC),
- KVM_ISA_EXT_ARR(ZAAMO),
- KVM_ISA_EXT_ARR(ZABHA),
- KVM_ISA_EXT_ARR(ZACAS),
- KVM_ISA_EXT_ARR(ZALASR),
- KVM_ISA_EXT_ARR(ZALRSC),
- KVM_ISA_EXT_ARR(ZAWRS),
- KVM_ISA_EXT_ARR(ZBA),
- KVM_ISA_EXT_ARR(ZBB),
- KVM_ISA_EXT_ARR(ZBC),
- KVM_ISA_EXT_ARR(ZBKB),
- KVM_ISA_EXT_ARR(ZBKC),
- KVM_ISA_EXT_ARR(ZBKX),
- KVM_ISA_EXT_ARR(ZBS),
- KVM_ISA_EXT_ARR(ZCA),
- KVM_ISA_EXT_ARR(ZCB),
- KVM_ISA_EXT_ARR(ZCD),
- KVM_ISA_EXT_ARR(ZCF),
- KVM_ISA_EXT_ARR(ZCLSD),
- KVM_ISA_EXT_ARR(ZCMOP),
- KVM_ISA_EXT_ARR(ZFA),
- KVM_ISA_EXT_ARR(ZFBFMIN),
- KVM_ISA_EXT_ARR(ZFH),
- KVM_ISA_EXT_ARR(ZFHMIN),
- KVM_ISA_EXT_ARR(ZICBOM),
- KVM_ISA_EXT_ARR(ZICBOP),
- KVM_ISA_EXT_ARR(ZICBOZ),
- KVM_ISA_EXT_ARR(ZICCRSE),
- KVM_ISA_EXT_ARR(ZICNTR),
- KVM_ISA_EXT_ARR(ZICOND),
- KVM_ISA_EXT_ARR(ZICSR),
- KVM_ISA_EXT_ARR(ZIFENCEI),
- KVM_ISA_EXT_ARR(ZIHINTNTL),
- KVM_ISA_EXT_ARR(ZIHINTPAUSE),
- KVM_ISA_EXT_ARR(ZIHPM),
- KVM_ISA_EXT_ARR(ZILSD),
- KVM_ISA_EXT_ARR(ZIMOP),
- KVM_ISA_EXT_ARR(ZKND),
- KVM_ISA_EXT_ARR(ZKNE),
- KVM_ISA_EXT_ARR(ZKNH),
- KVM_ISA_EXT_ARR(ZKR),
- KVM_ISA_EXT_ARR(ZKSED),
- KVM_ISA_EXT_ARR(ZKSH),
- KVM_ISA_EXT_ARR(ZKT),
- KVM_ISA_EXT_ARR(ZTSO),
- KVM_ISA_EXT_ARR(ZVBB),
- KVM_ISA_EXT_ARR(ZVBC),
- KVM_ISA_EXT_ARR(ZVFBFMIN),
- KVM_ISA_EXT_ARR(ZVFBFWMA),
- KVM_ISA_EXT_ARR(ZVFH),
- KVM_ISA_EXT_ARR(ZVFHMIN),
- KVM_ISA_EXT_ARR(ZVKB),
- KVM_ISA_EXT_ARR(ZVKG),
- KVM_ISA_EXT_ARR(ZVKNED),
- KVM_ISA_EXT_ARR(ZVKNHA),
- KVM_ISA_EXT_ARR(ZVKNHB),
- KVM_ISA_EXT_ARR(ZVKSED),
- KVM_ISA_EXT_ARR(ZVKSH),
- KVM_ISA_EXT_ARR(ZVKT),
-};
-
-static unsigned long kvm_riscv_vcpu_base2isa_ext(unsigned long base_ext)
-{
- unsigned long i;
-
- for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) {
- if (kvm_isa_ext_arr[i] == base_ext)
- return i;
- }
-
- return KVM_RISCV_ISA_EXT_MAX;
-}
-
-int __kvm_riscv_isa_check_host(unsigned long kvm_ext, unsigned long *base_ext)
-{
- unsigned long host_ext;
-
- if (kvm_ext >= KVM_RISCV_ISA_EXT_MAX ||
- kvm_ext >= ARRAY_SIZE(kvm_isa_ext_arr))
- return -ENOENT;
-
- switch (kvm_isa_ext_arr[kvm_ext]) {
- case RISCV_ISA_EXT_SMNPM:
- /*
- * Pointer masking effective in (H)S-mode is provided by the
- * Smnpm extension, so that extension is reported to the guest,
- * even though the CSR bits for configuring VS-mode pointer
- * masking on the host side are part of the Ssnpm extension.
- */
- host_ext = RISCV_ISA_EXT_SSNPM;
- break;
- default:
- host_ext = kvm_isa_ext_arr[kvm_ext];
- break;
- }
-
- if (!__riscv_isa_extension_available(NULL, host_ext))
- return -ENOENT;
-
- if (base_ext)
- *base_ext = kvm_isa_ext_arr[kvm_ext];
-
- return 0;
-}
-
-static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
-{
- switch (ext) {
- case KVM_RISCV_ISA_EXT_H:
- return false;
- case KVM_RISCV_ISA_EXT_SSCOFPMF:
- /* Sscofpmf depends on interrupt filtering defined in ssaia */
- return !kvm_riscv_isa_check_host(SSAIA);
- case KVM_RISCV_ISA_EXT_SVADU:
- /*
- * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero.
- * Guest OS can use Svadu only when host OS enable Svadu.
- */
- return arch_has_hw_pte_young();
- case KVM_RISCV_ISA_EXT_V:
- return riscv_v_vstate_ctrl_user_allowed();
- default:
- break;
- }
-
- return true;
-}
-
-static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
-{
- switch (ext) {
- /* Extensions which don't have any mechanism to disable */
- case KVM_RISCV_ISA_EXT_A:
- case KVM_RISCV_ISA_EXT_C:
- case KVM_RISCV_ISA_EXT_I:
- case KVM_RISCV_ISA_EXT_M:
- /* There is not architectural config bit to disable sscofpmf completely */
- case KVM_RISCV_ISA_EXT_SSCOFPMF:
- case KVM_RISCV_ISA_EXT_SSNPM:
- case KVM_RISCV_ISA_EXT_SSTC:
- case KVM_RISCV_ISA_EXT_SVINVAL:
- case KVM_RISCV_ISA_EXT_SVNAPOT:
- case KVM_RISCV_ISA_EXT_SVVPTC:
- case KVM_RISCV_ISA_EXT_ZAAMO:
- case KVM_RISCV_ISA_EXT_ZABHA:
- case KVM_RISCV_ISA_EXT_ZACAS:
- case KVM_RISCV_ISA_EXT_ZALASR:
- case KVM_RISCV_ISA_EXT_ZALRSC:
- case KVM_RISCV_ISA_EXT_ZAWRS:
- case KVM_RISCV_ISA_EXT_ZBA:
- case KVM_RISCV_ISA_EXT_ZBB:
- case KVM_RISCV_ISA_EXT_ZBC:
- case KVM_RISCV_ISA_EXT_ZBKB:
- case KVM_RISCV_ISA_EXT_ZBKC:
- case KVM_RISCV_ISA_EXT_ZBKX:
- case KVM_RISCV_ISA_EXT_ZBS:
- case KVM_RISCV_ISA_EXT_ZCA:
- case KVM_RISCV_ISA_EXT_ZCB:
- case KVM_RISCV_ISA_EXT_ZCD:
- case KVM_RISCV_ISA_EXT_ZCF:
- case KVM_RISCV_ISA_EXT_ZCMOP:
- case KVM_RISCV_ISA_EXT_ZFA:
- case KVM_RISCV_ISA_EXT_ZFBFMIN:
- case KVM_RISCV_ISA_EXT_ZFH:
- case KVM_RISCV_ISA_EXT_ZFHMIN:
- case KVM_RISCV_ISA_EXT_ZICBOP:
- case KVM_RISCV_ISA_EXT_ZICCRSE:
- case KVM_RISCV_ISA_EXT_ZICNTR:
- case KVM_RISCV_ISA_EXT_ZICOND:
- case KVM_RISCV_ISA_EXT_ZICSR:
- case KVM_RISCV_ISA_EXT_ZIFENCEI:
- case KVM_RISCV_ISA_EXT_ZIHINTNTL:
- case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
- case KVM_RISCV_ISA_EXT_ZIHPM:
- case KVM_RISCV_ISA_EXT_ZIMOP:
- case KVM_RISCV_ISA_EXT_ZKND:
- case KVM_RISCV_ISA_EXT_ZKNE:
- case KVM_RISCV_ISA_EXT_ZKNH:
- case KVM_RISCV_ISA_EXT_ZKR:
- case KVM_RISCV_ISA_EXT_ZKSED:
- case KVM_RISCV_ISA_EXT_ZKSH:
- case KVM_RISCV_ISA_EXT_ZKT:
- case KVM_RISCV_ISA_EXT_ZTSO:
- case KVM_RISCV_ISA_EXT_ZVBB:
- case KVM_RISCV_ISA_EXT_ZVBC:
- case KVM_RISCV_ISA_EXT_ZVFBFMIN:
- case KVM_RISCV_ISA_EXT_ZVFBFWMA:
- case KVM_RISCV_ISA_EXT_ZVFH:
- case KVM_RISCV_ISA_EXT_ZVFHMIN:
- case KVM_RISCV_ISA_EXT_ZVKB:
- case KVM_RISCV_ISA_EXT_ZVKG:
- case KVM_RISCV_ISA_EXT_ZVKNED:
- case KVM_RISCV_ISA_EXT_ZVKNHA:
- case KVM_RISCV_ISA_EXT_ZVKNHB:
- case KVM_RISCV_ISA_EXT_ZVKSED:
- case KVM_RISCV_ISA_EXT_ZVKSH:
- case KVM_RISCV_ISA_EXT_ZVKT:
- return false;
- /* Extensions which can be disabled using Smstateen */
- case KVM_RISCV_ISA_EXT_SSAIA:
- return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN);
- case KVM_RISCV_ISA_EXT_SVADE:
- /*
- * The henvcfg.ADUE is read-only zero if menvcfg.ADUE is zero.
- * Svade can't be disabled unless we support Svadu.
- */
- return arch_has_hw_pte_young();
- default:
- break;
- }
-
- return true;
-}
-
void kvm_riscv_vcpu_setup_isa(struct kvm_vcpu *vcpu)
{
unsigned long guest_ext, i;
- for (i = 0; i < ARRAY_SIZE(kvm_isa_ext_arr); i++) {
+ for (i = 0; i < KVM_RISCV_ISA_EXT_MAX; i++) {
if (__kvm_riscv_isa_check_host(i, &guest_ext))
continue;
- if (kvm_riscv_vcpu_isa_enable_allowed(i))
+ if (kvm_riscv_isa_enable_allowed(i))
set_bit(guest_ext, vcpu->arch.isa);
}
}
@@ -361,15 +120,15 @@ static int kvm_riscv_vcpu_set_reg_config(struct kvm_vcpu *vcpu,
if (!vcpu->arch.ran_atleast_once) {
/* Ignore the enable/disable request for certain extensions */
for (i = 0; i < RISCV_ISA_EXT_BASE; i++) {
- isa_ext = kvm_riscv_vcpu_base2isa_ext(i);
+ isa_ext = kvm_riscv_base2isa_ext(i);
if (isa_ext >= KVM_RISCV_ISA_EXT_MAX) {
reg_val &= ~BIT(i);
continue;
}
- if (!kvm_riscv_vcpu_isa_enable_allowed(isa_ext))
+ if (!kvm_riscv_isa_enable_allowed(isa_ext))
if (reg_val & BIT(i))
reg_val &= ~BIT(i);
- if (!kvm_riscv_vcpu_isa_disable_allowed(isa_ext))
+ if (!kvm_riscv_isa_disable_allowed(isa_ext))
if (!(reg_val & BIT(i)))
reg_val |= BIT(i);
}
@@ -693,10 +452,10 @@ static int riscv_vcpu_set_isa_ext_single(struct kvm_vcpu *vcpu,
* extension can be disabled
*/
if (reg_val == 1 &&
- kvm_riscv_vcpu_isa_enable_allowed(reg_num))
+ kvm_riscv_isa_enable_allowed(reg_num))
set_bit(guest_ext, vcpu->arch.isa);
else if (!reg_val &&
- kvm_riscv_vcpu_isa_disable_allowed(reg_num))
+ kvm_riscv_isa_disable_allowed(reg_num))
clear_bit(guest_ext, vcpu->arch.isa);
else
return -EINVAL;
diff --git a/arch/riscv/kvm/vcpu_pmu.c b/arch/riscv/kvm/vcpu_pmu.c
index 9759143c1785..5d37830c59b6 100644
--- a/arch/riscv/kvm/vcpu_pmu.c
+++ b/arch/riscv/kvm/vcpu_pmu.c
@@ -7,15 +7,16 @@
*/
#define pr_fmt(fmt) "riscv-kvm-pmu: " fmt
+#include <linux/bitops.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/kvm_host.h>
#include <linux/perf/riscv_pmu.h>
#include <asm/csr.h>
+#include <asm/kvm_isa.h>
#include <asm/kvm_vcpu_sbi.h>
#include <asm/kvm_vcpu_pmu.h>
#include <asm/sbi.h>
-#include <linux/bitops.h>
#define kvm_pmu_num_counters(pmu) ((pmu)->num_hw_ctrs + (pmu)->num_fw_ctrs)
#define get_event_type(x) (((x) & SBI_PMU_EVENT_IDX_TYPE_MASK) >> 16)
diff --git a/arch/riscv/kvm/vcpu_timer.c b/arch/riscv/kvm/vcpu_timer.c
index cac4f3a5f213..9817ff802821 100644
--- a/arch/riscv/kvm/vcpu_timer.c
+++ b/arch/riscv/kvm/vcpu_timer.c
@@ -12,6 +12,7 @@
#include <linux/uaccess.h>
#include <clocksource/timer-riscv.h>
#include <asm/delay.h>
+#include <asm/kvm_isa.h>
#include <asm/kvm_nacl.h>
#include <asm/kvm_vcpu_timer.h>
diff --git a/arch/riscv/kvm/vcpu_vector.c b/arch/riscv/kvm/vcpu_vector.c
index 8c7315a96b9e..a36e9e2c28df 100644
--- a/arch/riscv/kvm/vcpu_vector.c
+++ b/arch/riscv/kvm/vcpu_vector.c
@@ -12,6 +12,7 @@
#include <linux/kvm_host.h>
#include <linux/uaccess.h>
#include <asm/cpufeature.h>
+#include <asm/kvm_isa.h>
#include <asm/kvm_vcpu_vector.h>
#include <asm/vector.h>
--
2.43.0
Powered by blists - more mailing lists