The AArch64 changes look reasonable and resolve the bug I observed in both the test case you provided as well as the test where I initially discovered it.

Thanks,

Kinsey

On 3/8/2022 12:28, Sebastian Huber wrote:
The previous SMP multitasking start assumed that the initial heir thread of a
processor starts execution in _Thread_Handler().  The _Thread_Handler() sets
the interrupt state explicitly by _ISR_Set_level() before it calls the thread
entry.  Under certain timing conditions, processors may perform an initial
context switch to a thread which already executes its thread body (see
smptests/smpstart01).  In this case, interrupts are disabled after the context
switch on targets which do not save/restore the interrupt state during a
context switch (aarch64, arm, and riscv).

Close #4627.
---
  cpukit/score/cpu/aarch64/cpu_asm.S              | 17 +++++++++++++++++
  .../score/cpu/aarch64/include/rtems/score/cpu.h |  4 ++++
  cpukit/score/cpu/arm/cpu_asm.S                  | 12 ++++++++++++
  cpukit/score/cpu/arm/include/rtems/score/cpu.h  |  4 ++++
  .../score/cpu/riscv/include/rtems/score/cpu.h   |  4 ++++
  cpukit/score/cpu/riscv/riscv-context-switch.S   | 15 +++++++++++++++
  cpukit/score/src/threadstartmultitasking.c      |  3 +++
  7 files changed, 59 insertions(+)

diff --git a/cpukit/score/cpu/aarch64/cpu_asm.S 
b/cpukit/score/cpu/aarch64/cpu_asm.S
index 2379698336..6321acde90 100644
--- a/cpukit/score/cpu/aarch64/cpu_asm.S
+++ b/cpukit/score/cpu/aarch64/cpu_asm.S
@@ -202,5 +202,22 @@ DEFINE_FUNCTION_AARCH64(_CPU_Context_restore)
        str     x5, [x2, #PER_CPU_OFFSET_EXECUTING]
  #endif
+ b .L_check_is_executing
+
+DEFINE_FUNCTION_AARCH64(_AArch64_Start_multitasking)
+#ifdef AARCH64_MULTILIB_ARCH_V8_ILP32
+       /* Sanitize input for ILP32 ABI */
+       mov     w0, w0
+#endif
+
+       mov     x1, x0
+       GET_SELF_CPU_CONTROL    reg_2
+
+       /* Switch the stack to the temporary interrupt stack of this processor 
*/
+       add     sp, x2, #(PER_CPU_INTERRUPT_FRAME_AREA + 
CPU_INTERRUPT_FRAME_SIZE)
+
+       /* Enable interrupts */
+       msr     DAIFClr, #0x2
+
        b       .L_check_is_executing
  #endif
diff --git a/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h 
b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
index e1d9f0a5c2..fdc0e3d929 100644
--- a/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/aarch64/include/rtems/score/cpu.h
@@ -285,6 +285,10 @@ void _CPU_Context_Initialize(
    {
      context->is_executing = is_executing;
    }
+
+  RTEMS_NO_RETURN void _AArch64_Start_multitasking( Context_Control *heir );
+
+  #define _CPU_Start_multitasking( _heir ) _AArch64_Start_multitasking( _heir )
  #endif
#define _CPU_Context_Restart_self( _the_context ) \
diff --git a/cpukit/score/cpu/arm/cpu_asm.S b/cpukit/score/cpu/arm/cpu_asm.S
index 54d6f70b0d..d52a43f70d 100644
--- a/cpukit/score/cpu/arm/cpu_asm.S
+++ b/cpukit/score/cpu/arm/cpu_asm.S
@@ -181,6 +181,18 @@ DEFINE_FUNCTION_ARM(_CPU_Context_restore)
        /* Update the executing */
        str     r5, [r2, #PER_CPU_OFFSET_EXECUTING]
+ b .L_check_is_executing
+
+DEFINE_FUNCTION_ARM(_ARM_Start_multitasking)
+       mov     r1, r0
+       GET_SELF_CPU_CONTROL    r2
+
+       /* Switch the stack to the temporary interrupt stack of this processor 
*/
+       add     sp, r2, #(PER_CPU_INTERRUPT_FRAME_AREA + 
CPU_INTERRUPT_FRAME_SIZE)
+
+       /* Enable IRQ interrupts */
+       cpsie   i
+
        b       .L_check_is_executing
  #endif
diff --git a/cpukit/score/cpu/arm/include/rtems/score/cpu.h b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
index da521528a4..7ac180ac26 100644
--- a/cpukit/score/cpu/arm/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/arm/include/rtems/score/cpu.h
@@ -443,6 +443,10 @@ void _CPU_Context_Initialize(
    {
      context->is_executing = is_executing;
    }
+
+  RTEMS_NO_RETURN void _ARM_Start_multitasking( Context_Control *heir );
+
+  #define _CPU_Start_multitasking( _heir ) _ARM_Start_multitasking( _heir )
  #endif
#define _CPU_Context_Restart_self( _the_context ) \
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h 
b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
index 05ef2709ba..471c6c6c3e 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
@@ -509,6 +509,10 @@ static inline void _CPU_Context_Set_is_executing(
    context->is_executing = is_executing;
  }
+RTEMS_NO_RETURN void _RISCV_Start_multitasking( Context_Control *heir );
+
+#define _CPU_Start_multitasking( _heir ) _RISCV_Start_multitasking( _heir )
+
  #endif /* RTEMS_SMP */
/** Type that can store a 32-bit integer or a pointer. */
diff --git a/cpukit/score/cpu/riscv/riscv-context-switch.S 
b/cpukit/score/cpu/riscv/riscv-context-switch.S
index 3c0368886e..cfaff444b0 100644
--- a/cpukit/score/cpu/riscv/riscv-context-switch.S
+++ b/cpukit/score/cpu/riscv/riscv-context-switch.S
@@ -40,6 +40,9 @@
  PUBLIC(_CPU_Context_switch)
  PUBLIC(_CPU_Context_switch_no_return)
  PUBLIC(_CPU_Context_restore)
+#ifdef RTEMS_SMP
+PUBLIC(_RISCV_Start_multitasking)
+#endif
SYM(_CPU_Context_switch):
  SYM(_CPU_Context_switch_no_return):
@@ -174,5 +177,17 @@ SYM(_CPU_Context_restore):
        /* Update the executing */
        sw      a5, PER_CPU_OFFSET_EXECUTING(a2)
+ j .Ltry_update_is_executing
+
+SYM(_RISCV_Start_multitasking):
+       mv      a1, a0
+       GET_SELF_CPU_CONTROL    a2
+
+       /* Switch the stack to the temporary interrupt stack of this processor 
*/
+       addi    sp, a2, PER_CPU_INTERRUPT_FRAME_AREA + CPU_INTERRUPT_FRAME_SIZE
+
+       /* Enable interrupts */
+       csrrs   zero, mstatus, RISCV_MSTATUS_MIE
+
        j       .Ltry_update_is_executing
  #endif
diff --git a/cpukit/score/src/threadstartmultitasking.c 
b/cpukit/score/src/threadstartmultitasking.c
index 5cc2051be4..d97d2e0c82 100644
--- a/cpukit/score/src/threadstartmultitasking.c
+++ b/cpukit/score/src/threadstartmultitasking.c
@@ -64,6 +64,9 @@ void _Thread_Start_multitasking( void )
  #if defined(_CPU_Start_multitasking)
    _CPU_Start_multitasking( &heir->Registers );
  #elif defined(RTEMS_SMP)
+#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
+#error "The CPU port has to provide _CPU_Start_multitasking()"
+#endif
    {
      Context_Control trash;
_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to