Re: [PATCH] arm64: Defer the GMID_EL1 read to {init,update}_cpu_features()

From: Will Deacon

Date: Mon Aug 24 2026 - 09:14:48 EST


On Sun, Aug 23, 2026 at 02:09:02PM +0100, Fuad Tabba wrote:
> On Sat, 22 Aug 2026 at 10:13, Marc Zyngier <maz@xxxxxxxxxx> wrote:
> > On Wed, 19 Aug 2026 15:25:58 +0100,
> > Fuad Tabba <fuad.tabba@xxxxxxxxx> wrote:
> > >
> > > __cpuinfo_store_cpu() gates the GMID_EL1 read on the raw
> > > ID_AA64PFR1_EL1, so it reads the register on MTE hardware even when the
> > > kernel has disabled MTE (CONFIG_ARM64_MTE=n or arm64.nomte). KVM sets
> > > HCR_EL2.TID5 in that case, which traps the read to EL2 and injects an
> > > UNDEF:
> > >
> > > Internal error: Oops - Undefined instruction: 0000000002000000 [#1]
> > > pc : __cpuinfo_store_cpu+0xf4/0x264
> > > Call trace:
> > > __cpuinfo_store_cpu+0xf4/0x264 (P)
> > > secondary_start_kernel+0xc8/0x1d0
> > > __secondary_switched+0xc0/0xc4
> > > Kernel panic - not syncing: Attempted to kill the idle task!
> > >
> > > Only pKVM is affected, and only for a CPU onlined after KVM init: its
> >
> > Is that for a CPU that has gone through a an offline/online cycle?
> > Because otherwise, such a CPU wouldn't be able to boot at all (we have
> > a strong requirement that pKVM sees all CPUs at boot time).
> >
> > If that's the case, some clarification would be good. Otherwise, some
> > clarification is absolutely required! ;-)
>
> Yes, an offline/online cycle: every CPU's first bring-up happens
> before KVM's initcall, so hotplug is the only way to reach
> cpuinfo_store_cpu() with TID5 set. I'll say so in v2, along with a
> note on the reproducer (offline then online CPU1 with arm64.nomte, on
> QEMU with MTE enabled).
>
> As a side note, to answer a question Will asked me offlist, it's not
> an issue in any of the Android versions: Android 17 (and earlier)
> never gets the trap. The Android commit that disables MTE there does
> the HCR_ATA hunks only, and there is no handle_host_mte() either, so
> the read is untrapped.
>
> > > PSCI CPU_ON relay sets the host HCR before the CPU enters EL1, whereas
> > > plain nVHE sets it at CPUHP_AP_KVM_ONLINE, after cpuinfo_store_cpu().
> > >
> > > Defer the read to {init,update}_cpu_features() and gate it on the
> > > sanitised ID register, as MPAM already does. system_supports_mte()
> > > cannot serve as the gate, as update_cpu_features() also runs during
> > > initial SMP bring-up, before smp_cpus_done() calls
> > > setup_system_features(). The init path gains the CONFIG_ARM64_MTE test
> > > the update path already had, leaving SYS_GMID_EL1 uninitialised when
> > > MTE is compiled out, where its only other user (lib/mte.S) is not
> > > built.
> >
> > I'm starting to wonder whether having CPUs to go through a feature
> > collection process during an offline/online cycle is a good idea. The
> > data should still be there, and is not expected to change.
> >
> > Is it just that we don't have the correct tracking information?
>
> I think you're right. Nothing on the arm64 side tells a re-online from
> a first boot, so secondary_start_kernel() collects everything again.

I think that's deliberate, because we support the mostly theoretical
case of a different physical CPU being hotplugged in. Even though it's
a bit far-fetched for most systems, I don't think it's something we
should break unless we have a good reason to do so.

Will