[PATCH] arm64/cache: Fix cache_type_cwg() for register generation
Mark Rutland
mark.rutland at arm.com
Wed Aug 17 10:25:35 PDT 2022
On Wed, Aug 17, 2022 at 05:56:24PM +0100, Mark Rutland wrote:
> On Wed, Aug 17, 2022 at 05:02:46PM +0100, Mark Brown wrote:
> > Ard noticed that since we converted CTR_EL0 to automatic generation we have
> > been seeing errors on some systems handling the value of cache_type_cwg()
> > such as
> >
> > CPU features: No Cache Writeback Granule information, assuming 128
> >
> > This is because the manual definition of CTR_EL0_CWG_MASK was done without
> > a shift while our convention is to define the mask after shifting. This
> > means that the user in cache_type_cwg() was broken as it was written for
> > the manually written shift then mask. Fix this by reversing, we don't use
> > SYS_FIELD_GET() since that is defined in sysreg.h which we don't want to
> > include in cache.h.
> >
> > The only other field where the _MASK for this register is used is IminLine
> > which is at offset 0 so unaffected.
> >
> > Fixes: 9a3634d02301 ("arm64/sysreg: Convert CTR_EL0 to automatic generation")
> > Reported-by: Ard Biesheuvel <ardb at kernel.org>
> > Signed-off-by: Mark Brown <broonie at kernel.org>
> > ---
> > arch/arm64/include/asm/cache.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
> > index 119e4aa02eb1..8445a3213b2f 100644
> > --- a/arch/arm64/include/asm/cache.h
> > +++ b/arch/arm64/include/asm/cache.h
> > @@ -67,7 +67,7 @@ static __always_inline int icache_is_vpipt(void)
> >
> > static inline u32 cache_type_cwg(void)
> > {
> > - return (read_cpuid_cachetype() >> CTR_EL0_CWG_SHIFT) & CTR_EL0_CWG_MASK;
> > + return (read_cpuid_cachetype() & CTR_EL0_CWG_MASK) >> CTR_EL0_CWG_SHIFT;
> > }
>
> Can we follow the example of:
>
> 5b345e39d3ebc213 ("arm64/sysreg: Standardise naming for CTR_EL0 fields")
>
> ... and instead have:
>
> | #define CTR_CWG(ctr) SYS_FIELD_GET(CTR_EL0, CWG, ctr)
>
> ... and:
>
> | static inline u32 cache_type_cwg(void)
> | {
> | return CTR_CWG(read_cpuid_cachetype());
> | }
>
> ... since AFAICT we had SYS_FIELD_GET() available in commit
>
> 9a3634d02301 ("arm64/sysreg: Convert CTR_EL0 to automatic generation")
>
> ... and then it's all consistent and there's no confusion about how to apply
> MASK and SHIFT.
>
> With that:
>
> Acked-by: Mark Rutland <mark.rutland at arm.com>
Ah; I see that blows up because we're missing an include for
<linux/bitfield.h>. We'll need to fix sysreg.h too, e.g. as below.
Mark.
---->8----
diff --git a/arch/arm64/include/asm/cache.h b/arch/arm64/include/asm/cache.h
index ca9b487112ccb..794fe2652cded 100644
--- a/arch/arm64/include/asm/cache.h
+++ b/arch/arm64/include/asm/cache.h
@@ -50,6 +50,7 @@ static inline unsigned int arch_slab_minalign(void)
CTR_EL0_IMINLINE_MASK << CTR_EL0_IMINLINE_SHIFT)
#define CTR_L1IP(ctr) SYS_FIELD_GET(CTR_EL0, L1Ip, ctr)
+#define CTR_CWG(ctr) SYS_FIELD_GET(CTR_EL0, CWG, ctr)
#define ICACHEF_ALIASING 0
#define ICACHEF_VPIPT 1
@@ -71,7 +72,7 @@ static __always_inline int icache_is_vpipt(void)
static inline u32 cache_type_cwg(void)
{
- return (read_cpuid_cachetype() >> CTR_EL0_CWG_SHIFT) & CTR_EL0_CWG_MASK;
+ return CTR_CWG(read_cpuid_cachetype());
}
#define __read_mostly __section(".data..read_mostly")
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 7c71358d44c4a..7d806d1769d84 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -1116,6 +1116,7 @@
#else
+#include <linux/bitfield.h>
#include <linux/build_bug.h>
#include <linux/types.h>
#include <asm/alternative.h>
@@ -1209,8 +1210,6 @@
par; \
})
-#endif
-
#define SYS_FIELD_GET(reg, field, val) \
FIELD_GET(reg##_##field##_MASK, val)
@@ -1220,4 +1219,6 @@
#define SYS_FIELD_PREP_ENUM(reg, field, val) \
FIELD_PREP(reg##_##field##_MASK, reg##_##field##_##val)
+#endif /* __ASSEMBLY__ */
+
#endif /* __ASM_SYSREG_H */
More information about the linux-arm-kernel
mailing list