Procházet zdrojové kódy

RTX5: Add CLREX to exception exit paths

Safe use of LDREX/STREX requires that any thread switches, interrupts or
any other disruption between the LDREX and STREX be visible, so
exception handlers must ensure that the exclusive monitor flag is clear
when returning to foreground code.

Two possible error cases are

   <thread 1>
   LDREX          exclusive monitor set
   <thread switch 2>
   STR            exclusive monitor cleared
   LDREX          exclusive monitor set
   <thread switch 1>
   STREX          !!! store succeeds because exclusive monitor set

or

   <thread>
   LDREX          exclusive monitor set
   <IRQ>
   STR            exclusive monitor cleared
   LDREX          exclusive monitor set
   // No store because of failed compare-and-swap
   <IRQ return>
   STREX          !!! store succeeds because exclusive monitor set

For ARMv7-M and ARMv8-A, the monitor is automatically cleared on
exception return, but ARMv7-A requires that the clear be performed in
software.

Unneeded CLREX removed from data abort entry.  The entry state of the
exclusive monitor may be unknown on entry to an exception handler, but
no code can possibly be relying on it being clear - an STREX that is
intended to store must be preceded by an LDREX.
Kevin Bracey před 7 roky
rodič
revize
647a940cb2

+ 6 - 1
CMSIS/RTOS2/RTX/Source/ARM/irq_ca.s

@@ -100,6 +100,7 @@ Undef_Cont
                 SUB     LR, LR, R0
                 SUB     LR, LR, R0
                 LDR     R0, [SP, #28]               ; Restore stacked SPSR
                 LDR     R0, [SP, #28]               ; Restore stacked SPSR
                 MSR     SPSR_CXSF, R0
                 MSR     SPSR_CXSF, R0
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 ADD     SP, SP, #8                  ; Adjust SP for already-restored banked registers
                 ADD     SP, SP, #8                  ; Adjust SP for already-restored banked registers
                 MOVS    PC, LR
                 MOVS    PC, LR
@@ -129,6 +130,7 @@ PAbt_Handler\
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 ; Unadjust stack
                 ADD     SP, SP, R12                 ; Unadjust stack
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stack APCS registers
                 POP     {R0-R4, R12}                ; Restore stack APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -143,7 +145,6 @@ DAbt_Handler\
                 SUB     LR, LR, #8                  ; Pre-adjust LR
                 SUB     LR, LR, #8                  ; Pre-adjust LR
                 SRSFD   SP!, #MODE_ABT              ; Save LR and SPRS to ABT mode stack
                 SRSFD   SP!, #MODE_ABT              ; Save LR and SPRS to ABT mode stack
                 PUSH    {R0-R4, R12}                ; Save APCS corruptible registers to ABT mode stack
                 PUSH    {R0-R4, R12}                ; Save APCS corruptible registers to ABT mode stack
-                CLREX                               ; State of exclusive monitors unknown after taken data abort
                 MRC     p15, 0, R0, c5, c0, 0       ; DFSR
                 MRC     p15, 0, R0, c5, c0, 0       ; DFSR
                 MRC     p15, 0, R1, c6, c0, 0       ; DFAR
                 MRC     p15, 0, R1, c6, c0, 0       ; DFAR
 
 
@@ -158,6 +159,7 @@ DAbt_Handler\
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 ; Unadjust stack
                 ADD     SP, SP, R12                 ; Unadjust stack
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -211,6 +213,7 @@ IRQ_End
                 SUBS    R1, R1, #1                  ; Decrement IRQ nesting level
                 SUBS    R1, R1, #1                  ; Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               ; Clear exclusive monitor for interrupted code
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from IRQ handler
                 RFEFD   SP!                         ; Return from IRQ handler
 
 
@@ -281,6 +284,7 @@ SVC_ContextCheck
                 SUB     R1, R1, #1                  ; Decrement IRQ nesting level
                 SUB     R1, R1, #1                  ; Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -293,6 +297,7 @@ SVC_User
                 LDR     R12,[R5,R12,LSL #2]         ; Load SVC Function Address
                 LDR     R12,[R5,R12,LSL #2]         ; Load SVC Function Address
                 BLX     R12                         ; Call SVC Function
                 BLX     R12                         ; Call SVC Function
 SVC_Done
 SVC_Done
+                CLREX                               ; Clear exclusive monitor
                 POP     {R4, R5, R12, LR}
                 POP     {R4, R5, R12, LR}
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 

+ 6 - 1
CMSIS/RTOS2/RTX/Source/GCC/irq_ca.S

@@ -103,6 +103,7 @@ Undef_Cont:
                 SUB     LR, LR, R0
                 SUB     LR, LR, R0
                 LDR     R0, [SP, #28]               // Restore stacked SPSR
                 LDR     R0, [SP, #28]               // Restore stacked SPSR
                 MSR     SPSR_cxsf, R0
                 MSR     SPSR_cxsf, R0
+                CLREX                               // Clear exclusive monitor
                 POP     {R0-R4, R12}                // Restore stacked APCS registers
                 POP     {R0-R4, R12}                // Restore stacked APCS registers
                 ADD     SP, SP, #8                  // Adjust SP for already-restored banked registers
                 ADD     SP, SP, #8                  // Adjust SP for already-restored banked registers
                 MOVS    PC, LR
                 MOVS    PC, LR
@@ -134,6 +135,7 @@ PAbt_Handler:
                 POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 // Unadjust stack
                 ADD     SP, SP, R12                 // Unadjust stack
 
 
+                CLREX                               // Clear exclusive monitor
                 POP     {R0-R4, R12}                // Restore stack APCS registers
                 POP     {R0-R4, R12}                // Restore stack APCS registers
                 RFEFD   SP!                         // Return from exception
                 RFEFD   SP!                         // Return from exception
 
 
@@ -149,7 +151,6 @@ DAbt_Handler:
                 SUB     LR, LR, #8                  // Pre-adjust LR
                 SUB     LR, LR, #8                  // Pre-adjust LR
                 SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
                 SRSFD   SP!, #MODE_ABT              // Save LR and SPRS to ABT mode stack
                 PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
                 PUSH    {R0-R4, R12}                // Save APCS corruptible registers to ABT mode stack
-                CLREX                               // State of exclusive monitors unknown after taken data abort
                 MRC     p15, 0, R0, c5, c0, 0       // DFSR
                 MRC     p15, 0, R0, c5, c0, 0       // DFSR
                 MRC     p15, 0, R1, c6, c0, 0       // DFAR
                 MRC     p15, 0, R1, c6, c0, 0       // DFAR
 
 
@@ -164,6 +165,7 @@ DAbt_Handler:
                 POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   // Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 // Unadjust stack
                 ADD     SP, SP, R12                 // Unadjust stack
 
 
+                CLREX                               // Clear exclusive monitor
                 POP     {R0-R4, R12}                // Restore stacked APCS registers
                 POP     {R0-R4, R12}                // Restore stacked APCS registers
                 RFEFD   SP!                         // Return from exception
                 RFEFD   SP!                         // Return from exception
 
 
@@ -217,6 +219,7 @@ IRQ_End:
                 SUBS    R1, R1, #1                  // Decrement IRQ nesting level
                 SUBS    R1, R1, #1                  // Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               // Clear exclusive monitor for interrupted code
                 POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
                 RFEFD   SP!                         // Return from IRQ handler
                 RFEFD   SP!                         // Return from IRQ handler
 
 
@@ -286,6 +289,7 @@ SVC_ContextCheck:
                 SUB     R1, R1, #1                  // Decrement IRQ nesting level
                 SUB     R1, R1, #1                  // Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               // Clear exclusive monitor
                 POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            // Restore stacked APCS registers
                 RFEFD   SP!                         // Return from exception
                 RFEFD   SP!                         // Return from exception
 
 
@@ -300,6 +304,7 @@ SVC_User:
                 BLX     R12                         // Call SVC Function
                 BLX     R12                         // Call SVC Function
 
 
 SVC_Done:
 SVC_Done:
+                CLREX                               // Clear exclusive monitor
                 POP     {R4, R5, R12, LR}
                 POP     {R4, R5, R12, LR}
                 RFEFD   SP!                         // Return from exception
                 RFEFD   SP!                         // Return from exception
 
 

+ 6 - 1
CMSIS/RTOS2/RTX/Source/IAR/irq_ca.s

@@ -100,6 +100,7 @@ Undef_Cont
                 SUB     LR, LR, R0
                 SUB     LR, LR, R0
                 LDR     R0, [SP, #28]               ; Restore stacked SPSR
                 LDR     R0, [SP, #28]               ; Restore stacked SPSR
                 MSR     SPSR_CXSF, R0
                 MSR     SPSR_CXSF, R0
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 ADD     SP, SP, #8                  ; Adjust SP for already-restored banked registers
                 ADD     SP, SP, #8                  ; Adjust SP for already-restored banked registers
                 MOVS    PC, LR
                 MOVS    PC, LR
@@ -126,6 +127,7 @@ PAbt_Handler
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 ; Unadjust stack
                 ADD     SP, SP, R12                 ; Unadjust stack
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stack APCS registers
                 POP     {R0-R4, R12}                ; Restore stack APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -137,7 +139,6 @@ DAbt_Handler
                 SUB     LR, LR, #8                  ; Pre-adjust LR
                 SUB     LR, LR, #8                  ; Pre-adjust LR
                 SRSFD   SP!, #MODE_ABT              ; Save LR and SPRS to ABT mode stack
                 SRSFD   SP!, #MODE_ABT              ; Save LR and SPRS to ABT mode stack
                 PUSH    {R0-R4, R12}                ; Save APCS corruptible registers to ABT mode stack
                 PUSH    {R0-R4, R12}                ; Save APCS corruptible registers to ABT mode stack
-                CLREX                               ; State of exclusive monitors unknown after taken data abort
                 MRC     p15, 0, R0, c5, c0, 0       ; DFSR
                 MRC     p15, 0, R0, c5, c0, 0       ; DFSR
                 MRC     p15, 0, R1, c6, c0, 0       ; DFAR
                 MRC     p15, 0, R1, c6, c0, 0       ; DFAR
 
 
@@ -152,6 +153,7 @@ DAbt_Handler
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 POP     {R12, LR}                   ; Get stack adjustment & discard dummy LR
                 ADD     SP, SP, R12                 ; Unadjust stack
                 ADD     SP, SP, R12                 ; Unadjust stack
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 POP     {R0-R4, R12}                ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -202,6 +204,7 @@ IRQ_End
                 SUBS    R1, R1, #1                  ; Decrement IRQ nesting level
                 SUBS    R1, R1, #1                  ; Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               ; Clear exclusive monitor for interrupted code
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from IRQ handler
                 RFEFD   SP!                         ; Return from IRQ handler
 
 
@@ -269,6 +272,7 @@ SVC_ContextCheck
                 SUB     R1, R1, #1                  ; Decrement IRQ nesting level
                 SUB     R1, R1, #1                  ; Decrement IRQ nesting level
                 STR     R1, [R0]
                 STR     R1, [R0]
 
 
+                CLREX                               ; Clear exclusive monitor
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 POP     {R0-R3, R12, LR}            ; Restore stacked APCS registers
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception
 
 
@@ -281,6 +285,7 @@ SVC_User
                 LDR     R12,[R5,R12,LSL #2]         ; Load SVC Function Address
                 LDR     R12,[R5,R12,LSL #2]         ; Load SVC Function Address
                 BLX     R12                         ; Call SVC Function
                 BLX     R12                         ; Call SVC Function
 SVC_Done
 SVC_Done
+                CLREX                               ; Clear exclusive monitor
                 POP     {R4, R5, R12, LR}
                 POP     {R4, R5, R12, LR}
                 RFEFD   SP!                         ; Return from exception
                 RFEFD   SP!                         ; Return from exception