Patch "arm64/fpsimd: Only provide the length to cpufeature for xCR registers" has been added to the 6.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    arm64/fpsimd: Only provide the length to cpufeature for xCR registers

to the 6.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     arm64-fpsimd-only-provide-the-length-to-cpufeature-f.patch
and it can be found in the queue-6.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 44740be2638143d1fbc51759642f78ceeb7d0eff
Author: Mark Brown <broonie@xxxxxxxxxx>
Date:   Mon Jul 31 14:58:48 2023 +0100

    arm64/fpsimd: Only provide the length to cpufeature for xCR registers
    
    [ Upstream commit 01948b09edc3fecf8486c57c2d2fb8b80886f3d0 ]
    
    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, if we're doing that we don't need to
    bother reading the register at all and can simply use the RDVL/RDSVL
    value we were filling in instead.
    
    Fixes: 2e0f2478ea37 ("arm64/sve: Probe SVE capabilities and usable vector lengths")
    FixeS: b42990d3bf77 ("arm64/sme: Identify supported SME vector lengths at boot")
    Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
    Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx>
    Link: https://lore.kernel.org/r/20230731-arm64-sme-fa64-hotplug-v2-1-7714c00dd902@xxxxxxxxxx
    Signed-off-by: Will Deacon <will@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
index 087c05aa960ea..91e44ac7150f9 100644
--- a/arch/arm64/kernel/fpsimd.c
+++ b/arch/arm64/kernel/fpsimd.c
@@ -1179,9 +1179,6 @@ void sve_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
  */
 u64 read_zcr_features(void)
 {
-	u64 zcr;
-	unsigned int vq_max;
-
 	/*
 	 * Set the maximum possible VL, and write zeroes to all other
 	 * bits to see if they stick.
@@ -1189,12 +1186,8 @@ u64 read_zcr_features(void)
 	sve_kernel_enable(NULL);
 	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 */
-	vq_max = sve_vq_from_vl(sve_get_vl());
-	zcr |= vq_max - 1; /* set LEN field to maximum effective value */
-
-	return zcr;
+	/* Return LEN value that would be written to get the maximum VL */
+	return sve_vq_from_vl(sve_get_vl()) - 1;
 }
 
 void __init sve_setup(void)
@@ -1349,9 +1342,6 @@ void fa64_kernel_enable(const struct arm64_cpu_capabilities *__always_unused p)
  */
 u64 read_smcr_features(void)
 {
-	u64 smcr;
-	unsigned int vq_max;
-
 	sme_kernel_enable(NULL);
 
 	/*
@@ -1360,12 +1350,8 @@ u64 read_smcr_features(void)
 	write_sysreg_s(read_sysreg_s(SYS_SMCR_EL1) | SMCR_ELx_LEN_MASK,
 		       SYS_SMCR_EL1);
 
-	smcr = read_sysreg_s(SYS_SMCR_EL1);
-	smcr &= ~(u64)SMCR_ELx_LEN_MASK; /* Only the LEN field */
-	vq_max = sve_vq_from_vl(sme_get_vl());
-	smcr |= vq_max - 1; /* set LEN field to maximum effective value */
-
-	return smcr;
+	/* Return LEN value that would be written to get the maximum VL */
+	return sve_vq_from_vl(sme_get_vl()) - 1;
 }
 
 void __init sme_setup(void)



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux