KVM: arm64: VHE: Centralize ISBs when returning to host
authorMark Rutland <mark.rutland@arm.com>
Tue, 17 Jun 2025 13:37:18 +0000 (14:37 +0100)
committerMarc Zyngier <maz@kernel.org>
Thu, 19 Jun 2025 12:34:59 +0000 (13:34 +0100)
The VHE hyp code has recently gained a few ISBs. Simplify this to one
unconditional ISB in __kvm_vcpu_run_vhe(), and remove the unnecessary
ISB from the kvm_call_hyp_ret() macro.

While kvm_call_hyp_ret() is also used to invoke
__vgic_v3_get_gic_config(), but no ISB is necessary in that case either.

For the moment, an ISB is left in kvm_call_hyp(), as there are many more
users, and removing the ISB would require a more thorough audit.

Suggested-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Fuad Tabba <tabba@google.com>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Mark Brown <broonie@kernel.org>
Cc: Oliver Upton <oliver.upton@linux.dev>
Cc: Will Deacon <will@kernel.org>
Link: https://lore.kernel.org/r/20250617133718.4014181-8-mark.rutland@arm.com
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/include/asm/kvm_host.h
arch/arm64/kvm/hyp/include/hyp/debug-sr.h
arch/arm64/kvm/hyp/vhe/switch.c

index 5ccca509dff1a5e96c8836c439053e21c192bde4..d27079968341c00ef98ffc47fb35d4737feef3af 100644 (file)
@@ -1289,9 +1289,8 @@ void kvm_arm_resume_guest(struct kvm *kvm);
        })
 
 /*
- * The couple of isb() below are there to guarantee the same behaviour
- * on VHE as on !VHE, where the eret to EL1 acts as a context
- * synchronization event.
+ * The isb() below is there to guarantee the same behaviour on VHE as on !VHE,
+ * where the eret to EL1 acts as a context synchronization event.
  */
 #define kvm_call_hyp(f, ...)                                           \
        do {                                                            \
@@ -1309,7 +1308,6 @@ void kvm_arm_resume_guest(struct kvm *kvm);
                                                                        \
                if (has_vhe()) {                                        \
                        ret = f(__VA_ARGS__);                           \
-                       isb();                                          \
                } else {                                                \
                        ret = kvm_call_hyp_nvhe(f, ##__VA_ARGS__);      \
                }                                                       \
index 73881e1dc26794f7a979a1157b4386e70fba5e69..502a5b73ee70c21f59bf00d19ab8450d2b14943c 100644 (file)
@@ -167,9 +167,6 @@ static inline void __debug_switch_to_host_common(struct kvm_vcpu *vcpu)
 
        __debug_save_state(guest_dbg, guest_ctxt);
        __debug_restore_state(host_dbg, host_ctxt);
-
-       if (has_vhe())
-               isb();
 }
 
 #endif /* __ARM64_KVM_HYP_DEBUG_SR_H__ */
index 32b4814eb2b7ac6968b76e479d745c639e84c4f5..477f1580ffeaa867ebb0e772c9d8a99c17e8c569 100644 (file)
@@ -558,10 +558,10 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
        host_ctxt = host_data_ptr(host_ctxt);
        guest_ctxt = &vcpu->arch.ctxt;
 
-       sysreg_save_host_state_vhe(host_ctxt);
-
        fpsimd_lazy_switch_to_guest(vcpu);
 
+       sysreg_save_host_state_vhe(host_ctxt);
+
        /*
         * Note that ARM erratum 1165522 requires us to configure both stage 1
         * and stage 2 translation for the guest context before we clear
@@ -586,18 +586,23 @@ static int __kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu)
 
        __deactivate_traps(vcpu);
 
-       /* Ensure CPTR trap deactivation has taken effect */
+       sysreg_restore_host_state_vhe(host_ctxt);
+
+       __debug_switch_to_host(vcpu);
+
+       /*
+        * Ensure that all system register writes above have taken effect
+        * before returning to the host. In VHE mode, CPTR traps for
+        * FPSIMD/SVE/SME also apply to EL2, so FPSIMD/SVE/SME state must be
+        * manipulated after the ISB.
+        */
        isb();
 
        fpsimd_lazy_switch_to_host(vcpu);
 
-       sysreg_restore_host_state_vhe(host_ctxt);
-
        if (guest_owns_fp_regs())
                __fpsimd_save_fpexc32(vcpu);
 
-       __debug_switch_to_host(vcpu);
-
        return exit_code;
 }
 NOKPROBE_SYMBOL(__kvm_vcpu_run_vhe);
@@ -627,12 +632,6 @@ int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
         */
        local_daif_restore(DAIF_PROCCTX_NOIRQ);
 
-       /*
-        * When we exit from the guest we change a number of CPU configuration
-        * parameters, such as traps.  We rely on the isb() in kvm_call_hyp*()
-        * to make sure these changes take effect before running the host or
-        * additional guests.
-        */
        return ret;
 }