On Mon, Jul 20, 2026 at 12:07:29AM +0100, Mark Brown wrote: > At present when exiting from idle we do not fully reinitialise ZCR_EL1, > we update ZCR_EL1.LEN with a read/modify/write cycle when loading task > state but never set any of the other bits to an explicit value. Since > currently they are all architecturally RES0 or RAZ/WI this is not a > practical issue but it may become one if further fields are defined in > the register so we should explicitly configure the whole register. > > Rename the existing sme_suspend_exit() (which handles this for SME) to > fpsimd_suspend_exit() and add set ZCR_EL1 to 0 there, if needed LEN will > be updated when loading task state. > > Signed-off-by: Mark Brown <[email protected]>
While this happens to work today, this is a more general architecture problem, and I think we should cc stable such that kernels will work reliably on future hardware. All stable kernels support SVE, so this needs to go as far back as v5.10.y. One minor comment below, but with that fixed up (and a CC stable): Acked-by: Mark Rutland <[email protected]> > +void fpsimd_suspend_exit(void) > { > u64 smcr = 0; > > - if (!system_supports_sme()) > - return; > + if (system_supports_sve()) > + write_sysreg_s(0, SYS_ZCR_EL1); > > - if (system_supports_fa64()) > - smcr |= SMCR_ELx_FA64; > - if (system_supports_sme2()) > - smcr |= SMCR_ELx_EZT0; > + if (system_supports_sme()) { We should move the 'smcr' variable into this block. That way it's scoped to where it matters. > + if (system_supports_fa64()) > + smcr |= SMCR_ELx_FA64; > + if (system_supports_sme2()) > + smcr |= SMCR_ELx_EZT0; > > - write_sysreg_s(smcr, SYS_SMCR_EL1); > - write_sysreg_s(0, SYS_SMPRI_EL1); > + write_sysreg_s(smcr, SYS_SMCR_EL1); > + write_sysreg_s(0, SYS_SMPRI_EL1); > + } > } Mark.

