]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: Properly save/restore HCRX_EL2
authorMarc Zyngier <maz@kernel.org>
Wed, 30 Apr 2025 10:59:15 +0000 (11:59 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Wed, 7 May 2025 07:16:44 +0000 (00:16 -0700)
Rather than restoring HCRX_EL2 to a fixed value on vcpu exit,
perform a full save/restore of the register, ensuring that
we don't lose bits that would have been set at some point in
the host kernel lifetime, such as the GCSEn bit.

Fixes: ff5181d8a2a82 ("arm64/gcs: Provide basic EL2 setup to allow GCS usage at EL0 and EL1")
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250430105916.3815157-2-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/hyp/include/hyp/switch.h

index b741ea6aefa58f5dabf02aeb7f9bd8029db151be..96f625dc725669a0bcb15748516cfda1318d8783 100644 (file)
@@ -235,6 +235,8 @@ static inline void __deactivate_traps_mpam(void)
 
 static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 {
+       struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
+
        /* Trap on AArch32 cp15 c15 (impdef sysregs) accesses (EL1 or EL0) */
        write_sysreg(1 << 15, hstr_el2);
 
@@ -245,11 +247,8 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
         * EL1 instead of being trapped to EL2.
         */
        if (system_supports_pmuv3()) {
-               struct kvm_cpu_context *hctxt;
-
                write_sysreg(0, pmselr_el0);
 
-               hctxt = host_data_ptr(host_ctxt);
                ctxt_sys_reg(hctxt, PMUSERENR_EL0) = read_sysreg(pmuserenr_el0);
                write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
                vcpu_set_flag(vcpu, PMUSERENR_ON_CPU);
@@ -269,6 +268,7 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
                        hcrx &= ~clr;
                }
 
+               ctxt_sys_reg(hctxt, HCRX_EL2) = read_sysreg_s(SYS_HCRX_EL2);
                write_sysreg_s(hcrx, SYS_HCRX_EL2);
        }
 
@@ -278,19 +278,18 @@ static inline void __activate_traps_common(struct kvm_vcpu *vcpu)
 
 static inline void __deactivate_traps_common(struct kvm_vcpu *vcpu)
 {
+       struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);
+
        write_sysreg(*host_data_ptr(host_debug_state.mdcr_el2), mdcr_el2);
 
        write_sysreg(0, hstr_el2);
        if (system_supports_pmuv3()) {
-               struct kvm_cpu_context *hctxt;
-
-               hctxt = host_data_ptr(host_ctxt);
                write_sysreg(ctxt_sys_reg(hctxt, PMUSERENR_EL0), pmuserenr_el0);
                vcpu_clear_flag(vcpu, PMUSERENR_ON_CPU);
        }
 
        if (cpus_have_final_cap(ARM64_HAS_HCX))
-               write_sysreg_s(HCRX_HOST_FLAGS, SYS_HCRX_EL2);
+               write_sysreg_s(ctxt_sys_reg(hctxt, HCRX_EL2), SYS_HCRX_EL2);
 
        __deactivate_traps_hfgxtr(vcpu);
        __deactivate_traps_mpam();