This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 621f525804e5da2177080c59945f373e2bc88f8c Author: raiden00pl <[email protected]> AuthorDate: Wed Oct 7 13:43:14 2026 +0200 arch/x86_64/intel64: attach shared vector handlers only once. The vector table is shared by all CPUs, but the fault, debug and SMP IPI handlers were attached again on every CPU (up_irqinitialize(), x86_64_hwdebug_init() and x86_64_ap_boot()). With CONFIG_IRQCHAIN this adds duplicate chain entries per CPU and exhausts the IRQ chain pool, so later irq_attach() calls from drivers fail with -ENOMEM. Attach these handlers once, on CPU0. The SMP IPI handler prototypes move to intel64.h, under CONFIG_SMP. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: raiden00pl <[email protected]> --- arch/x86_64/src/common/x86_64_hwdebug.c | 11 +++++--- arch/x86_64/src/intel64/intel64.h | 7 +++++ arch/x86_64/src/intel64/intel64_cpustart.c | 11 -------- arch/x86_64/src/intel64/intel64_irq.c | 42 ++++++++++++++++++++---------- arch/x86_64/src/intel64/intel64_smpcall.c | 1 + 5 files changed, 44 insertions(+), 28 deletions(-) diff --git a/arch/x86_64/src/common/x86_64_hwdebug.c b/arch/x86_64/src/common/x86_64_hwdebug.c index 7022501f0ac..b99467b4724 100644 --- a/arch/x86_64/src/common/x86_64_hwdebug.c +++ b/arch/x86_64/src/common/x86_64_hwdebug.c @@ -518,10 +518,15 @@ int up_debugpoint_remove(int type, void *addr, size_t size) void x86_64_hwdebug_init(void) { - /* Attach debug interrupt and breakpoint interrupt */ + /* Attach debug interrupt and breakpoint interrupt. The vector table is + * shared by all CPUs, so do this only once. + */ - irq_attach(ISR1, x86_64_debug_handler, NULL); - irq_attach(ISR3, x86_64_debug_handler, NULL); + if (this_cpu() == 0) + { + irq_attach(ISR1, x86_64_debug_handler, NULL); + irq_attach(ISR3, x86_64_debug_handler, NULL); + } /* Disable all breakpoints */ diff --git a/arch/x86_64/src/intel64/intel64.h b/arch/x86_64/src/intel64/intel64.h index 3d517be2379..0297b642987 100644 --- a/arch/x86_64/src/intel64/intel64.h +++ b/arch/x86_64/src/intel64/intel64.h @@ -370,6 +370,13 @@ void vector_irq253(void); void vector_irq254(void); void vector_irq255(void); +#ifdef CONFIG_SMP +/* SMP call and scheduler IPI handlers (intel64_smpcall.c) */ + +int x86_64_smp_call_handler(int irq, void *c, void *arg); +int x86_64_smp_sched_handler(int irq, void *c, void *arg); +#endif + #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/x86_64/src/intel64/intel64_cpustart.c b/arch/x86_64/src/intel64/intel64_cpustart.c index d6e43a4faf7..413139a0b80 100644 --- a/arch/x86_64/src/intel64/intel64_cpustart.c +++ b/arch/x86_64/src/intel64/intel64_cpustart.c @@ -53,8 +53,6 @@ ****************************************************************************/ extern void __ap_entry(void); -extern int x86_64_smp_call_handler(int irq, void *c, void *arg); -extern int x86_64_smp_sched_handler(int irq, void *c, void *arg); extern uint64_t get_tsc_adjust(void); /**************************************************************************** @@ -168,15 +166,6 @@ void x86_64_ap_boot(void) sinfo("cpu=%d\n", cpu); - /* Connect Pause IRQ to CPU */ - - irq_attach(SMP_IPI_CALL_IRQ, x86_64_smp_call_handler, NULL); - irq_attach(SMP_IPI_SCHED_IRQ, x86_64_smp_sched_handler, NULL); - - /* NOTE: IPC interrupts don't use IOAPIC but interrupts are sent - * directly to CPU, so we don't use up_enable_irq() API here. - */ - #ifdef CONFIG_STACK_COLORATION /* If stack debug is enabled, then fill the stack with a * recognizable value that we can use later to test for high diff --git a/arch/x86_64/src/intel64/intel64_irq.c b/arch/x86_64/src/intel64/intel64_irq.c index aa02ce48d47..c86c5b6eec0 100644 --- a/arch/x86_64/src/intel64/intel64_irq.c +++ b/arch/x86_64/src/intel64/intel64_irq.c @@ -679,26 +679,40 @@ void up_irqinitialize(void) up_irq_restore(X86_64_RFLAGS_IF); #endif - /* Attach default handlers for faults. - * - * ISR6, ISR13 and ISR14 are attributable to the instruction that raised - * them, so an unprivileged task that raises one is killed on its own and - * the system runs on. The double fault is not: it says an exception - * could not be delivered at all, and there is nothing left to trust. + /* The vector table is shared by all CPUs, so attach the common handlers + * only once. Attaching them again on every CPU would add duplicate + * entries to the IRQ chains when CONFIG_IRQCHAIN is enabled. */ - irq_attach(ISR0, x86_64_fault_kill_isr, NULL); - irq_attach(ISR6, x86_64_fault_user_isr, NULL); - irq_attach(ISR8, x86_64_fault_panic_isr, NULL); - irq_attach(ISR13, x86_64_fault_user_isr, NULL); - irq_attach(ISR14, x86_64_fault_user_isr, NULL); - irq_attach(ISR16, x86_64_fault_kill_isr, NULL); + if (cpu == 0) + { + /* Attach default handlers for faults. + * + * ISR6, ISR13 and ISR14 are attributable to the instruction that + * raised them, so an unprivileged task that raises one is killed on + * its own and the system runs on. The double fault is not: it says + * an exception could not be delivered at all, and there is nothing + * left to trust. + */ + + irq_attach(ISR0, x86_64_fault_kill_isr, NULL); + irq_attach(ISR6, x86_64_fault_user_isr, NULL); + irq_attach(ISR8, x86_64_fault_panic_isr, NULL); + irq_attach(ISR13, x86_64_fault_user_isr, NULL); + irq_attach(ISR14, x86_64_fault_user_isr, NULL); + irq_attach(ISR16, x86_64_fault_kill_isr, NULL); #ifdef CONFIG_SMP - /* Attach TLB shootdown handler */ + /* Attach TLB shootdown and SMP call handlers. IPIs don't use the + * IOAPIC but are sent directly to the CPU, so up_enable_irq() is not + * needed for them. + */ - irq_attach(SMP_IPI_TLBSHOOTDOWN_IRQ, x86_64_tlb_handler, NULL); + irq_attach(SMP_IPI_TLBSHOOTDOWN_IRQ, x86_64_tlb_handler, NULL); + irq_attach(SMP_IPI_CALL_IRQ, x86_64_smp_call_handler, NULL); + irq_attach(SMP_IPI_SCHED_IRQ, x86_64_smp_sched_handler, NULL); #endif + } } /**************************************************************************** diff --git a/arch/x86_64/src/intel64/intel64_smpcall.c b/arch/x86_64/src/intel64/intel64_smpcall.c index 07768601e97..d879d3a0d55 100644 --- a/arch/x86_64/src/intel64/intel64_smpcall.c +++ b/arch/x86_64/src/intel64/intel64_smpcall.c @@ -41,6 +41,7 @@ #include "sched/sched.h" #include "x86_64_internal.h" +#include "intel64.h" /**************************************************************************** * Public Data
