[PATCH v12 12/29] KVM: arm64: Factor SVE code out of fpsimd_lazy_switch_to_host()

From: Mark Brown

Date: Thu Jul 09 2026 - 14:47:04 EST


Since the function will grow as a result of adding SME support move the
SVE code out of fpsimd_lazy_switch_to_host(). No functional change, just
code motion.

Reviewed-by: Jean-Philippe Brucker <jpb@xxxxxxxxxx>
Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
---
arch/arm64/kvm/hyp/include/hyp/switch.h | 48 ++++++++++++++++++---------------
1 file changed, 27 insertions(+), 21 deletions(-)

diff --git a/arch/arm64/kvm/hyp/include/hyp/switch.h b/arch/arm64/kvm/hyp/include/hyp/switch.h
index 33729e218c0a..e444f0a94dcf 100644
--- a/arch/arm64/kvm/hyp/include/hyp/switch.h
+++ b/arch/arm64/kvm/hyp/include/hyp/switch.h
@@ -519,11 +519,11 @@ static inline void fpsimd_lazy_switch_to_guest(struct kvm_vcpu *vcpu)
}
}

-static inline void fpsimd_lazy_switch_to_host(struct kvm_vcpu *vcpu)
+static inline void sve_lazy_switch_to_host(struct kvm_vcpu *vcpu)
{
u64 zcr_el1, zcr_el2;

- if (!guest_owns_fp_regs())
+ if (!vcpu_has_sve(vcpu))
return;

/*
@@ -534,29 +534,35 @@ static inline void fpsimd_lazy_switch_to_host(struct kvm_vcpu *vcpu)
* synchronization event, we don't need an ISB here to avoid taking
* traps for anything that was exposed to the guest.
*/
- if (vcpu_has_sve(vcpu)) {
- zcr_el1 = read_sysreg_el1(SYS_ZCR);
- __vcpu_assign_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu), zcr_el1);
+ zcr_el1 = read_sysreg_el1(SYS_ZCR);
+ __vcpu_assign_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu), zcr_el1);

- /*
- * The guest's state is always saved using the guest's max VL.
- * Ensure that the host has the guest's max VL active such that
- * the host can save the guest's state lazily, but don't
- * artificially restrict the host to the guest's max VL.
- */
- if (has_vhe()) {
- zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
- write_sysreg_el2(zcr_el2, SYS_ZCR);
- } else {
- zcr_el2 = sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1;
- write_sysreg_el2(zcr_el2, SYS_ZCR);
-
- zcr_el1 = vcpu_sve_max_vq(vcpu) - 1;
- write_sysreg_el1(zcr_el1, SYS_ZCR);
- }
+ /*
+ * The guest's state is always saved using the guest's max VL.
+ * Ensure that the host has the guest's max VL active such
+ * that the host can save the guest's state lazily, but don't
+ * artificially restrict the host to the guest's max VL.
+ */
+ if (has_vhe()) {
+ zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
+ write_sysreg_el2(zcr_el2, SYS_ZCR);
+ } else {
+ zcr_el2 = sve_vq_from_vl(kvm_host_max_vl[ARM64_VEC_SVE]) - 1;
+ write_sysreg_el2(zcr_el2, SYS_ZCR);
+
+ zcr_el1 = vcpu_sve_max_vq(vcpu) - 1;
+ write_sysreg_el1(zcr_el1, SYS_ZCR);
}
}

+static inline void fpsimd_lazy_switch_to_host(struct kvm_vcpu *vcpu)
+{
+ if (!guest_owns_fp_regs())
+ return;
+
+ sve_lazy_switch_to_host(vcpu);
+}
+
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
{
struct kvm_cpu_context *hctxt = host_data_ptr(host_ctxt);

--
2.47.3