diff options
| author | Osama Abdelkader <osama.abdelkader@gmail.com> | 2026-03-27 01:57:52 +0300 |
|---|---|---|
| committer | Will Deacon <will@kernel.org> | 2026-05-19 14:27:10 +0300 |
| commit | 7dc6922f7fdd3496de4e7d8fb99284fc08f98003 (patch) | |
| tree | bd43fdc3d34b01fa5e4f122e1fbb10cd68b3092e | |
| parent | e7cec385d2c6726e692d057f91f20b08c2981af3 (diff) | |
| download | linux-7dc6922f7fdd3496de4e7d8fb99284fc08f98003.tar.xz | |
arm64: panic from init_IRQ if IRQ handler stacks cannot be allocated
init_irq_stacks() and init_irq_scs() may fail when arch_alloc_vmap_stack
or scs_alloc return NULL. Return -ENOMEM from both and call panic() once
from init_IRQ(), covering per-CPU IRQ stacks and shadow IRQ stacks
consistently.
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
| -rw-r--r-- | arch/arm64/kernel/irq.c | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/arch/arm64/kernel/irq.c b/arch/arm64/kernel/irq.c index 15dedb385b9e..9fafd826002b 100644 --- a/arch/arm64/kernel/irq.c +++ b/arch/arm64/kernel/irq.c @@ -10,6 +10,7 @@ * Copyright (C) 2012 ARM Ltd. */ +#include <linux/errno.h> #include <linux/hardirq.h> #include <linux/init.h> #include <linux/irq.h> @@ -32,34 +33,43 @@ DEFINE_PER_CPU(struct nmi_ctx, nmi_contexts); DEFINE_PER_CPU(unsigned long *, irq_stack_ptr); - DECLARE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr); #ifdef CONFIG_SHADOW_CALL_STACK DEFINE_PER_CPU(unsigned long *, irq_shadow_call_stack_ptr); #endif -static void init_irq_scs(void) +static int __init init_irq_scs(void) { int cpu; + void *s; if (!scs_is_enabled()) - return; + return 0; + + for_each_possible_cpu(cpu) { + s = scs_alloc(early_cpu_to_node(cpu)); + if (!s) + return -ENOMEM; + per_cpu(irq_shadow_call_stack_ptr, cpu) = s; + } - for_each_possible_cpu(cpu) - per_cpu(irq_shadow_call_stack_ptr, cpu) = - scs_alloc(early_cpu_to_node(cpu)); + return 0; } -static void __init init_irq_stacks(void) +static int __init init_irq_stacks(void) { int cpu; unsigned long *p; for_each_possible_cpu(cpu) { p = arch_alloc_vmap_stack(IRQ_STACK_SIZE, early_cpu_to_node(cpu)); + if (!p) + return -ENOMEM; per_cpu(irq_stack_ptr, cpu) = p; } + + return 0; } #ifdef CONFIG_SOFTIRQ_ON_OWN_STACK @@ -109,8 +119,9 @@ int __init set_handle_fiq(void (*handle_fiq)(struct pt_regs *)) void __init init_IRQ(void) { - init_irq_stacks(); - init_irq_scs(); + if (init_irq_stacks() || init_irq_scs()) + panic("Failed to allocate IRQ stack resources\n"); + irqchip_init(); if (system_uses_irq_prio_masking()) { |
