* [PATCH v4 0/2] arm64: Clamp ID overrides and gate the GMID_EL1 read
@ 2026-08-25 16:42 Fuad Tabba
2026-08-25 16:42 ` [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities Fuad Tabba
2026-08-25 16:42 ` [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled Fuad Tabba
0 siblings, 2 replies; 8+ messages in thread
From: Fuad Tabba @ 2026-08-25 16:42 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon, linux-arm-kernel
Cc: Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose,
Mark Brown, kvmarm, linux-kernel, Fuad Tabba
Hi folks,
Changes since v3 [1]:
- Gate on __read_sysreg_by_encoding() and drop the helper's argument,
so the command-line override is not open-coded in the header.
(Catalin)
- Pick up Suzuki's override clamp as patch 1, rather than adding a
raw-presence check to the gate. (Will)
Patch 2 fixes a GMID_EL1 read that traps to EL2 when the kernel has
disabled MTE, panicking the host under pKVM on a CPU that is offlined
and brought back online. It gates the read on
__read_sysreg_by_encoding().
That needs patch 1, Suzuki's override clamp [2]. Without it
__read_sysreg_by_encoding() applies the command-line override raw, so
id_aa64pfr1.mte=2 on a CPU without FEAT_MTE2 makes the gate true and the
kernel reads a GMID_EL1 that is not there. On the boot CPU that read
comes before init_cpu_ftr_reg() strips the unsafe override, so the gate
cannot rely on it.
Tested on QEMU under pKVM. With -machine virt,mte=on, offlining and
onlining CPU1 with arm64.nomte panics an unpatched v7.2 in
__cpuinfo_store_cpu() and does not with the series. Without tag memory,
where QEMU implements no GMID_EL1, id_aa64pfr1.mte=2 covers the
force-up case.
Based on Linux 7.2 (8d3ae59288f1e).
Cheers,
/fuad
[1] https://lore.kernel.org/all/20260824184155.2644646-1-fuad.tabba@linux.dev/
[2] https://lore.kernel.org/all/afc5bd00-28ca-413b-b047-ee53589c285d@arm.com/
Fuad Tabba (1):
arm64: Don't read GMID_EL1 when MTE is disabled
Suzuki K Poulose (1):
arm64: Apply overrides to CPU local capabilities
arch/arm64/include/asm/cpufeature.h | 9 ++++++
arch/arm64/kernel/cpufeature.c | 48 +++++++++++++++++++++--------
arch/arm64/kernel/cpuinfo.c | 2 +-
3 files changed, 46 insertions(+), 13 deletions(-)
--
2.39.5
^ permalink raw reply [flat|nested] 8+ messages in thread* [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities 2026-08-25 16:42 [PATCH v4 0/2] arm64: Clamp ID overrides and gate the GMID_EL1 read Fuad Tabba @ 2026-08-25 16:42 ` Fuad Tabba 2026-08-26 13:47 ` Catalin Marinas 2026-08-25 16:42 ` [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled Fuad Tabba 1 sibling, 1 reply; 8+ messages in thread From: Fuad Tabba @ 2026-08-25 16:42 UTC (permalink / raw) To: Catalin Marinas, Will Deacon, linux-arm-kernel Cc: Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba From: Suzuki K Poulose <suzuki.poulose@arm.com> If an override has been applied, make sure we apply that for the secondary CPUs too, to limit the features. Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> Link: https://lore.kernel.org/all/afc5bd00-28ca-413b-b047-ee53589c285d@arm.com/ Cc: stable@vger.kernel.org [Fuad: whitespace and comment fixes] Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev> --- arch/arm64/kernel/cpufeature.c | 42 +++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 9a22df0c5120f..88b15b5ef2f7f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1232,10 +1232,43 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); } +/* + * Sanitise the register fields to clamp the values to the overrides that + * have been applied. + */ +static u64 override_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 val) +{ + const struct arm64_ftr_bits *ftrp; + + if (!reg || !reg->override->mask) + return val; + + for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) { + u64 ftr_mask = arm64_ftr_mask(ftrp); + s64 ftr_val, ftr_ovr, ftr_safe; + + /* Skip the fields not overridden */ + if ((ftr_mask & reg->override->mask) != ftr_mask) + continue; + + ftr_val = arm64_ftr_value(ftrp, val); + ftr_ovr = arm64_ftr_value(ftrp, reg->override->val); + ftr_safe = arm64_ftr_safe_value(ftrp, ftr_ovr, ftr_val); + + if (ftr_safe != ftr_val) + val = arm64_ftr_set_value(ftrp, val, ftr_safe); + } + + return val; +} + static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new) { const struct arm64_ftr_bits *ftrp; + /* Apply the overrides */ + new = override_cpu_ftr_reg(reg, new); + for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) { s64 ftr_cur = arm64_ftr_value(ftrp, reg->sys_val); s64 ftr_new = arm64_ftr_value(ftrp, new); @@ -1539,7 +1572,6 @@ EXPORT_SYMBOL_GPL(read_sanitised_ftr_reg); */ u64 __read_sysreg_by_encoding(u32 sys_id) { - struct arm64_ftr_reg *regp; u64 val; switch (sys_id) { @@ -1592,13 +1624,7 @@ u64 __read_sysreg_by_encoding(u32 sys_id) return 0; } - regp = get_arm64_ftr_reg(sys_id); - if (regp) { - val &= ~regp->override->mask; - val |= (regp->override->val & regp->override->mask); - } - - return val; + return override_cpu_ftr_reg(get_arm64_ftr_reg(sys_id), val); } #include <linux/irqchip/arm-gic-v3.h> -- 2.39.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities 2026-08-25 16:42 ` [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities Fuad Tabba @ 2026-08-26 13:47 ` Catalin Marinas 2026-08-27 8:58 ` Fuad Tabba 0 siblings, 1 reply; 8+ messages in thread From: Catalin Marinas @ 2026-08-26 13:47 UTC (permalink / raw) To: Fuad Tabba Cc: Will Deacon, linux-arm-kernel, Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba On Tue, Aug 25, 2026 at 05:42:18PM +0100, Fuad Tabba wrote: > From: Suzuki K Poulose <suzuki.poulose@arm.com> > > If an override has been applied, make sure we apply that for the > secondary CPUs too, to limit the features. > > Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com> > Link: https://lore.kernel.org/all/afc5bd00-28ca-413b-b047-ee53589c285d@arm.com/ > Cc: stable@vger.kernel.org > [Fuad: whitespace and comment fixes] > Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev> For completeness, we should add: Fixes: b3341ae0efa2 ("arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()") > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 9a22df0c5120f..88b15b5ef2f7f 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -1232,10 +1232,43 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) > init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); > } > > +/* > + * Sanitise the register fields to clamp the values to the overrides that > + * have been applied. > + */ > +static u64 override_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 val) > +{ > + const struct arm64_ftr_bits *ftrp; > + > + if (!reg || !reg->override->mask) > + return val; > + > + for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) { > + u64 ftr_mask = arm64_ftr_mask(ftrp); > + s64 ftr_val, ftr_ovr, ftr_safe; > + > + /* Skip the fields not overridden */ > + if ((ftr_mask & reg->override->mask) != ftr_mask) > + continue; > + > + ftr_val = arm64_ftr_value(ftrp, val); > + ftr_ovr = arm64_ftr_value(ftrp, reg->override->val); > + ftr_safe = arm64_ftr_safe_value(ftrp, ftr_ovr, ftr_val); > + > + if (ftr_safe != ftr_val) > + val = arm64_ftr_set_value(ftrp, val, ftr_safe); > + } > + > + return val; > +} > + > static void update_cpu_ftr_reg(struct arm64_ftr_reg *reg, u64 new) > { > const struct arm64_ftr_bits *ftrp; > > + /* Apply the overrides */ > + new = override_cpu_ftr_reg(reg, new); Not sure we need this. The init value has already been clamped, made safe, so it won't change the result. Otherwise: Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities 2026-08-26 13:47 ` Catalin Marinas @ 2026-08-27 8:58 ` Fuad Tabba 0 siblings, 0 replies; 8+ messages in thread From: Fuad Tabba @ 2026-08-27 8:58 UTC (permalink / raw) To: Catalin Marinas Cc: Will Deacon, linux-arm-kernel, Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel Hi Catalin, On Wed, 26 Aug 2026 at 14:47, Catalin Marinas <catalin.marinas@arm.com> wrote: ... > For completeness, we should add: > > Fixes: b3341ae0efa2 ("arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()") Ack ... > > + /* Apply the overrides */ > > + new = override_cpu_ftr_reg(reg, new); > > Not sure we need this. The init value has already been clamped, made > safe, so it won't change the result. I'll fix both on the respin. I'll wait to see if Will or anyone else has further comments before doing that. > Otherwise: > > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Thanks for the reviews! /fuad ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled 2026-08-25 16:42 [PATCH v4 0/2] arm64: Clamp ID overrides and gate the GMID_EL1 read Fuad Tabba 2026-08-25 16:42 ` [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities Fuad Tabba @ 2026-08-25 16:42 ` Fuad Tabba 2026-08-26 13:48 ` Catalin Marinas 2026-08-27 12:56 ` Will Deacon 1 sibling, 2 replies; 8+ messages in thread From: Fuad Tabba @ 2026-08-25 16:42 UTC (permalink / raw) To: Catalin Marinas, Will Deacon, linux-arm-kernel Cc: Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba __cpuinfo_store_cpu() gates the GMID_EL1 read on the raw ID_AA64PFR1_EL1, so it reads the register even when the kernel has disabled MTE (CONFIG_ARM64_MTE=n or arm64.nomte). KVM sets HCR_EL2.TID5 in that case, and pKVM injects an UNDEF the host cannot handle: Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP pc : __cpuinfo_store_cpu+0xf4/0x264 Kernel panic - not syncing: Attempted to kill the idle task! Only pKVM reaches it, and only after a CPU is offlined and brought back online: its CPU_ON relay sets the host HCR before the CPU enters EL1, while plain nVHE sets it at CPUHP_AP_KVM_ONLINE. Gate the read on __read_sysreg_by_encoding(), which applies the cmdline override, and on CONFIG_ARM64_MTE, which no register reflects. Fixes: f35abcbb8a084 ("KVM: arm64: Trap MTE access and discovery when MTE is disabled") Cc: stable@vger.kernel.org # needs "arm64: Apply overrides to CPU local capabilities" Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev> --- arch/arm64/include/asm/cpufeature.h | 9 +++++++++ arch/arm64/kernel/cpufeature.c | 6 ++---- arch/arm64/kernel/cpuinfo.c | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h index a57870fa96db5..0b374e938f708 100644 --- a/arch/arm64/include/asm/cpufeature.h +++ b/arch/arm64/include/asm/cpufeature.h @@ -1085,6 +1085,15 @@ static inline bool cpu_has_lpa2(void) #endif } +/* No ID register reflects CONFIG_ARM64_MTE. */ +static inline bool gmid_el1_accessible(void) +{ + if (!IS_ENABLED(CONFIG_ARM64_MTE)) + return false; + + return id_aa64pfr1_mte(__read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1)); +} + #endif /* __ASSEMBLER__ */ #endif diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 88b15b5ef2f7f..23f174b3c4e26 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -1228,7 +1228,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr); } - if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) + if (gmid_el1_accessible()) init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); } @@ -1523,11 +1523,9 @@ void update_cpu_features(int cpu, * they read/write depends on the GMID_EL1.BS field. Check that the * value is the same on all CPUs. */ - if (IS_ENABLED(CONFIG_ARM64_MTE) && - id_aa64pfr1_mte(info->reg_id_aa64pfr1)) { + if (gmid_el1_accessible()) taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu, info->reg_gmid, boot->reg_gmid); - } /* * If we don't have AArch32 at all then skip the checks entirely diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index d50e2a9b066b3..389fca84f106b 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1); info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1); - if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) + if (gmid_el1_accessible()) info->reg_gmid = read_cpuid(GMID_EL1); if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0)) -- 2.39.5 ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled 2026-08-25 16:42 ` [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled Fuad Tabba @ 2026-08-26 13:48 ` Catalin Marinas 2026-08-27 12:56 ` Will Deacon 1 sibling, 0 replies; 8+ messages in thread From: Catalin Marinas @ 2026-08-26 13:48 UTC (permalink / raw) To: Fuad Tabba Cc: Will Deacon, linux-arm-kernel, Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba On Tue, Aug 25, 2026 at 05:42:19PM +0100, Fuad Tabba wrote: > __cpuinfo_store_cpu() gates the GMID_EL1 read on the raw > ID_AA64PFR1_EL1, so it reads the register even when the kernel has > disabled MTE (CONFIG_ARM64_MTE=n or arm64.nomte). KVM sets HCR_EL2.TID5 > in that case, and pKVM injects an UNDEF the host cannot handle: > > Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP > pc : __cpuinfo_store_cpu+0xf4/0x264 > Kernel panic - not syncing: Attempted to kill the idle task! > > Only pKVM reaches it, and only after a CPU is offlined and brought back > online: its CPU_ON relay sets the host HCR before the CPU enters EL1, > while plain nVHE sets it at CPUHP_AP_KVM_ONLINE. > > Gate the read on __read_sysreg_by_encoding(), which applies the cmdline > override, and on CONFIG_ARM64_MTE, which no register reflects. > > Fixes: f35abcbb8a084 ("KVM: arm64: Trap MTE access and discovery when MTE is disabled") > Cc: stable@vger.kernel.org # needs "arm64: Apply overrides to CPU local capabilities" > Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled 2026-08-25 16:42 ` [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled Fuad Tabba 2026-08-26 13:48 ` Catalin Marinas @ 2026-08-27 12:56 ` Will Deacon 2026-08-27 13:19 ` Will Deacon 1 sibling, 1 reply; 8+ messages in thread From: Will Deacon @ 2026-08-27 12:56 UTC (permalink / raw) To: Fuad Tabba Cc: Catalin Marinas, linux-arm-kernel, Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba On Tue, Aug 25, 2026 at 05:42:19PM +0100, Fuad Tabba wrote: > __cpuinfo_store_cpu() gates the GMID_EL1 read on the raw > ID_AA64PFR1_EL1, so it reads the register even when the kernel has > disabled MTE (CONFIG_ARM64_MTE=n or arm64.nomte). KVM sets HCR_EL2.TID5 > in that case, and pKVM injects an UNDEF the host cannot handle: > > Internal error: Oops - Undefined instruction: 0000000002000000 [#1] SMP > pc : __cpuinfo_store_cpu+0xf4/0x264 > Kernel panic - not syncing: Attempted to kill the idle task! > > Only pKVM reaches it, and only after a CPU is offlined and brought back > online: its CPU_ON relay sets the host HCR before the CPU enters EL1, > while plain nVHE sets it at CPUHP_AP_KVM_ONLINE. > > Gate the read on __read_sysreg_by_encoding(), which applies the cmdline > override, and on CONFIG_ARM64_MTE, which no register reflects. > > Fixes: f35abcbb8a084 ("KVM: arm64: Trap MTE access and discovery when MTE is disabled") > Cc: stable@vger.kernel.org # needs "arm64: Apply overrides to CPU local capabilities" > Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev> > --- > arch/arm64/include/asm/cpufeature.h | 9 +++++++++ > arch/arm64/kernel/cpufeature.c | 6 ++---- > arch/arm64/kernel/cpuinfo.c | 2 +- > 3 files changed, 12 insertions(+), 5 deletions(-) > > diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h > index a57870fa96db5..0b374e938f708 100644 > --- a/arch/arm64/include/asm/cpufeature.h > +++ b/arch/arm64/include/asm/cpufeature.h > @@ -1085,6 +1085,15 @@ static inline bool cpu_has_lpa2(void) > #endif > } > > +/* No ID register reflects CONFIG_ARM64_MTE. */ > +static inline bool gmid_el1_accessible(void) > +{ > + if (!IS_ENABLED(CONFIG_ARM64_MTE)) > + return false; > + > + return id_aa64pfr1_mte(__read_sysreg_by_encoding(SYS_ID_AA64PFR1_EL1)); I'm planning to internalise __read_sysreg_by_encoding() into cpufeature.c so I'd prefer to avoid adding another user of it, if possible. In this case, __cpuinfo_store_cpu() has already read the thing, so all it needs is the override logic (but see below). > +} > + > #endif /* __ASSEMBLER__ */ > > #endif > diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c > index 88b15b5ef2f7f..23f174b3c4e26 100644 > --- a/arch/arm64/kernel/cpufeature.c > +++ b/arch/arm64/kernel/cpufeature.c > @@ -1228,7 +1228,7 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info) > init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr); > } > > - if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) > + if (gmid_el1_accessible()) > init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid); > } > > @@ -1523,11 +1523,9 @@ void update_cpu_features(int cpu, > * they read/write depends on the GMID_EL1.BS field. Check that the > * value is the same on all CPUs. > */ > - if (IS_ENABLED(CONFIG_ARM64_MTE) && > - id_aa64pfr1_mte(info->reg_id_aa64pfr1)) { > + if (gmid_el1_accessible()) > taint |= check_update_ftr_reg(SYS_GMID_EL1, cpu, > info->reg_gmid, boot->reg_gmid); > - } > > /* > * If we don't have AArch32 at all then skip the checks entirely > diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c > index d50e2a9b066b3..389fca84f106b 100644 > --- a/arch/arm64/kernel/cpuinfo.c > +++ b/arch/arm64/kernel/cpuinfo.c > @@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) > info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1); > info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1); > > - if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) > + if (gmid_el1_accessible()) > info->reg_gmid = read_cpuid(GMID_EL1); I'm not sure this is safe. For the boot CPU, __cpuinfo_store_cpu() is called before init_cpu_features(), so the arm64_ftr_regs[] array hasn't been sorted and we can't call get_arm64_ftr_reg() reliably. In fact, it doesn't even look like the overrides will have been processed. So we're in a bit of a chicken-and-egg problem here. Perhaps we need an early (__init) function that can apply the override manually to the value read from hardware using arm64_ftr_safe_value(). You'll probably need something like my old hack [1] to avoid the bsearch though :/ Will [1] https://lore.kernel.org/all/20230110161651.GB9436@willie-the-truck/ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled 2026-08-27 12:56 ` Will Deacon @ 2026-08-27 13:19 ` Will Deacon 0 siblings, 0 replies; 8+ messages in thread From: Will Deacon @ 2026-08-27 13:19 UTC (permalink / raw) To: Fuad Tabba Cc: Catalin Marinas, linux-arm-kernel, Marc Zyngier, Oliver Upton, Mark Rutland, Suzuki K Poulose, Mark Brown, kvmarm, linux-kernel, Fuad Tabba On Thu, Aug 27, 2026 at 01:56:35PM +0100, Will Deacon wrote: > On Tue, Aug 25, 2026 at 05:42:19PM +0100, Fuad Tabba wrote: > > diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c > > index d50e2a9b066b3..389fca84f106b 100644 > > --- a/arch/arm64/kernel/cpuinfo.c > > +++ b/arch/arm64/kernel/cpuinfo.c > > @@ -502,7 +502,7 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info) > > info->reg_id_aa64smfr0 = read_cpuid(ID_AA64SMFR0_EL1); > > info->reg_id_aa64fpfr0 = read_cpuid(ID_AA64FPFR0_EL1); > > > > - if (id_aa64pfr1_mte(info->reg_id_aa64pfr1)) > > + if (gmid_el1_accessible()) > > info->reg_gmid = read_cpuid(GMID_EL1); > > I'm not sure this is safe. For the boot CPU, __cpuinfo_store_cpu() is > called before init_cpu_features(), so the arm64_ftr_regs[] array hasn't > been sorted and we can't call get_arm64_ftr_reg() reliably. In fact, it > doesn't even look like the overrides will have been processed. > > So we're in a bit of a chicken-and-egg problem here. Perhaps we need an > early (__init) function that can apply the override manually to the > value read from hardware using arm64_ftr_safe_value(). You'll probably > need something like my old hack [1] to avoid the bsearch though :/ Thinking about this for a few more minutes, perhaps the best option for a quick fix would be to: - Internalise gmid_el1_accessible() in cpufeature.c and take cpuinfo * as a parameter - It could then refer directly to the ftr reg, along the lines of: val = arm64_ftr_safe_value(&ftr_id_aa64pfr1, <value from id_aa64pfr1_override>, <value from cpuinfo>); - Then check val before accessing the gmid. Then we can fix all this properly in the future by moving the override stuff earlier. Will ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-27 13:20 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-25 16:42 [PATCH v4 0/2] arm64: Clamp ID overrides and gate the GMID_EL1 read Fuad Tabba 2026-08-25 16:42 ` [PATCH v4 1/2] arm64: Apply overrides to CPU local capabilities Fuad Tabba 2026-08-26 13:47 ` Catalin Marinas 2026-08-27 8:58 ` Fuad Tabba 2026-08-25 16:42 ` [PATCH v4 2/2] arm64: Don't read GMID_EL1 when MTE is disabled Fuad Tabba 2026-08-26 13:48 ` Catalin Marinas 2026-08-27 12:56 ` Will Deacon 2026-08-27 13:19 ` Will Deacon
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox