Browse Source

[libcpu/arm] fix race condition with ldrex,strex (#7842)

Signed-off-by: Shell <smokewood@qq.com>
Shell 1 year ago
parent
commit
acfa74f078

+ 6 - 3
components/lwp/arch/arm/cortex-a/lwp_arch.c

@@ -54,10 +54,13 @@ static struct rt_varea kuser_varea;
 
 void arch_kuser_init(rt_aspace_t aspace, void *vectors)
 {
-    const size_t kuser_size = 0x1000;
     int err;
-    extern char *__kuser_helper_start, *__kuser_helper_end;
-    int kuser_sz = __kuser_helper_end - __kuser_helper_start;
+    const size_t kuser_size = 0x1000;
+    extern char __kuser_helper_start[];
+    extern char __kuser_helper_end[];
+    rt_base_t start = (rt_base_t)__kuser_helper_start;
+    rt_base_t end = (rt_base_t)__kuser_helper_end;
+    int kuser_sz = end - start;
 
     err = rt_aspace_map_static(aspace, &kuser_varea, &vectors, kuser_size,
                                MMU_MAP_U_RO, MMF_MAP_FIXED | MMF_PREFETCH,

+ 5 - 3
examples/utest/testcases/kernel/atomic_tc.c

@@ -134,10 +134,11 @@ static void ture_entry(void *parameter)
 static void test_atomic_add(void)
 {
     rt_thread_t thread;
-    int i;
+    size_t i;
     sem_t = rt_sem_create("atomic_sem", 0, RT_IPC_FLAG_PRIO);
 
-    count = 0;
+    rt_atomic_store(&count, 0);
+
     thread = rt_thread_create("t1", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
     rt_thread_startup(thread);
     thread = rt_thread_create("t2", ture_entry, RT_NULL, THREAD_STACKSIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
@@ -149,7 +150,8 @@ static void test_atomic_add(void)
     {
         rt_sem_take(sem_t, RT_WAITING_FOREVER);
     }
-    uassert_true(count == 3000000);
+    i = rt_atomic_load(&count);
+    uassert_true(i == 3000000);
 }
 
 static rt_err_t utest_tc_init(void)

+ 3 - 3
include/rtdef.h

@@ -128,11 +128,11 @@ typedef rt_ubase_t                      rt_dev_t;       /**< Type for device */
 typedef rt_base_t                       rt_off_t;       /**< Type for offset */
 
 #if !defined(__cplusplus)
-#if defined(RT_USING_STDC_ATOMIC)
+#if defined(RT_USING_HW_ATOMIC)
+    typedef rt_base_t rt_atomic_t;
+#elif defined(RT_USING_STDC_ATOMIC)
     #include <stdatomic.h>
     typedef atomic_size_t rt_atomic_t;
-#elif defined(RT_USING_HW_ATOMIC)
-    typedef rt_base_t rt_atomic_t;
 #else
 
     /* To detect std atomic */

+ 6 - 4
libcpu/aarch64/common/context_gcc.S

@@ -377,7 +377,6 @@ vector_fiq:
 
 .globl vector_irq
 vector_irq:
-    CLREX
     SAVE_CONTEXT
     STP     X0, X1, [SP, #-0x10]!   /* X0 is thread sp */
 
@@ -391,10 +390,11 @@ vector_irq:
 
 .global rt_hw_context_switch_exit
 rt_hw_context_switch_exit:
+    CLREX
     MOV     X0, SP
     RESTORE_CONTEXT
 
-#else
+#else   /* RT_USING_SMP */
 
 /*
  * void rt_hw_context_switch_to(rt_ubase_t to);
@@ -402,6 +402,7 @@ rt_hw_context_switch_exit:
  */
 .globl rt_hw_context_switch_to
 rt_hw_context_switch_to:
+    CLREX
     LDR     X0, [X0]
     RESTORE_CONTEXT
 
@@ -413,7 +414,7 @@ rt_hw_context_switch_to:
  */
 .globl rt_hw_context_switch
 rt_hw_context_switch:
-
+    CLREX
     SAVE_CONTEXT_FROM_EL1
 
     MOV    X2, SP
@@ -430,6 +431,7 @@ rt_hw_context_switch:
 .globl rt_interrupt_to_thread
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
+    CLREX
     LDR     X6, =rt_thread_switch_interrupt_flag
     LDR     X7, [X6]
     CMP     X7, #1
@@ -506,7 +508,7 @@ vector_irq:
 vector_irq_exit:
     MOV     SP, X0
     RESTORE_CONTEXT_WITHOUT_MMU_SWITCH
-#endif
+#endif  /* RT_USING_SMP */
 
 // -------------------------------------------------
 

+ 3 - 0
libcpu/arm/cortex-a/context_gcc.S

@@ -40,6 +40,7 @@ rt_hw_interrupt_enable:
  */
 .globl rt_hw_context_switch_to
 rt_hw_context_switch_to:
+    clrex
     ldr sp, [r0]            @ get new task stack pointer
 
 #ifdef RT_USING_SMP
@@ -76,6 +77,7 @@ _guest_switch_lvl:
  */
 .globl rt_hw_context_switch
 rt_hw_context_switch:
+    clrex
     stmfd   sp!, {lr}       @ push pc (lr should be pushed in place of PC)
     stmfd   sp!, {r0-r12, lr}   @ push lr & register file
 
@@ -143,6 +145,7 @@ rt_hw_context_switch:
 .globl rt_interrupt_to_thread
 .globl rt_hw_context_switch_interrupt
 rt_hw_context_switch_interrupt:
+    clrex
 #ifdef RT_USING_SMP
     /* r0 :svc_mod context
      * r1 :addr of from_thread's sp

+ 0 - 2
libcpu/arm/cortex-a/start_gcc.S

@@ -408,8 +408,6 @@ vector_fiq:
 .globl vector_irq
 vector_irq:
 #ifdef RT_USING_SMP
-    clrex
-
     stmfd   sp!, {r0, r1}
     cps     #Mode_SVC
     mov     r0, sp          /* svc_sp */