RISC-V: KVM: Enable Smstateen accesses
authorMayuresh Chitale <mchitale@ventanamicro.com>
Wed, 13 Sep 2023 16:39:02 +0000 (22:09 +0530)
committerAnup Patel <anup@brainfault.org>
Thu, 12 Oct 2023 13:14:07 +0000 (18:44 +0530)
Configure hstateen0 register so that the AIA state and envcfg are
accessible to the vcpus. This includes registers such as siselect,
sireg, siph, sieh and all the IMISC registers.

Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Signed-off-by: Anup Patel <anup@brainfault.org>
arch/riscv/include/asm/csr.h
arch/riscv/include/asm/kvm_host.h
arch/riscv/include/uapi/asm/kvm.h
arch/riscv/kvm/vcpu.c
arch/riscv/kvm/vcpu_onereg.c

index 777cb8299551ca3a33147471f032d319cdbcfb35..5717004d80fb32e3eea91cef327ba4f40a4e1b31 100644 (file)
 #define ENVCFG_CBIE_INV                        _AC(0x3, UL)
 #define ENVCFG_FIOM                    _AC(0x1, UL)
 
+/* Smstateen bits */
+#define SMSTATEEN0_AIA_IMSIC_SHIFT     58
+#define SMSTATEEN0_AIA_IMSIC           (_ULL(1) << SMSTATEEN0_AIA_IMSIC_SHIFT)
+#define SMSTATEEN0_AIA_SHIFT           59
+#define SMSTATEEN0_AIA                 (_ULL(1) << SMSTATEEN0_AIA_SHIFT)
+#define SMSTATEEN0_AIA_ISEL_SHIFT      60
+#define SMSTATEEN0_AIA_ISEL            (_ULL(1) << SMSTATEEN0_AIA_ISEL_SHIFT)
+#define SMSTATEEN0_HSENVCFG_SHIFT      62
+#define SMSTATEEN0_HSENVCFG            (_ULL(1) << SMSTATEEN0_HSENVCFG_SHIFT)
+#define SMSTATEEN0_SSTATEEN0_SHIFT     63
+#define SMSTATEEN0_SSTATEEN0           (_ULL(1) << SMSTATEEN0_SSTATEEN0_SHIFT)
+
 /* symbolic CSR names: */
 #define CSR_CYCLE              0xc00
 #define CSR_TIME               0xc01
 #define CSR_VSIEH              0x214
 #define CSR_VSIPH              0x254
 
+/* Hypervisor stateen CSRs */
+#define CSR_HSTATEEN0          0x60c
+#define CSR_HSTATEEN0H         0x61c
+
 #define CSR_MSTATUS            0x300
 #define CSR_MISA               0x301
 #define CSR_MIDELEG            0x303
index 4f787dce4da1caa721832fef77e96a45127aeb7c..50f3d6393d501b22689903a77a537c635cfd46d6 100644 (file)
@@ -166,6 +166,7 @@ struct kvm_vcpu_csr {
 
 struct kvm_vcpu_config {
        u64 henvcfg;
+       u64 hstateen0;
 };
 
 struct kvm_vcpu_arch {
index 992c5e407104958532d7ba930d50447ebe56fa25..12c17656c156d9dbfeefb25b179d8790d07d4315 100644 (file)
@@ -131,6 +131,7 @@ enum KVM_RISCV_ISA_EXT_ID {
        KVM_RISCV_ISA_EXT_ZICSR,
        KVM_RISCV_ISA_EXT_ZIFENCEI,
        KVM_RISCV_ISA_EXT_ZIHPM,
+       KVM_RISCV_ISA_EXT_SMSTATEEN,
        KVM_RISCV_ISA_EXT_MAX,
 };
 
index c5eccc798e70c35dab90ce313cddffcd02346f4b..417e257e05e1b57df4dde58fa815126920f20a56 100644 (file)
@@ -487,6 +487,16 @@ static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu)
 
        if (riscv_isa_extension_available(isa, ZICBOZ))
                cfg->henvcfg |= ENVCFG_CBZE;
+
+       if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) {
+               cfg->hstateen0 |= SMSTATEEN0_HSENVCFG;
+               if (riscv_isa_extension_available(isa, SSAIA))
+                       cfg->hstateen0 |= SMSTATEEN0_AIA_IMSIC |
+                                         SMSTATEEN0_AIA |
+                                         SMSTATEEN0_AIA_ISEL;
+               if (riscv_isa_extension_available(isa, SMSTATEEN))
+                       cfg->hstateen0 |= SMSTATEEN0_SSTATEEN0;
+       }
 }
 
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
@@ -506,6 +516,11 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        csr_write(CSR_HENVCFG, cfg->henvcfg);
        if (IS_ENABLED(CONFIG_32BIT))
                csr_write(CSR_HENVCFGH, cfg->henvcfg >> 32);
+       if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) {
+               csr_write(CSR_HSTATEEN0, cfg->hstateen0);
+               if (IS_ENABLED(CONFIG_32BIT))
+                       csr_write(CSR_HSTATEEN0H, cfg->hstateen0 >> 32);
+       }
 
        kvm_riscv_gstage_update_hgatp(vcpu);
 
index b7e0e03c69b1e50c7fa937ca513129259678aad3..9086e3abb52f8731a0c41c5d67f177fc936ff50b 100644 (file)
@@ -34,6 +34,7 @@ static const unsigned long kvm_isa_ext_arr[] = {
        [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(SMSTATEEN),
        KVM_ISA_EXT_ARR(SSAIA),
        KVM_ISA_EXT_ARR(SSTC),
        KVM_ISA_EXT_ARR(SVINVAL),
@@ -80,11 +81,11 @@ static bool kvm_riscv_vcpu_isa_enable_allowed(unsigned long ext)
 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:
-       case KVM_RISCV_ISA_EXT_SSAIA:
        case KVM_RISCV_ISA_EXT_SSTC:
        case KVM_RISCV_ISA_EXT_SVINVAL:
        case KVM_RISCV_ISA_EXT_SVNAPOT:
@@ -97,6 +98,9 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext)
        case KVM_RISCV_ISA_EXT_ZIHINTPAUSE:
        case KVM_RISCV_ISA_EXT_ZIHPM:
                return false;
+       /* Extensions which can be disabled using Smstateen */
+       case KVM_RISCV_ISA_EXT_SSAIA:
+               return riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN);
        default:
                break;
        }