This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch releases/12.7
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit a8717c6453d2bb32f399bbcfe30f6c722783d0c7
Author: hujun5 <[email protected]>
AuthorDate: Fri Apr 26 12:26:53 2024 +0800

    arch: We can use an independent SIG interrupt to handle async pause, which 
can save processing time.
    
    Signed-off-by: hujun5 <[email protected]>
---
 arch/arm/src/armv7-a/arm_cpupause.c        | 34 +++++++++++++++++++++++----
 arch/arm/src/armv7-a/arm_gicv2.c           |  2 ++
 arch/arm/src/armv7-a/gic.h                 | 25 ++++++++++++++++++++
 arch/arm/src/armv7-r/arm_cpupause.c        | 34 +++++++++++++++++++++++----
 arch/arm/src/armv7-r/arm_gicv2.c           |  2 ++
 arch/arm/src/armv7-r/gic.h                 | 26 +++++++++++++++++++++
 arch/arm/src/armv8-r/arm_gic.h             |  6 +++++
 arch/arm/src/armv8-r/arm_gicv3.c           |  3 +++
 arch/arm64/src/common/arm64_cpupause.c     | 35 ++++++++++++++++++++++++----
 arch/arm64/src/common/arm64_gic.h          | 24 +++++++++++++++++++
 arch/arm64/src/common/arm64_gicv2.c        |  2 ++
 arch/arm64/src/common/arm64_gicv3.c        |  3 +++
 arch/x86_64/include/intel64/irq.h          |  3 ++-
 arch/x86_64/src/intel64/intel64_cpupause.c | 37 ++++++++++++++++++++++++++++--
 arch/x86_64/src/intel64/intel64_cpustart.c |  3 +++
 15 files changed, 223 insertions(+), 16 deletions(-)

diff --git a/arch/arm/src/armv7-a/arm_cpupause.c 
b/arch/arm/src/armv7-a/arm_cpupause.c
index 0a25b9af5d..81dc1a534e 100644
--- a/arch/arm/src/armv7-a/arm_cpupause.c
+++ b/arch/arm/src/armv7-a/arm_cpupause.c
@@ -208,6 +208,34 @@ int up_cpu_paused_restore(void)
   return OK;
 }
 
+/****************************************************************************
+ * Name: arm_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int arm_pause_async_handler(int irq, void *context, void *arg)
+{
+  int cpu = this_cpu();
+
+  nxsched_process_delivered(cpu);
+  return OK;
+}
+
 /****************************************************************************
  * Name: arm_pause_handler
  *
@@ -256,8 +284,6 @@ int arm_pause_handler(int irq, void *context, void *arg)
       leave_critical_section(flags);
     }
 
-  nxsched_process_delivered(cpu);
-
   return OK;
 }
 
@@ -282,7 +308,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
 
 inline_function int up_cpu_pause_async(int cpu)
 {
-  arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
+  arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
 
   return OK;
 }
@@ -331,7 +357,7 @@ int up_cpu_pause(int cpu)
   spin_lock(&g_cpu_wait[cpu]);
   spin_lock(&g_cpu_paused[cpu]);
 
-  up_cpu_pause_async(cpu);
+  arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
 
   /* Wait for the other CPU to unlock g_cpu_paused meaning that
    * it is fully paused and ready for up_cpu_resume();
diff --git a/arch/arm/src/armv7-a/arm_gicv2.c b/arch/arm/src/armv7-a/arm_gicv2.c
index 87c5aa19e3..47a132fbc6 100644
--- a/arch/arm/src/armv7-a/arm_gicv2.c
+++ b/arch/arm/src/armv7-a/arm_gicv2.c
@@ -215,6 +215,8 @@ void arm_gic0_initialize(void)
 
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
+  DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
+                         arm_pause_async_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
                          nxsched_smp_call_handler, NULL));
 #endif
diff --git a/arch/arm/src/armv7-a/gic.h b/arch/arm/src/armv7-a/gic.h
index 29359e12dd..b652dea0a1 100644
--- a/arch/arm/src/armv7-a/gic.h
+++ b/arch/arm/src/armv7-a/gic.h
@@ -619,10 +619,12 @@
 #  define GIC_SMP_CPUSTART       GIC_IRQ_SGI9
 #  define GIC_SMP_CPUPAUSE       GIC_IRQ_SGI10
 #  define GIC_SMP_CPUCALL        GIC_IRQ_SGI11
+#  define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
 #else
 #  define GIC_SMP_CPUSTART       GIC_IRQ_SGI1
 #  define GIC_SMP_CPUPAUSE       GIC_IRQ_SGI2
 #  define GIC_SMP_CPUCALL        GIC_IRQ_SGI3
+#  define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
 #endif
 
 /****************************************************************************
@@ -839,6 +841,29 @@ int arm_start_handler(int irq, void *context, void *arg);
 int arm_pause_handler(int irq, void *context, void *arg);
 #endif
 
+/****************************************************************************
+ * Name: arm_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+int arm_pause_async_handler(int irq, void *context, void *arg);
+#endif
 /****************************************************************************
  * Name: arm_gic_dump
  *
diff --git a/arch/arm/src/armv7-r/arm_cpupause.c 
b/arch/arm/src/armv7-r/arm_cpupause.c
index f68f418216..c7d1ebe38e 100644
--- a/arch/arm/src/armv7-r/arm_cpupause.c
+++ b/arch/arm/src/armv7-r/arm_cpupause.c
@@ -230,8 +230,6 @@ int up_cpu_paused_restore(void)
 
 int arm_pause_handler(int irq, void *context, void *arg)
 {
-  int cpu = this_cpu();
-
   /* Check for false alarms.  Such false could occur as a consequence of
    * some deadlock breaking logic that might have already serviced the SG2
    * interrupt by calling up_cpu_paused().  If the pause event has already
@@ -256,8 +254,34 @@ int arm_pause_handler(int irq, void *context, void *arg)
       leave_critical_section(flags);
     }
 
-  nxsched_process_delivered(cpu);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: arm_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int arm_pause_async_handler(int irq, void *context, void *arg)
+{
+  int cpu = this_cpu();
 
+  nxsched_process_delivered(cpu);
   return OK;
 }
 
@@ -282,7 +306,7 @@ int arm_pause_handler(int irq, void *context, void *arg)
 
 inline_function int up_cpu_pause_async(int cpu)
 {
-  arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
+  arm_cpu_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
 
   return OK;
 }
@@ -331,7 +355,7 @@ int up_cpu_pause(int cpu)
   spin_lock(&g_cpu_wait[cpu]);
   spin_lock(&g_cpu_paused[cpu]);
 
-  up_cpu_pause_async(cpu);
+  arm_cpu_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
 
   /* Wait for the other CPU to unlock g_cpu_paused meaning that
    * it is fully paused and ready for up_cpu_resume();
diff --git a/arch/arm/src/armv7-r/arm_gicv2.c b/arch/arm/src/armv7-r/arm_gicv2.c
index d7513d252d..431ace37a4 100644
--- a/arch/arm/src/armv7-r/arm_gicv2.c
+++ b/arch/arm/src/armv7-r/arm_gicv2.c
@@ -161,6 +161,8 @@ void arm_gic0_initialize(void)
 
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUSTART, arm_start_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm_pause_handler, NULL));
+  DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
+                         arm_pause_async_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
                          nxsched_smp_call_handler, NULL));
 #endif
diff --git a/arch/arm/src/armv7-r/gic.h b/arch/arm/src/armv7-r/gic.h
index ecee23563d..d863233056 100644
--- a/arch/arm/src/armv7-r/gic.h
+++ b/arch/arm/src/armv7-r/gic.h
@@ -610,10 +610,12 @@
 #  define GIC_SMP_CPUSTART       GIC_IRQ_SGI9
 #  define GIC_SMP_CPUPAUSE       GIC_IRQ_SGI10
 #  define GIC_SMP_CPUCALL        GIC_IRQ_SGI11
+#  define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI12
 #else
 #  define GIC_SMP_CPUSTART       GIC_IRQ_SGI1
 #  define GIC_SMP_CPUPAUSE       GIC_IRQ_SGI2
 #  define GIC_SMP_CPUCALL        GIC_IRQ_SGI3
+#  define GIC_SMP_CPUPAUSE_ASYNC GIC_IRQ_SGI4
 #endif
 
 /****************************************************************************
@@ -827,6 +829,30 @@ int arm_start_handler(int irq, void *context, void *arg);
 int arm_pause_handler(int irq, void *context, void *arg);
 #endif
 
+/****************************************************************************
+ * Name: arm_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SMP
+int arm_pause_async_handler(int irq, void *context, void *arg);
+#endif
+
 /****************************************************************************
  * Name: arm_gic_dump
  *
diff --git a/arch/arm/src/armv8-r/arm_gic.h b/arch/arm/src/armv8-r/arm_gic.h
index e43ccff8d0..717e3660d2 100644
--- a/arch/arm/src/armv8-r/arm_gic.h
+++ b/arch/arm/src/armv8-r/arm_gic.h
@@ -313,10 +313,12 @@
 #  define GIC_SMP_CPUSTART          GIC_IRQ_SGI9
 #  define GIC_SMP_CPUPAUSE          GIC_IRQ_SGI10
 #  define GIC_SMP_CPUCALL           GIC_IRQ_SGI11
+#  define GIC_SMP_CPUPAUSE_ASYNC    GIC_IRQ_SGI12
 #else
 #  define GIC_SMP_CPUSTART          GIC_IRQ_SGI1
 #  define GIC_SMP_CPUPAUSE          GIC_IRQ_SGI2
 #  define GIC_SMP_CPUCALL           GIC_IRQ_SGI3
+#  define GIC_SMP_CPUPAUSE_ASYNC    GIC_IRQ_SGI4
 #endif
 
 /****************************************************************************
@@ -355,6 +357,10 @@ int arm_gic_raise_sgi(unsigned int sgi_id, uint16_t 
target_list);
 
 int arm_pause_handler(int irq, void *context, void *arg);
 
+#ifdef CONFIG_SMP
+int arm_pause_async_handler(int irq, void *context, void *arg);
+#endif
+
 void arm_gic_secondary_init(void);
 
 #endif
diff --git a/arch/arm/src/armv8-r/arm_gicv3.c b/arch/arm/src/armv8-r/arm_gicv3.c
index 7ff1d35582..d32db05ac7 100644
--- a/arch/arm/src/armv8-r/arm_gicv3.c
+++ b/arch/arm/src/armv8-r/arm_gicv3.c
@@ -568,6 +568,8 @@ static void gicv3_dist_init(void)
   /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
 
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
+  DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
+                         arm64_pause_async_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
                          nxsched_smp_call_handler, NULL));
 #endif
@@ -814,6 +816,7 @@ static void arm_gic_init(void)
 
 #ifdef CONFIG_SMP
   up_enable_irq(GIC_SMP_CPUPAUSE);
+  up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
 #endif
 }
 
diff --git a/arch/arm64/src/common/arm64_cpupause.c 
b/arch/arm64/src/common/arm64_cpupause.c
index f6579ba3b7..da81259d8d 100644
--- a/arch/arm64/src/common/arm64_cpupause.c
+++ b/arch/arm64/src/common/arm64_cpupause.c
@@ -211,6 +211,35 @@ int up_cpu_paused_restore(void)
   return OK;
 }
 
+/****************************************************************************
+ * Name: arm64_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int arm64_pause_async_handler(int irq, void *context, void *arg)
+{
+  int cpu = this_cpu();
+
+  nxsched_process_delivered(cpu);
+
+  return OK;
+}
+
 /****************************************************************************
  * Name: arm64_pause_handler
  *
@@ -259,8 +288,6 @@ int arm64_pause_handler(int irq, void *context, void *arg)
       leave_critical_section(flags);
     }
 
-  nxsched_process_delivered(cpu);
-
   return OK;
 }
 
@@ -287,7 +314,7 @@ inline_function int up_cpu_pause_async(int cpu)
 {
   /* Execute SGI2 */
 
-  arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
+  arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE_ASYNC, (1 << cpu));
 
   return OK;
 }
@@ -336,7 +363,7 @@ int up_cpu_pause(int cpu)
   spin_lock(&g_cpu_wait[cpu]);
   spin_lock(&g_cpu_paused[cpu]);
 
-  up_cpu_pause_async(cpu);
+  arm64_gic_raise_sgi(GIC_SMP_CPUPAUSE, (1 << cpu));
 
   /* Wait for the other CPU to unlock g_cpu_paused meaning that
    * it is fully paused and ready for up_cpu_resume();
diff --git a/arch/arm64/src/common/arm64_gic.h 
b/arch/arm64/src/common/arm64_gic.h
index 5b81e6ebde..de66d61696 100644
--- a/arch/arm64/src/common/arm64_gic.h
+++ b/arch/arm64/src/common/arm64_gic.h
@@ -281,10 +281,12 @@
 #define GIC_IRQ_SGI15               15
 
 #ifdef CONFIG_ARCH_TRUSTZONE_SECURE
+#  define GIC_SMP_CPUPAUSE_ASYNC    GIC_IRQ_SGI8
 #  define GIC_SMP_CPUSTART          GIC_IRQ_SGI9
 #  define GIC_SMP_CPUPAUSE          GIC_IRQ_SGI10
 #  define GIC_SMP_CPUCALL           GIC_IRQ_SGI11
 #else
+#  define GIC_SMP_CPUPAUSE_ASYNC    GIC_IRQ_SGI0
 #  define GIC_SMP_CPUSTART          GIC_IRQ_SGI1
 #  define GIC_SMP_CPUPAUSE          GIC_IRQ_SGI2
 #  define GIC_SMP_CPUCALL           GIC_IRQ_SGI3
@@ -343,6 +345,28 @@ void arm64_gic_raise_sgi(unsigned int sgi_id, uint16_t 
target_list);
 
 int arm64_pause_handler(int irq, void *context, void *arg);
 
+/****************************************************************************
+ * Name: arm64_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int arm64_pause_async_handler(int irq, void *context, void *arg);
+
 void arm64_gic_secondary_init(void);
 
 #endif
diff --git a/arch/arm64/src/common/arm64_gicv2.c 
b/arch/arm64/src/common/arm64_gicv2.c
index 3f019bfd9a..525298b185 100644
--- a/arch/arm64/src/common/arm64_gicv2.c
+++ b/arch/arm64/src/common/arm64_gicv2.c
@@ -911,6 +911,8 @@ static void arm_gic0_initialize(void)
   /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
 
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
+  DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
+                         arm64_pause_async_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
                          nxsched_smp_call_handler, NULL));
 #endif
diff --git a/arch/arm64/src/common/arm64_gicv3.c 
b/arch/arm64/src/common/arm64_gicv3.c
index 59b300cbf2..49b9d51335 100644
--- a/arch/arm64/src/common/arm64_gicv3.c
+++ b/arch/arm64/src/common/arm64_gicv3.c
@@ -654,6 +654,8 @@ static void gicv3_dist_init(void)
   /* Attach SGI interrupt handlers. This attaches the handler to all CPUs. */
 
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE, arm64_pause_handler, NULL));
+  DEBUGVERIFY(irq_attach(GIC_SMP_CPUPAUSE_ASYNC,
+                         arm64_pause_async_handler, NULL));
   DEBUGVERIFY(irq_attach(GIC_SMP_CPUCALL,
                          nxsched_smp_call_handler, NULL));
 #endif
@@ -952,6 +954,7 @@ static void arm64_gic_init(void)
 
 #ifdef CONFIG_SMP
   up_enable_irq(GIC_SMP_CPUPAUSE);
+  up_enable_irq(GIC_SMP_CPUPAUSE_ASYNC);
   up_enable_irq(GIC_SMP_CPUCALL);
 #endif
 }
diff --git a/arch/x86_64/include/intel64/irq.h 
b/arch/x86_64/include/intel64/irq.h
index 676458020d..fbcdf54500 100644
--- a/arch/x86_64/include/intel64/irq.h
+++ b/arch/x86_64/include/intel64/irq.h
@@ -346,9 +346,10 @@
 #define HPET0_IRQ    IRQ2
 #define HPET1_IRQ    IRQ8
 
-/* Use IRQ15 for SMP */
+/* Use IRQ15 IRQ16 for SMP */
 
 #define SMP_IPI_IRQ  IRQ15
+#define SMP_IPI_ASYNC_IRQ  IRQ16
 
 /* Common register save structure created by up_saveusercontext() and by
  * ISR/IRQ interrupt processing.
diff --git a/arch/x86_64/src/intel64/intel64_cpupause.c 
b/arch/x86_64/src/intel64/intel64_cpupause.c
index 44e3220c2a..7f6891d24c 100644
--- a/arch/x86_64/src/intel64/intel64_cpupause.c
+++ b/arch/x86_64/src/intel64/intel64_cpupause.c
@@ -264,6 +264,35 @@ int up_pause_handler(int irq, void *c, void *arg)
   return OK;
 }
 
+/****************************************************************************
+ * Name: up_pause_async_handler
+ *
+ * Description:
+ *   This is the handler for async pause.
+ *
+ *   1. It saves the current task state at the head of the current assigned
+ *      task list.
+ *   2. It porcess g_delivertasks
+ *   3. Returns from interrupt, restoring the state of the new task at the
+ *      head of the ready to run list.
+ *
+ * Input Parameters:
+ *   Standard interrupt handling
+ *
+ * Returned Value:
+ *   Zero on success; a negated errno value on failure.
+ *
+ ****************************************************************************/
+
+int up_pause_async_handler(int irq, void *c, void *arg)
+{
+  int cpu = this_cpu();
+
+  nxsched_process_delivered(cpu);
+
+  return OK;
+}
+
 /****************************************************************************
  * Name: up_cpu_pause_async
  *
@@ -290,7 +319,7 @@ inline_function int up_cpu_pause_async(int cpu)
   CPU_ZERO(&cpuset);
   CPU_SET(cpu, &cpuset);
 
-  up_trigger_irq(SMP_IPI_IRQ, cpuset);
+  up_trigger_irq(SMP_IPI_ASYNC_IRQ, cpuset);
 
   return OK;
 }
@@ -336,6 +365,7 @@ void up_send_smp_call(cpu_set_t cpuset)
 
 int up_cpu_pause(int cpu)
 {
+  cpu_set_t cpuset;
   sinfo("cpu=%d\n", cpu);
 
 #ifdef CONFIG_SCHED_INSTRUMENTATION
@@ -362,7 +392,10 @@ int up_cpu_pause(int cpu)
 
   /* Execute Pause IRQ to CPU(cpu) */
 
-  up_cpu_pause_async(cpu);
+  CPU_ZERO(&cpuset);
+  CPU_SET(cpu, &cpuset);
+
+  up_trigger_irq(SMP_IPI_IRQ, cpuset);
 
   /* Wait for the other CPU to unlock g_cpu_paused meaning that
    * it is fully paused and ready for up_cpu_resume();
diff --git a/arch/x86_64/src/intel64/intel64_cpustart.c 
b/arch/x86_64/src/intel64/intel64_cpustart.c
index c766ebfe1c..2fe404349a 100644
--- a/arch/x86_64/src/intel64/intel64_cpustart.c
+++ b/arch/x86_64/src/intel64/intel64_cpustart.c
@@ -47,6 +47,7 @@
 
 extern void __ap_entry(void);
 extern int up_pause_handler(int irq, void *c, void *arg);
+extern int up_pause_async_handler(int irq, void *c, void *arg);
 
 /****************************************************************************
  * Private Functions
@@ -160,7 +161,9 @@ void x86_64_ap_boot(void)
   /* Connect Pause IRQ to CPU */
 
   irq_attach(SMP_IPI_IRQ, up_pause_handler, NULL);
+  irq_attach(SMP_IPI_ASYNC_IRQ, up_pause_async_handler, NULL);
   up_enable_irq(SMP_IPI_IRQ);
+  up_enable_irq(SMP_IPI_ASYNC_IRQ);
 
   /* CPU ready */
 

Reply via email to