]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
RISC-V: KVM: Factor-out ISA checks into separate sources
authorAnup Patel <anup.patel@oss.qualcomm.com>
Tue, 20 Jan 2026 07:59:51 +0000 (13:29 +0530)
committerAnup Patel <anup@brainfault.org>
Fri, 3 Apr 2026 12:05:01 +0000 (17:35 +0530)
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@oss.qualcomm.com>
Reviewed-by: Radim Krčmář <radim.krcmar@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260120080013.2153519-6-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
arch/riscv/include/asm/kvm_host.h
arch/riscv/include/asm/kvm_isa.h [new file with mode: 0644]
arch/riscv/kvm/Makefile
arch/riscv/kvm/aia_device.c
arch/riscv/kvm/isa.c [new file with mode: 0644]
arch/riscv/kvm/vcpu_fp.c
arch/riscv/kvm/vcpu_onereg.c
arch/riscv/kvm/vcpu_pmu.c
arch/riscv/kvm/vcpu_timer.c
arch/riscv/kvm/vcpu_vector.c

index cf8da3ec6392404caeb36c2c0996c79f392076a6..7ee47b83c80d5cce402503fc96741af1fa0b1161 100644 (file)
@@ -311,10 +311,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 (file)
index 0000000..bc4b956
--- /dev/null
@@ -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
index 3b8afb038b35c22784ca8e7da0381a29b999f1a2..07eab96189e77b437d01452ca7ed9fcdb43d03ef 100644 (file)
@@ -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
index f3010dd2030a668d41bbd19bad1995961271bb2f..3d1e81e2a36b03f991df71ba95f03d66c88bf1a9 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/irqchip/riscv-imsic.h>
 #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 (file)
index 0000000..1132d90
--- /dev/null
@@ -0,0 +1,253 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2026 Qualcomm Technologies, Inc.
+ */
+
+#include <linux/cpufeature.h>
+#include <linux/errno.h>
+#include <linux/kvm_host.h>
+#include <linux/nospec.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 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;
+
+       kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr));
+       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;
+}
+
+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;
+}
index 2faa0cd37b69333ef4090b43eb303d495df72e77..6ad6df26a2fd428c462f304abbd9092e02b50e38 100644 (file)
@@ -13,6 +13,7 @@
 #include <linux/nospec.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)
index a92351b78bf8f4b8ede916d44721fb57b2594465..bb920e8923c930e55f885085965669233cc28a6e 100644 (file)
 #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;
-
-       kvm_ext = array_index_nospec(kvm_ext, ARRAY_SIZE(kvm_isa_ext_arr));
-       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);
        }
 }
@@ -363,15 +121,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);
                        }
@@ -715,10 +473,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;
index a8ca1e65734ad319cb1f7c4d98c6289b0486432e..18ef07b3f13a4bc2d208e78a69f811e19b4d8b9e 100644 (file)
@@ -7,16 +7,17 @@
  */
 
 #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/nospec.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)
index cac4f3a5f2137af7f6349282d072c4204263c614..9817ff8028216095c77c5c23b6f84f705beb7927 100644 (file)
@@ -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>
 
index 42ffb489c44796746e6953b817abb5c2cd10a4f3..62d2fb77bb9b931681d5901e37befd974a271fbc 100644 (file)
@@ -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>