summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladimir Murzin <vladimir.murzin@arm.com>2026-07-31 13:26:46 +0100
committerWill Deacon <will@kernel.org>2026-08-02 09:26:12 +0000
commit4c9c81a0860415284e9d260f998fbd755d3a7469 (patch)
tree8f6fece20b4df5a112a3d24473427e8728987b8a
parent25ef34b541eb216c09cb304778915fec845ef7ec (diff)
downloadlinux-next-4c9c81a0860415284e9d260f998fbd755d3a7469.tar.gz
linux-next-4c9c81a0860415284e9d260f998fbd755d3a7469.zip
arm64: smp: Fix IPI teardown for GICv5 flow
Sashiko reported that during CPU offlining, __cpu_disable() is executed by the stopper thread via take_cpu_down() with local interrupts disabled. __cpu_disable() calls ipi_teardown(), which invokes ipi_lpi_disable(). For the GICv5 flow, this eventually calls the sleepable disable_irq(). This can be reproduced easily with CONFIG_DEBUG_ATOMIC_SLEEP=y by offlining a CPU: BUG: sleeping function called from invalid context at kernel/irq/manage.c:702 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 20, name: migration/1 preempt_count: 1, expected: 0 no locks held by migration/1/20. irq event stamp: 186 hardirqs last enabled at (185): [<ffff800080b084c8>] _raw_spin_unlock_irq+0x38/0x68 hardirqs last disabled at (186): [<ffff8000801f8e08>] multi_cpu_stop+0xc8/0x190 softirqs last enabled at (80): [<ffff8000800c48b8>] handle_softirqs+0x410/0x468 softirqs last disabled at (75): [<ffff8000800102f4>] __do_softirq+0x1c/0x28 Fix this by using disable_irq_nosync() instead, which is safe in this atomic context. Fixes: ba1004f861d1 ("arm64: smp: Support non-SGIs for IPIs") Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> Signed-off-by: Will Deacon <will@kernel.org>
-rw-r--r--arch/arm64/kernel/smp.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c
index cdcdd160e5b6..3ab90aa24efb 100644
--- a/arch/arm64/kernel/smp.c
+++ b/arch/arm64/kernel/smp.c
@@ -1086,7 +1086,7 @@ static void ipi_teardown(int cpu)
disable_percpu_irq(ipi_irq_base + i);
}
} else {
- disable_irq(irq_desc_get_irq(get_ipi_desc(cpu, i)));
+ disable_irq_nosync(irq_desc_get_irq(get_ipi_desc(cpu, i)));
}
}
}