[PATCH v2 04/45] KVM: arm64: Turn vgic-v3 errata traps into a patched-in constant

Marc Zyngier maz at kernel.org
Thu Nov 13 02:59:12 PST 2025


On Thu, 13 Nov 2025 09:52:23 +0000,
Marek Szyprowski <m.szyprowski at samsung.com> wrote:
> 
> On 09.11.2025 18:15, Marc Zyngier wrote:
> > The trap bits are currently only set to manage CPU errata. However,
> > we are about to make use of them for purposes beyond beating broken
> > CPUs into submission.
> >
> > For this purpose, turn these errata-driven bits into a patched-in
> > constant that is merged with the KVM-driven value at the point of
> > programming the ICH_HCR_EL2 register, rather than being directly
> > stored with with the shadow value..
> >
> > This allows the KVM code to distinguish between a trap being handled
> > for the purpose of an erratum workaround, or for KVM's own need.
> >
> > Signed-off-by: Marc Zyngier <maz at kernel.org>
> 
> This patch landed in today's linux-next as commit ca30799f7c2d ("KVM: 
> arm64: Turn vgic-v3 errata traps into a patched-in constant"). In my 
> tests I found that it triggers oops and breaks booting on Raspberry Pi5 
> and Amlogic SM1 based boards: Odroid-C4 and Khadas VIM3l. Here is the 
> failure log:
> 
> alternatives: applying system-wide alternatives
> Internal error: Oops - Undefined instruction: 0000000002000000 [#1]  SMP
> Modules linked in:
> CPU: 0 UID: 0 PID: 18 Comm: migration/0 Not tainted 6.18.0-rc3+ #11665 
> PREEMPT
> Hardware name: Raspberry Pi 5 Model B Rev 1.0 (DT)
> Stopper: multi_cpu_stop+0x0/0x178 <- __stop_cpus.constprop.0+0x7c/0xc8
> pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : vgic_v3_broken_seis+0x14/0x44
> lr : kvm_compute_ich_hcr_trap_bits+0x48/0xd8
> ...
> Call trace:
>   vgic_v3_broken_seis+0x14/0x44 (P)
>   __apply_alternatives+0x1b4/0x200
>   __apply_alternatives_multi_stop+0xac/0xc8
>   multi_cpu_stop+0x90/0x178
>   cpu_stopper_thread+0x8c/0x11c
>   smpboot_thread_fn+0x160/0x32c
>   kthread+0x150/0x228
>   ret_from_fork+0x10/0x20
> Code: 52800000 f100203f 54000040 d65f03c0 (d53ccb21)
> ---[ end trace 0000000000000000 ]---
> note: migration/0[18] exited with irqs disabled
> note: migration/0[18] exited with preempt_count 1
> rcu: INFO: rcu_preempt detected stalls on CPUs/tasks:
> rcu:     1-...0: (7 ticks this GP) idle=0124/1/0x4000000000000000 
> softirq=9/10 fqs=3250
> rcu:     2-...0: (7 ticks this GP) idle=0154/1/0x4000000000000000 
> softirq=9/10 fqs=3250
> rcu:     3-...0: (7 ticks this GP) idle=018c/1/0x4000000000000000 
> softirq=9/10 fqs=3250
> rcu:     (detected by 0, t=6502 jiffies, g=-1179, q=2 ncpus=4)
> Sending NMI from CPU 0 to CPUs 1:
> Sending NMI from CPU 0 to CPUs 2:
> Sending NMI from CPU 0 to CPUs 3:
> 
> Let me know how I can help in debugging this issue.

Wild guess. Can you try this (untested)?

	M.

diff --git a/arch/arm64/kvm/vgic/vgic-v3.c b/arch/arm64/kvm/vgic/vgic-v3.c
index fc7a4cb8e231d..598621b14a30d 100644
--- a/arch/arm64/kvm/vgic/vgic-v3.c
+++ b/arch/arm64/kvm/vgic/vgic-v3.c
@@ -829,8 +829,8 @@ static const struct midr_range broken_seis[] = {
 static bool vgic_v3_broken_seis(void)
 {
 	return (is_kernel_in_hyp_mode() &&
-		(read_sysreg_s(SYS_ICH_VTR_EL2) & ICH_VTR_EL2_SEIS) &&
-		is_midr_in_range_list(broken_seis));
+		is_midr_in_range_list(broken_seis) &&
+		(read_sysreg_s(SYS_ICH_VTR_EL2) & ICH_VTR_EL2_SEIS));
 }
 
 void noinstr kvm_compute_ich_hcr_trap_bits(struct alt_instr *alt,

-- 
Without deviation from the norm, progress is not possible.



More information about the linux-arm-kernel mailing list