Messages in this thread Patch in this message | | | Date | Wed, 2 Aug 2023 12:21:23 +0100 | From | Will Deacon <> | Subject | Re: [PATCH] arm64/fpsimd: Only provide the length to cpufeature for xCR registers |
| |
On Thu, Jul 27, 2023 at 10:31:44PM +0100, Mark Brown wrote: > For both SVE and SME we abuse the generic register field comparison > support in the cpufeature code as part of our detection of unsupported > variations in the vector lengths available to PEs, reporting the maximum > vector lengths via ZCR_EL1.LEN and SMCR_EL1.LEN. Since these are > configuration registers rather than identification registers the > assumptions the cpufeature code makes about how unknown bitfields behave > are invalid, leading to warnings when SME features like FA64 are enabled > and we hotplug a CPU: > > CPU features: SANITY CHECK: Unexpected variation in SYS_SMCR_EL1. Boot CPU: 0x0000000000000f, CPU3: 0x0000008000000f > CPU features: Unsupported CPU feature variation detected. > > SVE has no controls other than the vector length so is not yet impacted > but the same issue will apply there if any are defined. > > Since the only field we are interested in having the cpufeature code > handle is the length field and we use a custom read function to obtain > the value we can avoid these warnings by filtering out all other bits > when we return the register value. > > Fixes: 2e0f2478ea37eb ("arm64/sve: Probe SVE capabilities and usable vector lengths") > FixeS: b42990d3bf77cc ("arm64/sme: Identify supported SME vector lengths at boot") > Signed-off-by: Mark Brown <broonie@kernel.org> > --- > arch/arm64/kernel/fpsimd.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c > index 89d54a5242d1..c7fdeebd050c 100644 > --- a/arch/arm64/kernel/fpsimd.c > +++ b/arch/arm64/kernel/fpsimd.c > @@ -1189,11 +1189,11 @@ u64 read_zcr_features(void) > write_sysreg_s(ZCR_ELx_LEN_MASK, SYS_ZCR_EL1); > > zcr = read_sysreg_s(SYS_ZCR_EL1); > - zcr &= ~(u64)ZCR_ELx_LEN_MASK; /* find sticky 1s outside LEN field */ > + zcr &= ~(u64)ZCR_ELx_LEN_MASK; > vq_max = sve_vq_from_vl(sve_get_vl()); > zcr |= vq_max - 1; /* set LEN field to maximum effective value */ > > - return zcr; > + return SYS_FIELD_GET(ZCR_ELx, LEN, zcr);
Hmm, now this function looks like a mixture of code which relies on the LEN field living at the bottom of the register and code which is agnostic to that.
Can we update the 'zcr |= vq_max - 1' part to use something like FIELD_PREP() instead?
> } > > void __init sve_setup(void) > @@ -1364,7 +1364,7 @@ u64 read_smcr_features(void) > vq_max = sve_vq_from_vl(sme_get_vl()); > smcr |= vq_max - 1; /* set LEN field to maximum effective value */ > > - return smcr; > + return SYS_FIELD_GET(SMCR_ELx, LEN, smcr);
It looks like there's a similar thing here.
Will
| |