Commit 04c5355b authored by Mark Rutland's avatar Mark Rutland Committed by Marc Zyngier
Browse files

KVM: arm64: VHE: Centralize ISBs when returning to host



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: default avatarMarc Zyngier <maz@kernel.org>
Signed-off-by: default avatarMark 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: default avatarMarc Zyngier <maz@kernel.org>
parent 3a300a33
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -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__);	\
		}							\
+0 −3
Original line number Diff line number Diff line
@@ -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__ */
+12 −13
Original line number Diff line number Diff line
@@ -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;
}