From 9dbaf381008dfa2fad6225633004f7adb1bac252 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:08:59 +0530 Subject: RISC-V: Detect Smstateen extension Extend the ISA string parsing to detect the Smstateen extension. If the extension is enabled then access to certain 'state' such as AIA CSRs in VS mode is controlled by *stateen0 registers. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpufeature.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index b7b58258f6c7..0f520f7d058a 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -58,6 +58,7 @@ #define RISCV_ISA_EXT_ZICSR 40 #define RISCV_ISA_EXT_ZIFENCEI 41 #define RISCV_ISA_EXT_ZIHPM 42 +#define RISCV_ISA_EXT_SMSTATEEN 43 #define RISCV_ISA_EXT_MAX 64 diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 1cfbba65d11a..3755a8c2a9de 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -175,6 +175,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(zbb, RISCV_ISA_EXT_ZBB), __RISCV_ISA_EXT_DATA(zbs, RISCV_ISA_EXT_ZBS), __RISCV_ISA_EXT_DATA(smaia, RISCV_ISA_EXT_SMAIA), + __RISCV_ISA_EXT_DATA(smstateen, RISCV_ISA_EXT_SMSTATEEN), __RISCV_ISA_EXT_DATA(ssaia, RISCV_ISA_EXT_SSAIA), __RISCV_ISA_EXT_DATA(sscofpmf, RISCV_ISA_EXT_SSCOFPMF), __RISCV_ISA_EXT_DATA(sstc, RISCV_ISA_EXT_SSTC), -- cgit From a4f5f39849f39f62f5d4e88cbb600f95f927003d Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:00 +0530 Subject: dt-bindings: riscv: Add smstateen entry Add an entry for the Smstateen extension to the riscv,isa-extensions property. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley Signed-off-by: Anup Patel --- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml index cc1f546fdbdc..36ff6749fbba 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -128,6 +128,12 @@ properties: changes to interrupts as frozen at commit ccbddab ("Merge pull request #42 from riscv/jhauser-2023-RC4") of riscv-aia. + - const: smstateen + description: | + The standard Smstateen extension for controlling access to CSRs + added by other RISC-V extensions in H/S/VS/U/VU modes and as + ratified at commit a28bfae (Ratified (#7)) of riscv-state-enable. + - const: ssaia description: | The standard Ssaia supervisor-level extension for the advanced -- cgit From 662a601aa355c6917ed2bc1c4e316a4c0ee206ed Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Sep 2023 14:09:44 +0530 Subject: RISC-V: Detect Zicond from ISA string The RISC-V integer conditional (Zicond) operation extension defines standard conditional arithmetic and conditional-select/move operations which are inspired from the XVentanaCondOps extension. In fact, QEMU RISC-V also has support for emulating Zicond extension. Let us detect Zicond extension from ISA string available through DT or ACPI. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley Acked-by: Palmer Dabbelt Signed-off-by: Anup Patel --- arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpufeature.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/riscv/include/asm/hwcap.h b/arch/riscv/include/asm/hwcap.h index 0f520f7d058a..6fc51c1b34cf 100644 --- a/arch/riscv/include/asm/hwcap.h +++ b/arch/riscv/include/asm/hwcap.h @@ -59,6 +59,7 @@ #define RISCV_ISA_EXT_ZIFENCEI 41 #define RISCV_ISA_EXT_ZIHPM 42 #define RISCV_ISA_EXT_SMSTATEEN 43 +#define RISCV_ISA_EXT_ZICOND 44 #define RISCV_ISA_EXT_MAX 64 diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c index 3755a8c2a9de..e3803822ab5a 100644 --- a/arch/riscv/kernel/cpufeature.c +++ b/arch/riscv/kernel/cpufeature.c @@ -167,6 +167,7 @@ const struct riscv_isa_ext_data riscv_isa_ext[] = { __RISCV_ISA_EXT_DATA(zicbom, RISCV_ISA_EXT_ZICBOM), __RISCV_ISA_EXT_DATA(zicboz, RISCV_ISA_EXT_ZICBOZ), __RISCV_ISA_EXT_DATA(zicntr, RISCV_ISA_EXT_ZICNTR), + __RISCV_ISA_EXT_DATA(zicond, RISCV_ISA_EXT_ZICOND), __RISCV_ISA_EXT_DATA(zicsr, RISCV_ISA_EXT_ZICSR), __RISCV_ISA_EXT_DATA(zifencei, RISCV_ISA_EXT_ZIFENCEI), __RISCV_ISA_EXT_DATA(zihintpause, RISCV_ISA_EXT_ZIHINTPAUSE), -- cgit From 00c6f39c8247b0a5ddca4586d43aec1af7cbccb6 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 25 Sep 2023 14:46:25 +0530 Subject: dt-bindings: riscv: Add Zicond extension entry Add an entry for the Zicond extension to the riscv,isa-extensions property. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Reviewed-by: Conor Dooley Signed-off-by: Anup Patel --- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/devicetree/bindings/riscv/extensions.yaml b/Documentation/devicetree/bindings/riscv/extensions.yaml index 36ff6749fbba..c91ab0e46648 100644 --- a/Documentation/devicetree/bindings/riscv/extensions.yaml +++ b/Documentation/devicetree/bindings/riscv/extensions.yaml @@ -218,6 +218,12 @@ properties: ratified in the 20191213 version of the unprivileged ISA specification. + - const: zicond + description: + The standard Zicond extension for conditional arithmetic and + conditional-select/move operations as ratified in commit 95cf1f9 + ("Add changes requested by Ved during signoff") of riscv-zicond. + - const: zicsr description: | The standard Zicsr extension for control and status register -- cgit From fe0bab701e3b71a1d2db123c05b4f5c33098cc96 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:01 +0530 Subject: RISC-V: KVM: Add kvm_vcpu_config Add a placeholder for all registers such as henvcfg, hstateen etc which have 'static' configurations depending on extensions supported by the guest. The values are derived once and are then subsequently written to the corresponding CSRs while switching to the vcpu. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/kvm_host.h | 7 +++++++ arch/riscv/kvm/vcpu.c | 27 ++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 1ebf20dfbaa6..4f787dce4da1 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -164,6 +164,10 @@ struct kvm_vcpu_csr { unsigned long scounteren; }; +struct kvm_vcpu_config { + u64 henvcfg; +}; + struct kvm_vcpu_arch { /* VCPU ran at least once */ bool ran_atleast_once; @@ -244,6 +248,9 @@ struct kvm_vcpu_arch { /* Performance monitoring context */ struct kvm_pmu pmu_context; + + /* 'static' configurations which are set only once */ + struct kvm_vcpu_config cfg; }; static inline void kvm_arch_sync_events(struct kvm *kvm) {} diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 82229db1ce73..c5eccc798e70 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -471,31 +471,28 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu, return -EINVAL; } -static void kvm_riscv_vcpu_update_config(const unsigned long *isa) +static void kvm_riscv_vcpu_setup_config(struct kvm_vcpu *vcpu) { - u64 henvcfg = 0; + const unsigned long *isa = vcpu->arch.isa; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; if (riscv_isa_extension_available(isa, SVPBMT)) - henvcfg |= ENVCFG_PBMTE; + cfg->henvcfg |= ENVCFG_PBMTE; if (riscv_isa_extension_available(isa, SSTC)) - henvcfg |= ENVCFG_STCE; + cfg->henvcfg |= ENVCFG_STCE; if (riscv_isa_extension_available(isa, ZICBOM)) - henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE); + cfg->henvcfg |= (ENVCFG_CBIE | ENVCFG_CBCFE); if (riscv_isa_extension_available(isa, ZICBOZ)) - henvcfg |= ENVCFG_CBZE; - - csr_write(CSR_HENVCFG, henvcfg); -#ifdef CONFIG_32BIT - csr_write(CSR_HENVCFGH, henvcfg >> 32); -#endif + cfg->henvcfg |= ENVCFG_CBZE; } void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) { struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; csr_write(CSR_VSSTATUS, csr->vsstatus); csr_write(CSR_VSIE, csr->vsie); @@ -506,8 +503,9 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) csr_write(CSR_VSTVAL, csr->vstval); csr_write(CSR_HVIP, csr->hvip); csr_write(CSR_VSATP, csr->vsatp); - - kvm_riscv_vcpu_update_config(vcpu->arch.isa); + csr_write(CSR_HENVCFG, cfg->henvcfg); + if (IS_ENABLED(CONFIG_32BIT)) + csr_write(CSR_HENVCFGH, cfg->henvcfg >> 32); kvm_riscv_gstage_update_hgatp(vcpu); @@ -627,6 +625,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) struct kvm_cpu_trap trap; struct kvm_run *run = vcpu->run; + if (!vcpu->arch.ran_atleast_once) + kvm_riscv_vcpu_setup_config(vcpu); + /* Mark this VCPU ran at least once */ vcpu->arch.ran_atleast_once = true; -- cgit From d21b5d342fc12eb0a0f812864aa58aa9bb2c0599 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:02 +0530 Subject: RISC-V: KVM: Enable Smstateen accesses 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 Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/csr.h | 16 ++++++++++++++++ arch/riscv/include/asm/kvm_host.h | 1 + arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu.c | 15 +++++++++++++++ arch/riscv/kvm/vcpu_onereg.c | 6 +++++- 5 files changed, 38 insertions(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 777cb8299551..5717004d80fb 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -203,6 +203,18 @@ #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 @@ -349,6 +361,10 @@ #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 diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 4f787dce4da1..50f3d6393d50 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -166,6 +166,7 @@ struct kvm_vcpu_csr { struct kvm_vcpu_config { u64 henvcfg; + u64 hstateen0; }; struct kvm_vcpu_arch { diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 992c5e407104..12c17656c156 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -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, }; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index c5eccc798e70..417e257e05e1 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -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); diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index b7e0e03c69b1..9086e3abb52f 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -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; } -- cgit From db3c01c7a3081c6a6a50570e48bdbea509ba30e4 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:03 +0530 Subject: RISCV: KVM: Add senvcfg context save/restore Add senvcfg context save/restore for guest VCPUs and also add it to the ONE_REG interface to allow its access from user space. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/csr.h | 1 + arch/riscv/include/asm/kvm_host.h | 2 ++ arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu.c | 16 ++++++++++++++++ 4 files changed, 20 insertions(+) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 5717004d80fb..65b871dbf7e8 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -287,6 +287,7 @@ #define CSR_SIE 0x104 #define CSR_STVEC 0x105 #define CSR_SCOUNTEREN 0x106 +#define CSR_SENVCFG 0x10a #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SCAUSE 0x142 diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 50f3d6393d50..1980be6a3e79 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -162,6 +162,7 @@ struct kvm_vcpu_csr { unsigned long hvip; unsigned long vsatp; unsigned long scounteren; + unsigned long senvcfg; }; struct kvm_vcpu_config { @@ -188,6 +189,7 @@ struct kvm_vcpu_arch { unsigned long host_sscratch; unsigned long host_stvec; unsigned long host_scounteren; + unsigned long host_senvcfg; /* CPU context of Host */ struct kvm_cpu_context host_context; diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 12c17656c156..c161791f55cb 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -80,6 +80,7 @@ struct kvm_riscv_csr { unsigned long sip; unsigned long satp; unsigned long scounteren; + unsigned long senvcfg; }; /* AIA CSR registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 417e257e05e1..3013ae30c3af 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -619,6 +619,20 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_aia_update_hvip(vcpu); } +static __always_inline void kvm_riscv_vcpu_swap_in_guest_state(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + + vcpu->arch.host_senvcfg = csr_swap(CSR_SENVCFG, csr->senvcfg); +} + +static __always_inline void kvm_riscv_vcpu_swap_in_host_state(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + + csr->senvcfg = csr_swap(CSR_SENVCFG, vcpu->arch.host_senvcfg); +} + /* * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while * the vCPU is running. @@ -628,10 +642,12 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) */ static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu) { + kvm_riscv_vcpu_swap_in_guest_state(vcpu); guest_state_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); vcpu->arch.last_exit_cpu = vcpu->cpu; guest_state_exit_irqoff(); + kvm_riscv_vcpu_swap_in_host_state(vcpu); } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) -- cgit From 81f0f314fec92a69d6c4951b9d9db21d37419669 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:04 +0530 Subject: RISCV: KVM: Add sstateen0 context save/restore Define sstateen0 and add sstateen0 save/restore for guest VCPUs. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/csr.h | 1 + arch/riscv/include/asm/kvm_host.h | 8 ++++++++ arch/riscv/kvm/vcpu.c | 12 ++++++++++++ 3 files changed, 21 insertions(+) diff --git a/arch/riscv/include/asm/csr.h b/arch/riscv/include/asm/csr.h index 65b871dbf7e8..306a19a5509c 100644 --- a/arch/riscv/include/asm/csr.h +++ b/arch/riscv/include/asm/csr.h @@ -288,6 +288,7 @@ #define CSR_STVEC 0x105 #define CSR_SCOUNTEREN 0x106 #define CSR_SENVCFG 0x10a +#define CSR_SSTATEEN0 0x10c #define CSR_SSCRATCH 0x140 #define CSR_SEPC 0x141 #define CSR_SCAUSE 0x142 diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index 1980be6a3e79..0eefd9c991ae 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -170,6 +170,10 @@ struct kvm_vcpu_config { u64 hstateen0; }; +struct kvm_vcpu_smstateen_csr { + unsigned long sstateen0; +}; + struct kvm_vcpu_arch { /* VCPU ran at least once */ bool ran_atleast_once; @@ -190,6 +194,7 @@ struct kvm_vcpu_arch { unsigned long host_stvec; unsigned long host_scounteren; unsigned long host_senvcfg; + unsigned long host_sstateen0; /* CPU context of Host */ struct kvm_cpu_context host_context; @@ -200,6 +205,9 @@ struct kvm_vcpu_arch { /* CPU CSR context of Guest VCPU */ struct kvm_vcpu_csr guest_csr; + /* CPU Smstateen CSR context of Guest VCPU */ + struct kvm_vcpu_smstateen_csr smstateen_csr; + /* CPU context upon Guest VCPU reset */ struct kvm_cpu_context guest_reset_context; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 3013ae30c3af..c061a1c5fe98 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -621,16 +621,28 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) static __always_inline void kvm_riscv_vcpu_swap_in_guest_state(struct kvm_vcpu *vcpu) { + struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr; struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; vcpu->arch.host_senvcfg = csr_swap(CSR_SENVCFG, csr->senvcfg); + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) && + (cfg->hstateen0 & SMSTATEEN0_SSTATEEN0)) + vcpu->arch.host_sstateen0 = csr_swap(CSR_SSTATEEN0, + smcsr->sstateen0); } static __always_inline void kvm_riscv_vcpu_swap_in_host_state(struct kvm_vcpu *vcpu) { + struct kvm_vcpu_smstateen_csr *smcsr = &vcpu->arch.smstateen_csr; struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + struct kvm_vcpu_config *cfg = &vcpu->arch.cfg; csr->senvcfg = csr_swap(CSR_SENVCFG, vcpu->arch.host_senvcfg); + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN) && + (cfg->hstateen0 & SMSTATEEN0_SSTATEEN0)) + smcsr->sstateen0 = csr_swap(CSR_SSTATEEN0, + vcpu->arch.host_sstateen0); } /* -- cgit From c04913f2b54ee86be34d1a1e9df7b7876b12b8c0 Mon Sep 17 00:00:00 2001 From: Mayuresh Chitale Date: Wed, 13 Sep 2023 22:09:05 +0530 Subject: RISCV: KVM: Add sstateen0 to ONE_REG Add support for sstateen0 CSR to the ONE_REG interface to allow its access from user space. Signed-off-by: Mayuresh Chitale Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/uapi/asm/kvm.h | 8 +++++ arch/riscv/kvm/vcpu_onereg.c | 64 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 70 insertions(+), 2 deletions(-) diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index c161791f55cb..b1baf6f096a3 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -94,6 +94,11 @@ struct kvm_riscv_aia_csr { unsigned long iprio2h; }; +/* Smstateen CSR for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ +struct kvm_riscv_smstateen_csr { + unsigned long sstateen0; +}; + /* TIMER registers for KVM_GET_ONE_REG and KVM_SET_ONE_REG */ struct kvm_riscv_timer { __u64 frequency; @@ -180,10 +185,13 @@ enum KVM_RISCV_SBI_EXT_ID { #define KVM_REG_RISCV_CSR (0x03 << KVM_REG_RISCV_TYPE_SHIFT) #define KVM_REG_RISCV_CSR_GENERAL (0x0 << KVM_REG_RISCV_SUBTYPE_SHIFT) #define KVM_REG_RISCV_CSR_AIA (0x1 << KVM_REG_RISCV_SUBTYPE_SHIFT) +#define KVM_REG_RISCV_CSR_SMSTATEEN (0x2 << KVM_REG_RISCV_SUBTYPE_SHIFT) #define KVM_REG_RISCV_CSR_REG(name) \ (offsetof(struct kvm_riscv_csr, name) / sizeof(unsigned long)) #define KVM_REG_RISCV_CSR_AIA_REG(name) \ (offsetof(struct kvm_riscv_aia_csr, name) / sizeof(unsigned long)) +#define KVM_REG_RISCV_CSR_SMSTATEEN_REG(name) \ + (offsetof(struct kvm_riscv_smstateen_csr, name) / sizeof(unsigned long)) /* Timer registers are mapped as type 4 */ #define KVM_REG_RISCV_TIMER (0x04 << KVM_REG_RISCV_TYPE_SHIFT) diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index 9086e3abb52f..388599fcf684 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -382,6 +382,34 @@ static int kvm_riscv_vcpu_general_set_csr(struct kvm_vcpu *vcpu, return 0; } +static inline int kvm_riscv_vcpu_smstateen_set_csr(struct kvm_vcpu *vcpu, + unsigned long reg_num, + unsigned long reg_val) +{ + struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + + if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long)) + return -EINVAL; + + ((unsigned long *)csr)[reg_num] = reg_val; + return 0; +} + +static int kvm_riscv_vcpu_smstateen_get_csr(struct kvm_vcpu *vcpu, + unsigned long reg_num, + unsigned long *out_val) +{ + struct kvm_vcpu_smstateen_csr *csr = &vcpu->arch.smstateen_csr; + + if (reg_num >= sizeof(struct kvm_riscv_smstateen_csr) / + sizeof(unsigned long)) + return -EINVAL; + + *out_val = ((unsigned long *)csr)[reg_num]; + return 0; +} + static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) { @@ -405,6 +433,12 @@ static int kvm_riscv_vcpu_get_reg_csr(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_CSR_AIA: rc = kvm_riscv_vcpu_aia_get_csr(vcpu, reg_num, ®_val); break; + case KVM_REG_RISCV_CSR_SMSTATEEN: + rc = -EINVAL; + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) + rc = kvm_riscv_vcpu_smstateen_get_csr(vcpu, reg_num, + ®_val); + break; default: rc = -ENOENT; break; @@ -444,6 +478,12 @@ static int kvm_riscv_vcpu_set_reg_csr(struct kvm_vcpu *vcpu, case KVM_REG_RISCV_CSR_AIA: rc = kvm_riscv_vcpu_aia_set_csr(vcpu, reg_num, reg_val); break; + case KVM_REG_RISCV_CSR_SMSTATEEN: + rc = -EINVAL; + if (riscv_has_extension_unlikely(RISCV_ISA_EXT_SMSTATEEN)) + rc = kvm_riscv_vcpu_smstateen_set_csr(vcpu, reg_num, + reg_val); +break; default: rc = -ENOENT; break; @@ -700,6 +740,8 @@ static inline unsigned long num_csr_regs(const struct kvm_vcpu *vcpu) if (riscv_isa_extension_available(vcpu->arch.isa, SSAIA)) n += sizeof(struct kvm_riscv_aia_csr) / sizeof(unsigned long); + if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) + n += sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long); return n; } @@ -708,7 +750,7 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu, u64 __user *uindices) { int n1 = sizeof(struct kvm_riscv_csr) / sizeof(unsigned long); - int n2 = 0; + int n2 = 0, n3 = 0; /* copy general csr regs */ for (int i = 0; i < n1; i++) { @@ -742,7 +784,25 @@ static int copy_csr_reg_indices(const struct kvm_vcpu *vcpu, } } - return n1 + n2; + /* copy Smstateen csr regs */ + if (riscv_isa_extension_available(vcpu->arch.isa, SMSTATEEN)) { + n3 = sizeof(struct kvm_riscv_smstateen_csr) / sizeof(unsigned long); + + for (int i = 0; i < n3; i++) { + u64 size = IS_ENABLED(CONFIG_32BIT) ? + KVM_REG_SIZE_U32 : KVM_REG_SIZE_U64; + u64 reg = KVM_REG_RISCV | size | KVM_REG_RISCV_CSR | + KVM_REG_RISCV_CSR_SMSTATEEN | i; + + if (uindices) { + if (put_user(reg, uindices)) + return -EFAULT; + uindices++; + } + } + } + + return n1 + n2 + n3; } static inline unsigned long num_timer_regs(void) -- cgit From 26c7d6d8a5a2ce9705e89d10683f3d41ed68de5c Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 17 Aug 2023 18:23:45 +0200 Subject: MAINTAINERS: RISC-V: KVM: Add another kselftests path With the introduction of the get-reg-list test for riscv, another directory has been added that should be tracked by riscv kvm maintainers. Signed-off-by: Andrew Jones Reviewed-by: Haibo Xu Signed-off-by: Anup Patel --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 6c4cce45a09d..0de22d536c36 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -11556,6 +11556,7 @@ F: arch/riscv/include/asm/kvm* F: arch/riscv/include/uapi/asm/kvm* F: arch/riscv/kvm/ F: tools/testing/selftests/kvm/*/riscv/ +F: tools/testing/selftests/kvm/riscv/ KERNEL VIRTUAL MACHINE for s390 (KVM/s390) M: Christian Borntraeger -- cgit From 6a53a5fbc8f494e69922e13491f7077ce010ec28 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Thu, 17 Aug 2023 18:23:46 +0200 Subject: KVM: selftests: Add array order helpers to riscv get-reg-list Add a couple macros to use when filling arrays in order to ensure the elements are placed in the right order, regardless of the order we prefer to read them. And immediately apply the new macro to resorting the ISA extension lists alphabetically. Signed-off-by: Andrew Jones Reviewed-by: Haibo Xu Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 86 +++++++++++++----------- 1 file changed, 47 insertions(+), 39 deletions(-) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 9f99ea42f45f..a61b706a8778 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -25,6 +25,8 @@ bool filter_reg(__u64 reg) * the visibility of the ISA_EXT register itself. * * Based on above, we should filter-out all ISA_EXT registers. + * + * Note: The below list is alphabetically sorted. */ case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_A: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_C: @@ -33,21 +35,21 @@ bool filter_reg(__u64 reg) case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_H: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_I: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_M: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVPBMT: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSTC: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVINVAL: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOM: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOZ: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA: - case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVNAPOT: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVPBMT: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBA: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBB: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZBS: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOM: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOZ: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICSR: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIFENCEI: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHPM: return true; /* AIA registers are always available when Ssaia can't be disabled */ @@ -311,35 +313,38 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id) return NULL; } +#define KVM_ISA_EXT_ARR(ext) \ +[KVM_RISCV_ISA_EXT_##ext] = "KVM_RISCV_ISA_EXT_" #ext + static const char *isa_ext_id_to_str(__u64 id) { /* reg_off is the offset into unsigned long kvm_isa_ext_arr[] */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_ISA_EXT); static const char * const kvm_isa_ext_reg_name[] = { - "KVM_RISCV_ISA_EXT_A", - "KVM_RISCV_ISA_EXT_C", - "KVM_RISCV_ISA_EXT_D", - "KVM_RISCV_ISA_EXT_F", - "KVM_RISCV_ISA_EXT_H", - "KVM_RISCV_ISA_EXT_I", - "KVM_RISCV_ISA_EXT_M", - "KVM_RISCV_ISA_EXT_SVPBMT", - "KVM_RISCV_ISA_EXT_SSTC", - "KVM_RISCV_ISA_EXT_SVINVAL", - "KVM_RISCV_ISA_EXT_ZIHINTPAUSE", - "KVM_RISCV_ISA_EXT_ZICBOM", - "KVM_RISCV_ISA_EXT_ZICBOZ", - "KVM_RISCV_ISA_EXT_ZBB", - "KVM_RISCV_ISA_EXT_SSAIA", - "KVM_RISCV_ISA_EXT_V", - "KVM_RISCV_ISA_EXT_SVNAPOT", - "KVM_RISCV_ISA_EXT_ZBA", - "KVM_RISCV_ISA_EXT_ZBS", - "KVM_RISCV_ISA_EXT_ZICNTR", - "KVM_RISCV_ISA_EXT_ZICSR", - "KVM_RISCV_ISA_EXT_ZIFENCEI", - "KVM_RISCV_ISA_EXT_ZIHPM", + KVM_ISA_EXT_ARR(A), + KVM_ISA_EXT_ARR(C), + KVM_ISA_EXT_ARR(D), + KVM_ISA_EXT_ARR(F), + KVM_ISA_EXT_ARR(H), + KVM_ISA_EXT_ARR(I), + KVM_ISA_EXT_ARR(M), + KVM_ISA_EXT_ARR(V), + KVM_ISA_EXT_ARR(SSAIA), + KVM_ISA_EXT_ARR(SSTC), + KVM_ISA_EXT_ARR(SVINVAL), + KVM_ISA_EXT_ARR(SVNAPOT), + KVM_ISA_EXT_ARR(SVPBMT), + KVM_ISA_EXT_ARR(ZBA), + KVM_ISA_EXT_ARR(ZBB), + KVM_ISA_EXT_ARR(ZBS), + KVM_ISA_EXT_ARR(ZICBOM), + KVM_ISA_EXT_ARR(ZICBOZ), + KVM_ISA_EXT_ARR(ZICNTR), + KVM_ISA_EXT_ARR(ZICSR), + KVM_ISA_EXT_ARR(ZIFENCEI), + KVM_ISA_EXT_ARR(ZIHINTPAUSE), + KVM_ISA_EXT_ARR(ZIHPM), }; if (reg_off >= ARRAY_SIZE(kvm_isa_ext_reg_name)) { @@ -353,19 +358,22 @@ static const char *isa_ext_id_to_str(__u64 id) return kvm_isa_ext_reg_name[reg_off]; } +#define KVM_SBI_EXT_ARR(ext) \ +[ext] = "KVM_REG_RISCV_SBI_SINGLE | " #ext + static const char *sbi_ext_single_id_to_str(__u64 reg_off) { /* reg_off is KVM_RISCV_SBI_EXT_ID */ static const char * const kvm_sbi_ext_reg_name[] = { - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_V01", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_TIME", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_IPI", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_RFENCE", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_SRST", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_HSM", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL", - "KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR", + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_V01), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_TIME), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_IPI), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_RFENCE), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_SRST), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_HSM), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR), }; if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) { -- cgit From df68f4d8cb496ea31fa42cf2620366571c05376b Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Sep 2023 17:51:10 +0530 Subject: RISC-V: KVM: Allow Zicond extension for Guest/VM We extend the KVM ISA extension ONE_REG interface to allow KVM user space to detect and enable Zicond extension for Guest/VM. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu_onereg.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index b1baf6f096a3..917d8cc2489e 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -138,6 +138,7 @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZIFENCEI, KVM_RISCV_ISA_EXT_ZIHPM, KVM_RISCV_ISA_EXT_SMSTATEEN, + KVM_RISCV_ISA_EXT_ZICOND, KVM_RISCV_ISA_EXT_MAX, }; diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index 388599fcf684..c6ebce6126b5 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -46,6 +46,7 @@ static const unsigned long kvm_isa_ext_arr[] = { KVM_ISA_EXT_ARR(ZICBOM), KVM_ISA_EXT_ARR(ZICBOZ), KVM_ISA_EXT_ARR(ZICNTR), + KVM_ISA_EXT_ARR(ZICOND), KVM_ISA_EXT_ARR(ZICSR), KVM_ISA_EXT_ARR(ZIFENCEI), KVM_ISA_EXT_ARR(ZIHINTPAUSE), @@ -93,6 +94,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) case KVM_RISCV_ISA_EXT_ZBB: case KVM_RISCV_ISA_EXT_ZBS: 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_ZIHINTPAUSE: -- cgit From 4d554e0226e6568c7b0b75418e7a24fefedbcefb Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Sep 2023 21:25:27 +0530 Subject: KVM: riscv: selftests: Add senvcfg register to get-reg-list test We have a new senvcfg register in the general CSR ONE_REG interface so let us add it to get-reg-list test. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index a61b706a8778..6cec0ef75cc7 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -211,6 +211,8 @@ static const char *general_csr_id_to_str(__u64 reg_off) return RISCV_CSR_GENERAL(satp); case KVM_REG_RISCV_CSR_REG(scounteren): return RISCV_CSR_GENERAL(scounteren); + case KVM_REG_RISCV_CSR_REG(senvcfg): + return RISCV_CSR_GENERAL(senvcfg); } TEST_FAIL("Unknown general csr reg: 0x%llx", reg_off); @@ -540,6 +542,7 @@ static __u64 base_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(sip), KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(satp), KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(scounteren), + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(senvcfg), KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(frequency), KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(time), KVM_REG_RISCV | KVM_REG_SIZE_U64 | KVM_REG_RISCV_TIMER | KVM_REG_RISCV_TIMER_REG(compare), -- cgit From e1a8db0c9a0e7125c8e142c9eed7041ea37031d3 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Sep 2023 21:52:12 +0530 Subject: KVM: riscv: selftests: Add smstateen registers to get-reg-list test We have a new smstateen registers as separate sub-type of CSR ONE_REG interface so let us add these registers to get-reg-list test. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 34 ++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 6cec0ef75cc7..625118d53b74 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -36,6 +36,7 @@ bool filter_reg(__u64 reg) case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_I: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_M: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_V: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SMSTATEEN: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSTC: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SVINVAL: @@ -186,6 +187,8 @@ static const char *core_id_to_str(const char *prefix, __u64 id) "KVM_REG_RISCV_CSR_GENERAL | KVM_REG_RISCV_CSR_REG(" #csr ")" #define RISCV_CSR_AIA(csr) \ "KVM_REG_RISCV_CSR_AIA | KVM_REG_RISCV_CSR_REG(" #csr ")" +#define RISCV_CSR_SMSTATEEN(csr) \ + "KVM_REG_RISCV_CSR_SMSTATEEN | KVM_REG_RISCV_CSR_REG(" #csr ")" static const char *general_csr_id_to_str(__u64 reg_off) { @@ -243,6 +246,18 @@ static const char *aia_csr_id_to_str(__u64 reg_off) return NULL; } +static const char *smstateen_csr_id_to_str(__u64 reg_off) +{ + /* reg_off is the offset into struct kvm_riscv_smstateen_csr */ + switch (reg_off) { + case KVM_REG_RISCV_CSR_SMSTATEEN_REG(sstateen0): + return RISCV_CSR_SMSTATEEN(sstateen0); + } + + TEST_FAIL("Unknown smstateen csr reg: 0x%llx", reg_off); + return NULL; +} + static const char *csr_id_to_str(const char *prefix, __u64 id) { __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CSR); @@ -255,6 +270,8 @@ static const char *csr_id_to_str(const char *prefix, __u64 id) return general_csr_id_to_str(reg_off); case KVM_REG_RISCV_CSR_AIA: return aia_csr_id_to_str(reg_off); + case KVM_REG_RISCV_CSR_SMSTATEEN: + return smstateen_csr_id_to_str(reg_off); } TEST_FAIL("%s: Unknown csr subtype: 0x%llx", prefix, reg_subtype); @@ -332,6 +349,7 @@ static const char *isa_ext_id_to_str(__u64 id) KVM_ISA_EXT_ARR(I), KVM_ISA_EXT_ARR(M), KVM_ISA_EXT_ARR(V), + KVM_ISA_EXT_ARR(SMSTATEEN), KVM_ISA_EXT_ARR(SSAIA), KVM_ISA_EXT_ARR(SSTC), KVM_ISA_EXT_ARR(SVINVAL), @@ -637,6 +655,11 @@ static __u64 aia_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SSAIA, }; +static __u64 smstateen_regs[] = { + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_CSR | KVM_REG_RISCV_CSR_SMSTATEEN | KVM_REG_RISCV_CSR_SMSTATEEN_REG(sstateen0), + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_SMSTATEEN, +}; + static __u64 fp_f_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_U32 | KVM_REG_RISCV_FP_F | KVM_REG_RISCV_FP_F_REG(f[0]), KVM_REG_RISCV | KVM_REG_SIZE_U32 | KVM_REG_RISCV_FP_F | KVM_REG_RISCV_FP_F_REG(f[1]), @@ -744,6 +767,8 @@ static __u64 fp_d_regs[] = { {"zihpm", .feature = KVM_RISCV_ISA_EXT_ZIHPM, .regs = zihpm_regs, .regs_n = ARRAY_SIZE(zihpm_regs),} #define AIA_REGS_SUBLIST \ {"aia", .feature = KVM_RISCV_ISA_EXT_SSAIA, .regs = aia_regs, .regs_n = ARRAY_SIZE(aia_regs),} +#define SMSTATEEN_REGS_SUBLIST \ + {"smstateen", .feature = KVM_RISCV_ISA_EXT_SMSTATEEN, .regs = smstateen_regs, .regs_n = ARRAY_SIZE(smstateen_regs),} #define FP_F_REGS_SUBLIST \ {"fp_f", .feature = KVM_RISCV_ISA_EXT_F, .regs = fp_f_regs, \ .regs_n = ARRAY_SIZE(fp_f_regs),} @@ -871,6 +896,14 @@ static struct vcpu_reg_list aia_config = { }, }; +static struct vcpu_reg_list smstateen_config = { + .sublists = { + BASE_SUBLIST, + SMSTATEEN_REGS_SUBLIST, + {0}, + }, +}; + static struct vcpu_reg_list fp_f_config = { .sublists = { BASE_SUBLIST, @@ -903,6 +936,7 @@ struct vcpu_reg_list *vcpu_configs[] = { &zifencei_config, &zihpm_config, &aia_config, + &smstateen_config, &fp_f_config, &fp_d_config, }; -- cgit From 2b3f2b78ec93bdb1cfd8574158719d54263d50d6 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 15 Sep 2023 22:32:40 +0530 Subject: KVM: riscv: selftests: Add condops extensions to get-reg-list test We have a new conditional operations related ISA extensions so let us add these extensions to get-reg-list test. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 625118d53b74..77dc5221c465 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -48,6 +48,7 @@ bool filter_reg(__u64 reg) case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOM: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICBOZ: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR: + case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICOND: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICSR: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIFENCEI: case KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZIHINTPAUSE: @@ -361,6 +362,7 @@ static const char *isa_ext_id_to_str(__u64 id) KVM_ISA_EXT_ARR(ZICBOM), KVM_ISA_EXT_ARR(ZICBOZ), KVM_ISA_EXT_ARR(ZICNTR), + KVM_ISA_EXT_ARR(ZICOND), KVM_ISA_EXT_ARR(ZICSR), KVM_ISA_EXT_ARR(ZIFENCEI), KVM_ISA_EXT_ARR(ZIHINTPAUSE), @@ -632,6 +634,10 @@ static __u64 zicntr_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICNTR, }; +static __u64 zicond_regs[] = { + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICOND, +}; + static __u64 zicsr_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_ISA_EXT | KVM_RISCV_ISA_EXT_ZICSR, }; @@ -759,6 +765,8 @@ static __u64 fp_d_regs[] = { {"zbs", .feature = KVM_RISCV_ISA_EXT_ZBS, .regs = zbs_regs, .regs_n = ARRAY_SIZE(zbs_regs),} #define ZICNTR_REGS_SUBLIST \ {"zicntr", .feature = KVM_RISCV_ISA_EXT_ZICNTR, .regs = zicntr_regs, .regs_n = ARRAY_SIZE(zicntr_regs),} +#define ZICOND_REGS_SUBLIST \ + {"zicond", .feature = KVM_RISCV_ISA_EXT_ZICOND, .regs = zicond_regs, .regs_n = ARRAY_SIZE(zicond_regs),} #define ZICSR_REGS_SUBLIST \ {"zicsr", .feature = KVM_RISCV_ISA_EXT_ZICSR, .regs = zicsr_regs, .regs_n = ARRAY_SIZE(zicsr_regs),} #define ZIFENCEI_REGS_SUBLIST \ @@ -864,6 +872,14 @@ static struct vcpu_reg_list zicntr_config = { }, }; +static struct vcpu_reg_list zicond_config = { + .sublists = { + BASE_SUBLIST, + ZICOND_REGS_SUBLIST, + {0}, + }, +}; + static struct vcpu_reg_list zicsr_config = { .sublists = { BASE_SUBLIST, @@ -932,6 +948,7 @@ struct vcpu_reg_list *vcpu_configs[] = { &zbb_config, &zbs_config, &zicntr_config, + &zicond_config, &zicsr_config, &zifencei_config, &zihpm_config, -- cgit From 62d0c458f828949dd01bfe41daf3bed73ab9e288 Mon Sep 17 00:00:00 2001 From: Andrew Jones Date: Wed, 20 Sep 2023 16:37:14 +0200 Subject: KVM: riscv: selftests: get-reg-list print_reg should never fail When outputting the "new" register list we want to print all of the new registers, decoding as much as possible of each of them. Also, we don't want to assert while listing registers with '--list'. We output "/* UNKNOWN */" after each new register (which we were already doing for some), which should be enough. Signed-off-by: Andrew Jones Reviewed-by: Haibo Xu Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 93 +++++++++++------------- 1 file changed, 42 insertions(+), 51 deletions(-) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 77dc5221c465..234006d035c9 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -116,11 +116,13 @@ void finalize_vcpu(struct kvm_vcpu *vcpu, struct vcpu_reg_list *c) } } -static const char *config_id_to_str(__u64 id) +static const char *config_id_to_str(const char *prefix, __u64 id) { /* reg_off is the offset into struct kvm_riscv_config */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CONFIG); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CONFIG); + switch (reg_off) { case KVM_REG_RISCV_CONFIG_REG(isa): return "KVM_REG_RISCV_CONFIG_REG(isa)"; @@ -138,11 +140,7 @@ static const char *config_id_to_str(__u64 id) return "KVM_REG_RISCV_CONFIG_REG(satp_mode)"; } - /* - * Config regs would grow regularly with new pseudo reg added, so - * just show raw id to indicate a new pseudo config reg. - */ - return strdup_printf("KVM_REG_RISCV_CONFIG_REG(%lld) /* UNKNOWN */", reg_off); + return strdup_printf("%lld /* UNKNOWN */", reg_off); } static const char *core_id_to_str(const char *prefix, __u64 id) @@ -150,6 +148,8 @@ static const char *core_id_to_str(const char *prefix, __u64 id) /* reg_off is the offset into struct kvm_riscv_core */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CORE); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CORE); + switch (reg_off) { case KVM_REG_RISCV_CORE_REG(regs.pc): return "KVM_REG_RISCV_CORE_REG(regs.pc)"; @@ -180,8 +180,7 @@ static const char *core_id_to_str(const char *prefix, __u64 id) return "KVM_REG_RISCV_CORE_REG(mode)"; } - TEST_FAIL("%s: Unknown core reg id: 0x%llx", prefix, id); - return NULL; + return strdup_printf("%lld /* UNKNOWN */", reg_off); } #define RISCV_CSR_GENERAL(csr) \ @@ -219,8 +218,7 @@ static const char *general_csr_id_to_str(__u64 reg_off) return RISCV_CSR_GENERAL(senvcfg); } - TEST_FAIL("Unknown general csr reg: 0x%llx", reg_off); - return NULL; + return strdup_printf("KVM_REG_RISCV_CSR_GENERAL | %lld /* UNKNOWN */", reg_off); } static const char *aia_csr_id_to_str(__u64 reg_off) @@ -243,8 +241,7 @@ static const char *aia_csr_id_to_str(__u64 reg_off) return RISCV_CSR_AIA(iprio2h); } - TEST_FAIL("Unknown aia csr reg: 0x%llx", reg_off); - return NULL; + return strdup_printf("KVM_REG_RISCV_CSR_AIA | %lld /* UNKNOWN */", reg_off); } static const char *smstateen_csr_id_to_str(__u64 reg_off) @@ -264,6 +261,8 @@ static const char *csr_id_to_str(const char *prefix, __u64 id) __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_CSR); __u64 reg_subtype = reg_off & KVM_REG_RISCV_SUBTYPE_MASK; + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_CSR); + reg_off &= ~KVM_REG_RISCV_SUBTYPE_MASK; switch (reg_subtype) { @@ -275,8 +274,7 @@ static const char *csr_id_to_str(const char *prefix, __u64 id) return smstateen_csr_id_to_str(reg_off); } - TEST_FAIL("%s: Unknown csr subtype: 0x%llx", prefix, reg_subtype); - return NULL; + return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off); } static const char *timer_id_to_str(const char *prefix, __u64 id) @@ -284,6 +282,8 @@ static const char *timer_id_to_str(const char *prefix, __u64 id) /* reg_off is the offset into struct kvm_riscv_timer */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_TIMER); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_TIMER); + switch (reg_off) { case KVM_REG_RISCV_TIMER_REG(frequency): return "KVM_REG_RISCV_TIMER_REG(frequency)"; @@ -295,8 +295,7 @@ static const char *timer_id_to_str(const char *prefix, __u64 id) return "KVM_REG_RISCV_TIMER_REG(state)"; } - TEST_FAIL("%s: Unknown timer reg id: 0x%llx", prefix, id); - return NULL; + return strdup_printf("%lld /* UNKNOWN */", reg_off); } static const char *fp_f_id_to_str(const char *prefix, __u64 id) @@ -304,6 +303,8 @@ static const char *fp_f_id_to_str(const char *prefix, __u64 id) /* reg_off is the offset into struct __riscv_f_ext_state */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_FP_F); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_F); + switch (reg_off) { case KVM_REG_RISCV_FP_F_REG(f[0]) ... KVM_REG_RISCV_FP_F_REG(f[31]): @@ -312,8 +313,7 @@ static const char *fp_f_id_to_str(const char *prefix, __u64 id) return "KVM_REG_RISCV_FP_F_REG(fcsr)"; } - TEST_FAIL("%s: Unknown fp_f reg id: 0x%llx", prefix, id); - return NULL; + return strdup_printf("%lld /* UNKNOWN */", reg_off); } static const char *fp_d_id_to_str(const char *prefix, __u64 id) @@ -321,6 +321,8 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id) /* reg_off is the offset into struct __riscv_d_ext_state */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_FP_D); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_FP_D); + switch (reg_off) { case KVM_REG_RISCV_FP_D_REG(f[0]) ... KVM_REG_RISCV_FP_D_REG(f[31]): @@ -329,18 +331,19 @@ static const char *fp_d_id_to_str(const char *prefix, __u64 id) return "KVM_REG_RISCV_FP_D_REG(fcsr)"; } - TEST_FAIL("%s: Unknown fp_d reg id: 0x%llx", prefix, id); - return NULL; + return strdup_printf("%lld /* UNKNOWN */", reg_off); } #define KVM_ISA_EXT_ARR(ext) \ [KVM_RISCV_ISA_EXT_##ext] = "KVM_RISCV_ISA_EXT_" #ext -static const char *isa_ext_id_to_str(__u64 id) +static const char *isa_ext_id_to_str(const char *prefix, __u64 id) { /* reg_off is the offset into unsigned long kvm_isa_ext_arr[] */ __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_ISA_EXT); + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_ISA_EXT); + static const char * const kvm_isa_ext_reg_name[] = { KVM_ISA_EXT_ARR(A), KVM_ISA_EXT_ARR(C), @@ -369,13 +372,8 @@ static const char *isa_ext_id_to_str(__u64 id) KVM_ISA_EXT_ARR(ZIHPM), }; - if (reg_off >= ARRAY_SIZE(kvm_isa_ext_reg_name)) { - /* - * isa_ext regs would grow regularly with new isa extension added, so - * just show "reg" to indicate a new extension. - */ + if (reg_off >= ARRAY_SIZE(kvm_isa_ext_reg_name)) return strdup_printf("%lld /* UNKNOWN */", reg_off); - } return kvm_isa_ext_reg_name[reg_off]; } @@ -398,35 +396,27 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off) KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR), }; - if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) { - /* - * sbi_ext regs would grow regularly with new sbi extension added, so - * just show "reg" to indicate a new extension. - */ + if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) return strdup_printf("KVM_REG_RISCV_SBI_SINGLE | %lld /* UNKNOWN */", reg_off); - } return kvm_sbi_ext_reg_name[reg_off]; } static const char *sbi_ext_multi_id_to_str(__u64 reg_subtype, __u64 reg_off) { - if (reg_off > KVM_REG_RISCV_SBI_MULTI_REG_LAST) { - /* - * sbi_ext regs would grow regularly with new sbi extension added, so - * just show "reg" to indicate a new extension. - */ - return strdup_printf("%lld /* UNKNOWN */", reg_off); - } + const char *unknown = ""; + + if (reg_off > KVM_REG_RISCV_SBI_MULTI_REG_LAST) + unknown = " /* UNKNOWN */"; switch (reg_subtype) { case KVM_REG_RISCV_SBI_MULTI_EN: - return strdup_printf("KVM_REG_RISCV_SBI_MULTI_EN | %lld", reg_off); + return strdup_printf("KVM_REG_RISCV_SBI_MULTI_EN | %lld%s", reg_off, unknown); case KVM_REG_RISCV_SBI_MULTI_DIS: - return strdup_printf("KVM_REG_RISCV_SBI_MULTI_DIS | %lld", reg_off); + return strdup_printf("KVM_REG_RISCV_SBI_MULTI_DIS | %lld%s", reg_off, unknown); } - return NULL; + return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off); } static const char *sbi_ext_id_to_str(const char *prefix, __u64 id) @@ -434,6 +424,8 @@ static const char *sbi_ext_id_to_str(const char *prefix, __u64 id) __u64 reg_off = id & ~(REG_MASK | KVM_REG_RISCV_SBI_EXT); __u64 reg_subtype = reg_off & KVM_REG_RISCV_SUBTYPE_MASK; + assert((id & KVM_REG_RISCV_TYPE_MASK) == KVM_REG_RISCV_SBI_EXT); + reg_off &= ~KVM_REG_RISCV_SUBTYPE_MASK; switch (reg_subtype) { @@ -444,8 +436,7 @@ static const char *sbi_ext_id_to_str(const char *prefix, __u64 id) return sbi_ext_multi_id_to_str(reg_subtype, reg_off); } - TEST_FAIL("%s: Unknown sbi ext subtype: 0x%llx", prefix, reg_subtype); - return NULL; + return strdup_printf("%lld | %lld /* UNKNOWN */", reg_subtype, reg_off); } void print_reg(const char *prefix, __u64 id) @@ -466,14 +457,14 @@ void print_reg(const char *prefix, __u64 id) reg_size = "KVM_REG_SIZE_U128"; break; default: - TEST_FAIL("%s: Unexpected reg size: 0x%llx in reg id: 0x%llx", - prefix, (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id); + printf("\tKVM_REG_RISCV | (%lld << KVM_REG_SIZE_SHIFT) | 0x%llx /* UNKNOWN */,", + (id & KVM_REG_SIZE_MASK) >> KVM_REG_SIZE_SHIFT, id & REG_MASK); } switch (id & KVM_REG_RISCV_TYPE_MASK) { case KVM_REG_RISCV_CONFIG: printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_CONFIG | %s,\n", - reg_size, config_id_to_str(id)); + reg_size, config_id_to_str(prefix, id)); break; case KVM_REG_RISCV_CORE: printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_CORE | %s,\n", @@ -497,15 +488,15 @@ void print_reg(const char *prefix, __u64 id) break; case KVM_REG_RISCV_ISA_EXT: printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_ISA_EXT | %s,\n", - reg_size, isa_ext_id_to_str(id)); + reg_size, isa_ext_id_to_str(prefix, id)); break; case KVM_REG_RISCV_SBI_EXT: printf("\tKVM_REG_RISCV | %s | KVM_REG_RISCV_SBI_EXT | %s,\n", reg_size, sbi_ext_id_to_str(prefix, id)); break; default: - TEST_FAIL("%s: Unexpected reg type: 0x%llx in reg id: 0x%llx", prefix, - (id & KVM_REG_RISCV_TYPE_MASK) >> KVM_REG_RISCV_TYPE_SHIFT, id); + printf("\tKVM_REG_RISCV | %s | 0x%llx /* UNKNOWN */,", + reg_size, id & REG_MASK); } } -- cgit From dadf7886993c69c6838107573e250a3b3fda25e3 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 22 Jul 2022 18:54:54 +0530 Subject: RISC-V: Add defines for SBI debug console extension We add SBI debug console extension related defines/enum to the asm/sbi.h header. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/sbi.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 5b4a1bf5f439..12dfda6bb924 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -30,6 +30,7 @@ enum sbi_ext_id { SBI_EXT_HSM = 0x48534D, SBI_EXT_SRST = 0x53525354, SBI_EXT_PMU = 0x504D55, + SBI_EXT_DBCN = 0x4442434E, /* Experimentals extensions must lie within this range */ SBI_EXT_EXPERIMENTAL_START = 0x08000000, @@ -236,6 +237,12 @@ enum sbi_pmu_ctr_type { /* Flags defined for counter stop function */ #define SBI_PMU_STOP_FLAG_RESET (1 << 0) +enum sbi_ext_dbcn_fid { + SBI_EXT_DBCN_CONSOLE_WRITE = 0, + SBI_EXT_DBCN_CONSOLE_READ = 1, + SBI_EXT_DBCN_CONSOLE_WRITE_BYTE = 2, +}; + #define SBI_SPEC_VERSION_DEFAULT 0x1 #define SBI_SPEC_VERSION_MAJOR_SHIFT 24 #define SBI_SPEC_VERSION_MAJOR_MASK 0x7f -- cgit From b88e87a0a1ec0aa10861d84f8321743902583443 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Tue, 10 Oct 2023 15:23:51 +0530 Subject: RISC-V: KVM: Change the SBI specification version to v2.0 We will be implementing SBI DBCN extension for KVM RISC-V so let us change the KVM RISC-V SBI specification version to v2.0. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index cdcf0ff07be7..8d6d4dce8a5e 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -11,7 +11,7 @@ #define KVM_SBI_IMPID 3 -#define KVM_SBI_VERSION_MAJOR 1 +#define KVM_SBI_VERSION_MAJOR 2 #define KVM_SBI_VERSION_MINOR 0 enum kvm_riscv_sbi_ext_status { -- cgit From 56d8a385b60556019ecb45d6098830c9ef6a13e0 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 11 Oct 2023 17:52:26 +0530 Subject: RISC-V: KVM: Allow some SBI extensions to be disabled by default Currently, all SBI extensions are enabled by default which is problematic for SBI extensions (such as DBCN) which are forwarded to the KVM user-space because we might have an older KVM user-space which is not aware/ready to handle newer SBI extensions. Ideally, the SBI extensions forwarded to the KVM user-space must be disabled by default. To address above, we allow certain SBI extensions to be disabled by default so that KVM user-space must explicitly enable such SBI extensions to receive forwarded calls from Guest VCPU. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 4 +++ arch/riscv/kvm/vcpu.c | 6 ++++ arch/riscv/kvm/vcpu_sbi.c | 57 +++++++++++++++++------------------ 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 8d6d4dce8a5e..c02bda5559d7 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -35,6 +35,9 @@ struct kvm_vcpu_sbi_return { struct kvm_vcpu_sbi_extension { unsigned long extid_start; unsigned long extid_end; + + bool default_unavail; + /** * SBI extension handler. It can be defined for a given extension or group of * extension. But it should always return linux error codes rather than SBI @@ -59,6 +62,7 @@ int kvm_riscv_vcpu_get_reg_sbi_ext(struct kvm_vcpu *vcpu, const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( struct kvm_vcpu *vcpu, unsigned long extid); int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run); +void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu); #ifdef CONFIG_RISCV_SBI_V01 extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index c061a1c5fe98..e087c809073c 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -141,6 +141,12 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) if (rc) return rc; + /* + * Setup SBI extensions + * NOTE: This must be the last thing to be initialized. + */ + kvm_riscv_vcpu_sbi_init(vcpu); + /* Reset VCPU */ kvm_riscv_reset_vcpu(vcpu); diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 9cd97091c723..bda8b0b33343 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -155,14 +155,8 @@ static int riscv_vcpu_set_sbi_ext_single(struct kvm_vcpu *vcpu, if (!sext) return -ENOENT; - /* - * We can't set the extension status to available here, since it may - * have a probe() function which needs to confirm availability first, - * but it may be too early to call that here. We can set the status to - * unavailable, though. - */ - if (!reg_val) - scontext->ext_status[sext->ext_idx] = + scontext->ext_status[sext->ext_idx] = (reg_val) ? + KVM_RISCV_SBI_EXT_AVAILABLE : KVM_RISCV_SBI_EXT_UNAVAILABLE; return 0; @@ -188,16 +182,8 @@ static int riscv_vcpu_get_sbi_ext_single(struct kvm_vcpu *vcpu, if (!sext) return -ENOENT; - /* - * If the extension status is still uninitialized, then we should probe - * to determine if it's available, but it may be too early to do that - * here. The best we can do is report that the extension has not been - * disabled, i.e. we return 1 when the extension is available and also - * when it only may be available. - */ - *reg_val = scontext->ext_status[sext->ext_idx] != - KVM_RISCV_SBI_EXT_UNAVAILABLE; - + *reg_val = scontext->ext_status[sext->ext_idx] == + KVM_RISCV_SBI_EXT_AVAILABLE; return 0; } @@ -337,18 +323,8 @@ const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext( scontext->ext_status[entry->ext_idx] == KVM_RISCV_SBI_EXT_AVAILABLE) return ext; - if (scontext->ext_status[entry->ext_idx] == - KVM_RISCV_SBI_EXT_UNAVAILABLE) - return NULL; - if (ext->probe && !ext->probe(vcpu)) { - scontext->ext_status[entry->ext_idx] = - KVM_RISCV_SBI_EXT_UNAVAILABLE; - return NULL; - } - scontext->ext_status[entry->ext_idx] = - KVM_RISCV_SBI_EXT_AVAILABLE; - return ext; + return NULL; } } @@ -419,3 +395,26 @@ ecall_done: return ret; } + +void kvm_riscv_vcpu_sbi_init(struct kvm_vcpu *vcpu) +{ + struct kvm_vcpu_sbi_context *scontext = &vcpu->arch.sbi_context; + const struct kvm_riscv_sbi_extension_entry *entry; + const struct kvm_vcpu_sbi_extension *ext; + int i; + + for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) { + entry = &sbi_ext[i]; + ext = entry->ext_ptr; + + if (ext->probe && !ext->probe(vcpu)) { + scontext->ext_status[entry->ext_idx] = + KVM_RISCV_SBI_EXT_UNAVAILABLE; + continue; + } + + scontext->ext_status[entry->ext_idx] = ext->default_unavail ? + KVM_RISCV_SBI_EXT_UNAVAILABLE : + KVM_RISCV_SBI_EXT_AVAILABLE; + } +} -- cgit From c667ad229d13c41590882a35a8c159387b4e149b Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 22 Jul 2022 19:46:24 +0530 Subject: RISC-V: KVM: Forward SBI DBCN extension to user-space The frozen SBI v2.0 specification defines the SBI debug console (DBCN) extension which replaces the legacy SBI v0.1 console functions namely sbi_console_getchar() and sbi_console_putchar(). The SBI DBCN extension needs to be emulated in the KVM user-space (i.e. QEMU-KVM or KVMTOOL) so we forward SBI DBCN calls from KVM guest to the KVM user-space which can then redirect the console input/output to wherever it wants (e.g. telnet, file, stdio, etc). The SBI debug console is simply a early console available to KVM guest for early prints and it does not intend to replace the proper console devices such as 8250, VirtIO console, etc. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 + arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu_sbi.c | 4 ++++ arch/riscv/kvm/vcpu_sbi_replace.c | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index c02bda5559d7..6a453f7f8b56 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -73,6 +73,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_experimental; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_vendor; diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index 917d8cc2489e..60d3b21dead7 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -156,6 +156,7 @@ enum KVM_RISCV_SBI_EXT_ID { KVM_RISCV_SBI_EXT_PMU, KVM_RISCV_SBI_EXT_EXPERIMENTAL, KVM_RISCV_SBI_EXT_VENDOR, + KVM_RISCV_SBI_EXT_DBCN, KVM_RISCV_SBI_EXT_MAX, }; diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index bda8b0b33343..a04ff98085d9 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -66,6 +66,10 @@ static const struct kvm_riscv_sbi_extension_entry sbi_ext[] = { .ext_idx = KVM_RISCV_SBI_EXT_PMU, .ext_ptr = &vcpu_sbi_ext_pmu, }, + { + .ext_idx = KVM_RISCV_SBI_EXT_DBCN, + .ext_ptr = &vcpu_sbi_ext_dbcn, + }, { .ext_idx = KVM_RISCV_SBI_EXT_EXPERIMENTAL, .ext_ptr = &vcpu_sbi_ext_experimental, diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index 7c4d5d38a339..23b57c931b15 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -175,3 +175,35 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = { .extid_end = SBI_EXT_SRST, .handler = kvm_sbi_ext_srst_handler, }; + +static int kvm_sbi_ext_dbcn_handler(struct kvm_vcpu *vcpu, + struct kvm_run *run, + struct kvm_vcpu_sbi_return *retdata) +{ + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long funcid = cp->a6; + + switch (funcid) { + case SBI_EXT_DBCN_CONSOLE_WRITE: + case SBI_EXT_DBCN_CONSOLE_READ: + case SBI_EXT_DBCN_CONSOLE_WRITE_BYTE: + /* + * The SBI debug console functions are unconditionally + * forwarded to the userspace. + */ + kvm_riscv_vcpu_sbi_forward(vcpu, run); + retdata->uexit = true; + break; + default: + retdata->err_val = SBI_ERR_NOT_SUPPORTED; + } + + return 0; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_dbcn = { + .extid_start = SBI_EXT_DBCN, + .extid_end = SBI_EXT_DBCN, + .default_unavail = true, + .handler = kvm_sbi_ext_dbcn_handler, +}; -- cgit From d9c00f44e5de542340cce1d09e2c990e16c0ed3a Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 20 Oct 2023 12:38:27 +0530 Subject: KVM: riscv: selftests: Add SBI DBCN extension to get-reg-list test We have a new SBI debug console (DBCN) extension supported by in-kernel KVM so let us add this extension to get-reg-list test. Signed-off-by: Anup Patel Reviewed-by: Andrew Jones Signed-off-by: Anup Patel --- tools/testing/selftests/kvm/riscv/get-reg-list.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/testing/selftests/kvm/riscv/get-reg-list.c b/tools/testing/selftests/kvm/riscv/get-reg-list.c index 234006d035c9..6bedaea95395 100644 --- a/tools/testing/selftests/kvm/riscv/get-reg-list.c +++ b/tools/testing/selftests/kvm/riscv/get-reg-list.c @@ -394,6 +394,7 @@ static const char *sbi_ext_single_id_to_str(__u64 reg_off) KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_PMU), KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_EXPERIMENTAL), KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_VENDOR), + KVM_SBI_EXT_ARR(KVM_RISCV_SBI_EXT_DBCN), }; if (reg_off >= ARRAY_SIZE(kvm_sbi_ext_reg_name)) @@ -567,6 +568,7 @@ static __u64 base_regs[] = { KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_PMU, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_EXPERIMENTAL, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_VENDOR, + KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_SINGLE | KVM_RISCV_SBI_EXT_DBCN, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_EN | 0, KVM_REG_RISCV | KVM_REG_SIZE_ULONG | KVM_REG_RISCV_SBI_EXT | KVM_REG_RISCV_SBI_MULTI_DIS | 0, }; -- cgit