Message ID | 20230808114711.2013842-27-maz@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | KVM: arm64: NV trap forwarding infrastructure | expand |
Hi Marc, On 8/8/23 13:47, Marc Zyngier wrote: > Although the nVHE behaviour requires HCRX_EL2 to be switched > on each switch between host and guest, there is nothing in > this register that would affect a VHE host. > > It is thus possible to save/restore this register on load/put > on VHE systems, avoiding unnecessary sysreg access on the hot > path. Additionally, it avoids unnecessary traps when running > with NV. > > To achieve this, simply move the read/writes to the *_common() > helpers, which are called on load/put on VHE, and more eagerly > on nVHE. > > Signed-off-by: Marc Zyngier <maz@kernel.org> > --- > arch/arm64/kvm/hyp/include/hyp/switch.h | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h > index a4750070563f..060c5a0409e5 100644 > --- a/arch/arm64/kvm/hyp/include/hyp/switch.h > +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h > @@ -197,6 +197,9 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) > vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); > write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); > > + if (cpus_have_final_cap(ARM64_HAS_HCX)) > + write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2); > + > __activate_traps_hfgxtr(vcpu); > } > > @@ -213,6 +216,9 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) > vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU); > } > > + if (cpus_have_final_cap(ARM64_HAS_HCX)) > + write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2); > + > __deactivate_traps_hfgxtr(vcpu); > } > > @@ -227,9 +233,6 @@ static inline void ___activate_traps(struct kvm_vcpu *vcpu) > > if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE)) > write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2); > - > - if (cpus_have_final_cap(ARM64_HAS_HCX)) > - write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2); > } > > static inline void ___deactivate_traps(struct kvm_vcpu *vcpu) > @@ -244,9 +247,6 @@ static inline void ___deactivate_traps(struct kvm_vcpu *vcpu) > vcpu->arch.hcr_el2 &= ~HCR_VSE; > vcpu->arch.hcr_el2 |= read_sysreg(hcr_el2) & HCR_VSE; > } > - > - if (cpus_have_final_cap(ARM64_HAS_HCX)) > - write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2); > } > > static inline bool __populate_fault_info(struct kvm_vcpu *vcpu) Reviewed-by: Eric Auger <eric.auger@redhat.com> Thanks Eric
diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h index a4750070563f..060c5a0409e5 100644 --- a/arch/arm64/kvm/hyp/include/hyp/switch.h +++ b/arch/arm64/kvm/hyp/include/hyp/switch.h @@ -197,6 +197,9 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu) vcpu->arch.mdcr_el2_host = read_sysreg(mdcr_el2); write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2); + if (cpus_have_final_cap(ARM64_HAS_HCX)) + write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2); + __activate_traps_hfgxtr(vcpu); } @@ -213,6 +216,9 @@ static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu) vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU); } + if (cpus_have_final_cap(ARM64_HAS_HCX)) + write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2); + __deactivate_traps_hfgxtr(vcpu); } @@ -227,9 +233,6 @@ static inline void ___activate_traps(struct kvm_vcpu *vcpu) if (cpus_have_final_cap(ARM64_HAS_RAS_EXTN) && (hcr & HCR_VSE)) write_sysreg_s(vcpu->arch.vsesr_el2, SYS_VSESR_EL2); - - if (cpus_have_final_cap(ARM64_HAS_HCX)) - write_sysreg_s(HCRX_GUEST_FLAGS, SYS_HCRX_EL2); } static inline void ___deactivate_traps(struct kvm_vcpu *vcpu) @@ -244,9 +247,6 @@ static inline void ___deactivate_traps(struct kvm_vcpu *vcpu) vcpu->arch.hcr_el2 &= ~HCR_VSE; vcpu->arch.hcr_el2 |= read_sysreg(hcr_el2) & HCR_VSE; } - - if (cpus_have_final_cap(ARM64_HAS_HCX)) - write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2); } static inline bool __populate_fault_info(struct kvm_vcpu *vcpu)
Although the nVHE behaviour requires HCRX_EL2 to be switched on each switch between host and guest, there is nothing in this register that would affect a VHE host. It is thus possible to save/restore this register on load/put on VHE systems, avoiding unnecessary sysreg access on the hot path. Additionally, it avoids unnecessary traps when running with NV. To achieve this, simply move the read/writes to the *_common() helpers, which are called on load/put on VHE, and more eagerly on nVHE. Signed-off-by: Marc Zyngier <maz@kernel.org> --- arch/arm64/kvm/hyp/include/hyp/switch.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)