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

Reply via email to