From 0102b592f46ff3f0784e693efa0b812551345271 Mon Sep 17 00:00:00 2001 From: Mykola Kvach Date: Mon, 10 Aug 2026 22:41:46 +0300 Subject: [PATCH] xen/arm: propagate secondary GIC initialization failures The GICv3 secondary_init() callback can fail while discovering or waking a Redistributor, enabling LPIs, or setting up an ITS collection. gic_init_secondary_cpu() currently discards that status. start_secondary() then marks the CPU online even though its per-CPU GIC interface may be unusable. Return the callback status through the common GIC layer. Have start_secondary() report the failure and stop the affected CPU before it updates system features or is added to cpu_online_map. Fixes: bc183a0235e0 ("xen/arm: Add support for GIC v3") Signed-off-by: Mykola Kvach Reviewed-by: Michal Orzel --- xen/arch/arm/gic.c | 10 ++++++++-- xen/arch/arm/include/asm/gic.h | 2 +- xen/arch/arm/smpboot.c | 11 +++++++++-- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c index ee75258fc3..078049e741 100644 --- a/xen/arch/arm/gic.c +++ b/xen/arch/arm/gic.c @@ -282,11 +282,17 @@ void smp_send_state_dump(unsigned int cpu) } /* Set up the per-CPU parts of the GIC for a secondary CPU */ -void gic_init_secondary_cpu(void) +int gic_init_secondary_cpu(void) { - gic_hw_ops->secondary_init(); + int rc = gic_hw_ops->secondary_init(); + + if ( rc ) + return rc; + /* Clear LR mask for secondary cpus */ clear_cpu_lr_mask(); + + return 0; } /* Shut down the per-CPU GIC interface */ diff --git a/xen/arch/arm/include/asm/gic.h b/xen/arch/arm/include/asm/gic.h index ff22dea40d..ee2c26adb4 100644 --- a/xen/arch/arm/include/asm/gic.h +++ b/xen/arch/arm/include/asm/gic.h @@ -291,7 +291,7 @@ extern void gic_preinit(void); /* Bring up the interrupt controller, and report # cpus attached */ extern void gic_init(void); /* Bring up a secondary CPU's per-CPU GIC interface */ -extern void gic_init_secondary_cpu(void); +extern int gic_init_secondary_cpu(void); /* Take down a CPU's per-CPU GIC interface */ extern void gic_disable_cpu(void); /* setup the gic virtual interface for a guest */ diff --git a/xen/arch/arm/smpboot.c b/xen/arch/arm/smpboot.c index ba5fd2dd52..1806c47a08 100644 --- a/xen/arch/arm/smpboot.c +++ b/xen/arch/arm/smpboot.c @@ -319,6 +319,7 @@ smp_prepare_cpus(void) void asmlinkage noreturn start_secondary(void) { unsigned int cpuid = init_data.cpuid; + int rc; memset(get_cpu_info(), 0, sizeof (struct cpu_info)); @@ -366,6 +367,14 @@ void asmlinkage noreturn start_secondary(void) stop_cpu(); } + rc = gic_init_secondary_cpu(); + if ( rc ) + { + printk(XENLOG_ERR "CPU%u: Failed to initialize the GIC: %d\n", + smp_processor_id(), rc); + stop_cpu(); + } + /* * system features must be updated only if we do not stop the core or * we might disable features due to a non used core (for example when @@ -373,8 +382,6 @@ void asmlinkage noreturn start_secondary(void) */ update_system_features(¤t_cpu_data); - gic_init_secondary_cpu(); - set_current(idle_vcpu[cpuid]); /* Run local notifiers */