Risc-V Kvm Smstateen
Subsystems (3)
v2 cover Risc-V Kvm Smstateen
This series adds support to detect the Smstateen extension for both, the host and the guest vcpu. It also adds senvcfg and sstateen0 to the ONE_REG interface and the vcpu context save/restore.
Changes in v2:
- Add smstaeen description in riscv/extensions.yaml
- Avoid line wrap at 80 chars
Mayuresh Chitale (6):
RISC-V: Detect Smstateen extension
RISC-V: KVM: Add kvm_vcpu_config
RISC-V: KVM: Enable Smstateen accesses
RISCV: KVM: Add senvcfg context save/restore
RISCV: KVM: Add sstateen0 context save/restore
RISCV: KVM: Add sstateen0 to ONE_REG
.../devicetree/bindings/riscv/extensions.yaml | 6 ++ arch/riscv/include/asm/csr.h | 18 ++++ arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/include/asm/kvm_host.h | 18 ++++ arch/riscv/include/uapi/asm/kvm.h | 11 +++ arch/riscv/kernel/cpu.c | 1 + arch/riscv/kernel/cpufeature.c | 1 + arch/riscv/kvm/vcpu.c | 97 ++++++++++++++++--- 8 files changed, 140 insertions(+), 13 deletions(-)
Signature · 1 line
2.34.1
PATCH v2 1/6 RISC-V: Detect Smstateen extension
Extend the ISA string parsing to detect the Smstateen extension
--- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpu.c | 1 + arch/riscv/kernel/cpufeature.c | 1 + 4 files changed, 9 insertions(+)
Documentation/devicetree/bindings/riscv/extensions.yaml +6 -0
@@ -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 accesss to CSRs + added by other Risc-V extensions in H/S/VS/U/VU modes and as + ratified at commit a28bfae (Ratified (#7)). + - const: ssaia description: | The standard Ssaia supervisor-level extension for the advanced
arch/riscv/include/asm/hwcap.h +1 -0
@@ -53,6 +53,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#define RISCV_ISA_EXT_NAME_LEN_MAX 32
arch/riscv/kernel/cpu.c +1 -0
@@ -217,6 +217,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {__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),
arch/riscv/kernel/cpufeature.c +1 -0
@@ -301,6 +301,7 @@ void __init riscv_fill_hwcap(void) }else {/* sorted alphabetically */ SET_ISA_EXT_MAP ("smaia" ,RISCV_ISA_EXT_SMAIA ); +SET_ISA_EXT_MAP ("smstateen" ,RISCV_ISA_EXT_SMSTATEEN );SET_ISA_EXT_MAP ("ssaia" ,RISCV_ISA_EXT_SSAIA );SET_ISA_EXT_MAP ("sscofpmf" ,RISCV_ISA_EXT_SSCOFPMF );SET_ISA_EXT_MAP ("sstc" ,RISCV_ISA_EXT_SSTC );
Signature · 1 line
2.34.1
PATCH v2 1/6 RISC-V: Detect Smstateen extension
Quoted 15 lines · Mayuresh Chitale
Extend the ISA string parsing to detect the Smstateen extension
Signed-off-by Mayuresh Chitale <[email protected]>--- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpu.c | 1 + arch/riscv/kernel/cpufeature.c | 1 + 4 files changed, 9 insertions(+)Documentation/devicetree/bindings/riscv/extensions.yaml +0
-0
Documentation/devicetree/bindings/riscv/extensions.yaml properties: · line 133
Quoted 6 lines
Documentation/devicetree/bindings/riscv/extensions.yaml +3
-0@@ -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 accesss to CSRs
^ access
Documentation/devicetree/bindings/riscv/extensions.yaml properties: · line 134
Quoted 1 line
Documentation/devicetree/bindings/riscv/extensions.yaml +1
-0+ added by other Risc-V extensions in H/S/VS/U/VU modes and as
s/and//
Quoted 44 lines
Documentation/devicetree/bindings/riscv/extensions.yaml +2
-0+ ratified at commit a28bfae (Ratified (#7)). + - const: ssaia description: | The standard Ssaia supervisor-level extension for the advancedarch/riscv/include/asm/hwcap.h +1
-0@@ -53,6 +53,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#define RISCV_ISA_EXT_NAME_LEN_MAX 32arch/riscv/kernel/cpu.c +1
-0@@ -217,6 +217,7 @@ static struct riscv_isa_ext_data isa_ext_arr[] = {__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),arch/riscv/kernel/cpufeature.c +1
-0@@ -301,6 +301,7 @@ void __init riscv_fill_hwcap(void) }else {/* sorted alphabetically */ SET_ISA_EXT_MAP ("smaia" ,RISCV_ISA_EXT_SMAIA ); +SET_ISA_EXT_MAP ("smstateen" ,RISCV_ISA_EXT_SMSTATEEN );SET_ISA_EXT_MAP ("ssaia" ,RISCV_ISA_EXT_SSAIA );SET_ISA_EXT_MAP ("sscofpmf" ,RISCV_ISA_EXT_SSCOFPMF );SET_ISA_EXT_MAP ("sstc" ,RISCV_ISA_EXT_SSTC );Signature · 1 line
2.34.1
Otherwise,
PATCH v2 1/6 RISC-V: Detect Smstateen extension
Hey,
Quoted 19 lines · Andrew Jones
Quoted 18 lines · Mayuresh Chitale
Extend the ISA string parsing to detect the Smstateen extension
Signed-off-by Mayuresh Chitale <[email protected]>--- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++ arch/riscv/include/asm/hwcap.h | 1 + arch/riscv/kernel/cpu.c | 1 + arch/riscv/kernel/cpufeature.c | 1 + 4 files changed, 9 insertions(+)Documentation/devicetree/bindings/riscv/extensions.yaml +0
-0@@ -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.
Quoted 6 lines
Documentation/devicetree/bindings/riscv/extensions.yaml properties: · line 133
Quoted 3 lines
Documentation/devicetree/bindings/riscv/extensions.yaml +3
-0+ - const: smstateen + description: | + The standard Smstateen extension for controlling accesss to CSRs^ access
Quoted 1 line
Documentation/devicetree/bindings/riscv/extensions.yaml +1
-0+ added by other Risc-V extensions in H/S/VS/U/VU modes and as
s/Risc-V/RISC-V/. Let's not invent new stylisations please.
Quoted 3 lines
s/and//
Quoted 1 line
Documentation/devicetree/bindings/riscv/extensions.yaml +1
-0+ ratified at commit a28bfae (Ratified (#7)).
An "of riscv-state-enable" at the end might be helpful too.
Either way, neither checkpatch nor get_maintainer were run on this v2 patch, the former would have pointed out that dt-binding changes should be made in their own patches.
The C stuff is fine, but this needs to be split in two.
Thanks,
Conor.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 228 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/kvm-riscv/attachments/20230721/4cb9343d/attachment.sig>
PATCH v2 1/6 RISC-V: Detect Smstateen extension
In reply to Mayuresh ChitaleQuoted 5 lines · Mayuresh Chitale
Extend the ISA string parsing to detect the Smstateen extension
Signed-off-by Mayuresh Chitale <[email protected]>--- Documentation/devicetree/bindings/riscv/extensions.yaml | 6 ++++++
Please run scripts/checkpatch.pl and fix reported warnings. Some warnings can be ignored, but the code here looks like it needs a fix. Feel free to get in touch if the warning is not clear.
Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.
You missed at least DT list (maybe more), so this won't be tested by automated tooling. Performing review on untested code might be a waste of time, thus I will skip this patch entirely till you follow the process allowing the patch to be tested.
Please kindly resend and include all necessary To/Cc entries.
Best regards,
Krzysztof
PATCH v2 2/6 RISC-V: KVM: Add kvm_vcpu_config
In reply to Mayuresh ChitaleAdd 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.
--- arch/riscv/include/asm/kvm_host.h | 7 +++++++ arch/riscv/kvm/vcpu.c | 27 ++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-)
arch/riscv/include/asm/kvm_host.h +7 -0
@@ -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) {}
arch/riscv/kvm/vcpu.c +14 -13
@@ -980,31 +980,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);
@@ -1015,8 +1012,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);
@@ -1136,6 +1134,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;
Signature · 1 line
2.34.1
PATCH v2 2/6 RISC-V: KVM: Add kvm_vcpu_config
Quoted 11 lines · Mayuresh Chitale
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 <[email protected]>--- arch/riscv/include/asm/kvm_host.h | 7 +++++++ arch/riscv/kvm/vcpu.c | 27 ++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-)
PATCH v2 3/6 RISC-V: KVM: Enable Smstateen accesses
In reply to Mayuresh ChitaleConfigure 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.
--- 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 | 16 ++++++++++++++++ 4 files changed, 34 insertions(+)
arch/riscv/include/asm/csr.h +16 -0
@@ -201,6 +201,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
@@ -347,6 +359,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
arch/riscv/include/asm/kvm_host.h +1 -0
@@ -166,6 +166,7 @@ struct kvm_vcpu_csr {struct kvm_vcpu_config {u64 henvcfg; +u64 hstateen0; };struct kvm_vcpu_arch {
arch/riscv/include/uapi/asm/kvm.h +1 -0
@@ -124,6 +124,7 @@ enum KVM_RISCV_ISA_EXT_ID {KVM_RISCV_ISA_EXT_SSAIA ,KVM_RISCV_ISA_EXT_V ,KVM_RISCV_ISA_EXT_SVNAPOT , +KVM_RISCV_ISA_EXT_SMSTATEEN , KVM_RISCV_ISA_EXT_MAX, };
arch/riscv/kvm/vcpu.c +16 -0
@@ -70,6 +70,7 @@ static const unsigned long kvm_isa_ext_arr[] = {KVM_ISA_EXT_ARR (ZIHINTPAUSE ),KVM_ISA_EXT_ARR (ZICBOM ),KVM_ISA_EXT_ARR (ZICBOZ ), + KVM_ISA_EXT_ARR(SMSTATEEN), };static unsigned long kvm_riscv_vcpu_base2isa_ext (unsigned long base_ext)
@@ -996,6 +997,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)
@@ -1015,6 +1026,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);
Signature · 1 line
2.34.1
PATCH v2 3/6 RISC-V: KVM: Enable Smstateen accesses
Quoted 4 lines · Mayuresh Chitale
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.
Quoted 8 lines
Signed-off-by Mayuresh Chitale <[email protected]>--- 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 | 16 ++++++++++++++++ 4 files changed, 34 insertions(+)
PATCH v2 4/6 RISCV: KVM: Add senvcfg context save/restore
In reply to Mayuresh ChitaleAdd senvcfg context save/restore for guest VCPUs and also add it to the ONE_REG interface to allow its access from user space.
--- 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 | 4 ++++ 4 files changed, 8 insertions(+)
arch/riscv/include/asm/csr.h +1 -0
@@ -285,6 +285,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
arch/riscv/include/asm/kvm_host.h +2 -0
@@ -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;
arch/riscv/include/uapi/asm/kvm.h +1 -0
@@ -79,6 +79,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 */
arch/riscv/kvm/vcpu.c +4 -0
@@ -1138,10 +1138,14 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)*/ static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu) { +struct kvm_vcpu_csr *csr = &vcpu->arch.guest_csr; + + vcpu->arch.host_senvcfg =csr_swap (CSR_SENVCFG , csr->senvcfg);guest_state_enter_irqoff ();__kvm_riscv_switch_to (&vcpu->arch); vcpu->arch.last_exit_cpu = vcpu->cpu;guest_state_exit_irqoff (); + csr->senvcfg =csr_swap (CSR_SENVCFG , vcpu->arch.host_senvcfg); }int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu)
Signature · 1 line
2.34.1
PATCH v2 4/6 RISCV: KVM: Add senvcfg context save/restore
Quoted 11 lines · Mayuresh Chitale
Add senvcfg context save/restore for guest VCPUs and also add it to the
ONE_REGinterface to allow its access from user space.Signed-off-by Mayuresh Chitale <[email protected]>--- 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 | 4 ++++ 4 files changed, 8 insertions(+)
PATCH v2 5/6 RISCV: KVM: Add sstateen0 context save/restore
In reply to Mayuresh ChitaleDefine sstateen0 and add sstateen0 save/restore for guest VCPUs.
--- arch/riscv/include/asm/csr.h | 1 + arch/riscv/include/asm/kvm_host.h | 8 ++++++++ arch/riscv/kvm/vcpu.c | 10 ++++++++++ 3 files changed, 19 insertions(+)
arch/riscv/include/asm/csr.h +1 -0
@@ -286,6 +286,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
arch/riscv/include/asm/kvm_host.h +8 -0
@@ -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;
arch/riscv/kvm/vcpu.c +10 -0
@@ -1138,14 +1138,24 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)*/ static void noinstr kvm_riscv_vcpu_enter_exit(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);guest_state_enter_irqoff ();__kvm_riscv_switch_to (&vcpu->arch); vcpu->arch.last_exit_cpu = vcpu->cpu;guest_state_exit_irqoff (); 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); }int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu)
Signature · 1 line
2.34.1
PATCH v2 5/6 RISCV: KVM: Add sstateen0 context save/restore
Quoted 71 lines · Mayuresh Chitale
Define sstateen0 and add sstateen0 save/restore for guest VCPUs.
Signed-off-by Mayuresh Chitale <[email protected]>--- arch/riscv/include/asm/csr.h | 1 + arch/riscv/include/asm/kvm_host.h | 8 ++++++++ arch/riscv/kvm/vcpu.c | 10 ++++++++++ 3 files changed, 19 insertions(+)arch/riscv/include/asm/csr.h +1
-0@@ -286,6 +286,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 0x142arch/riscv/include/asm/kvm_host.h +8
-0@@ -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;arch/riscv/kvm/vcpu.c +6
-0@@ -1138,14 +1138,24 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)*/ static void noinstr kvm_riscv_vcpu_enter_exit(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);
arch/riscv/kvm/vcpu.c static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) · line 1159
Quoted 10 lines
arch/riscv/kvm/vcpu.c +4
-0guest_state_enter_irqoff ();__kvm_riscv_switch_to (&vcpu->arch); vcpu->arch.last_exit_cpu = vcpu->cpu;guest_state_exit_irqoff (); 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); }
It might be nice to keep kvm_riscv_vcpu_enter_exit() "clean", by adding a couple functions. Something like
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);}
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);}
Quoted 5 lines
arch/riscv/kvm/vcpu.c +0
-0int kvm_arch_vcpu_ioctl_run (struct kvm_vcpu *vcpu)Signature · 1 line
2.34.1
Either way,
Thanks,
drew
PATCH v2 6/6 RISCV: KVM: Add sstateen0 to ONE_REG
In reply to Mayuresh ChitaleAdd support for sstateen0 CSR to the ONE_REG interface to allow its access from user space.
--- arch/riscv/include/uapi/asm/kvm.h | 9 +++++++ arch/riscv/kvm/vcpu.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+)
arch/riscv/include/uapi/asm/kvm.h +9 -0
@@ -93,6 +93,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;
@@ -173,10 +178,14 @@ 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)
arch/riscv/kvm/vcpu.c +40 -0
@@ -507,6 +507,34 @@ static int kvm_riscv_vcpu_general_get_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 inline int kvm_riscv_vcpu_general_set_csr (struct kvm_vcpu *vcpu,unsigned long reg_num,unsigned long reg_val)
@@ -552,6 +580,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 = -EINVAL ;break ;
@@ -591,6 +625,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 = -EINVAL ;break ;
Signature · 1 line
2.34.1
PATCH v2 6/6 RISCV: KVM: Add sstateen0 to ONE_REG
Quoted 108 lines · Mayuresh Chitale
Add support for sstateen0 CSR to the
ONE_REGinterface to allow its access from user space.Signed-off-by Mayuresh Chitale <[email protected]>--- arch/riscv/include/uapi/asm/kvm.h | 9 +++++++ arch/riscv/kvm/vcpu.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+)arch/riscv/include/uapi/asm/kvm.h +9
-0@@ -93,6 +93,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;@@ -173,10 +178,14 @@ 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)arch/riscv/kvm/vcpu.c +40
-0@@ -507,6 +507,34 @@ static int kvm_riscv_vcpu_general_get_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 inline int kvm_riscv_vcpu_general_set_csr (struct kvm_vcpu *vcpu,unsigned long reg_num,unsigned long reg_val)@@ -552,6 +580,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 = -EINVAL ;break ;@@ -591,6 +625,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 = -EINVAL ;break ;Signature · 1 line
2.34.1
The EINVAL's will get changed to ENOENT's with the get/set-one-reg error code rework that's coming after get-reg-list lands, but for now I guess it makes sense to leave them consistent with the others.