On Mon, Feb 10, 2025 at 05:21:59PM +0000, Mark Rutland wrote: > On Mon, Feb 10, 2025 at 04:53:27PM +0000, Will Deacon wrote: > > On Thu, Feb 06, 2025 at 02:11:02PM +0000, Mark Rutland wrote: > > > +static inline void fpsimd_lazy_switch_to_host(struct kvm_vcpu *vcpu) > > > +{ > > > + u64 zcr_el1, zcr_el2; > > > + > > > + if (!guest_owns_fp_regs()) > > > + return; > > > + > > > + if (vcpu_has_sve(vcpu)) { > > > + zcr_el1 = read_sysreg_el1(SYS_ZCR); > > > + __vcpu_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_sve_max_vl) - 1; > > > + write_sysreg_el2(zcr_el2, SYS_ZCR); > > > + > > > + zcr_el1 = vcpu_sve_max_vq(vcpu) - 1; > > > + write_sysreg_el1(zcr_el1, SYS_ZCR); > > > > Do we need an ISB before this to make sure that the CPTR traps have been > > deactivated properly? > > Sorry, I had meant to add a comment here that this relies upon a > subtlety that avoids the need for the ISB. Ah yes, it really all hinges on guest_owns_fp_regs() and so I think a comment would be helpful, thanks. Just on this, though: > When the guest owns the FP regs here, we know: > > * If the guest doesn't have SVE, then we're not poking anything, and so > no ISB is necessary. > > * If the guest has SVE, then either: > > - The guest owned the FP regs when it was entered. > > - The guest *didn't* own the FP regs when it was entered, but acquired > ownership via a trap which executed kvm_hyp_handle_fpsimd(). > > ... and in either case, *after* disabling the traps there's been an > ERET to the guest and an exception back to hyp, either of which > provides the necessary context synchronization such that the traps are > disabled here. What about the case where we find that there's an interrupt pending on return to the guest? In that case, I think we elide the ERET and go back to the host (see the check of isr_el1 in hyp/entry.S). Will