mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-04 09:09:56 +00:00
Fix 2 bugs :
- A race condition could happen if two threads were using RAS at the same time as the code didn't reset RAS_END, the RAS code could believe we were not in a RAS, when we were in fact. - Using signed value logic to compare addresses wasn't such a good idea. Many thanks to Ian to investigate on these issues. Pointy hat to: cognet PR: arm/161498 Submitted by: Ian Lepore <freebsd At damnhippie DOT dyndns dot org MFC after: 1 week
This commit is contained in:
parent
04c4548981
commit
c435dafb84
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=226443
@ -71,9 +71,8 @@
|
||||
ldr r0, =ARM_RAS_START; \
|
||||
mov r1, #0; \
|
||||
str r1, [r0]; \
|
||||
ldr r0, =ARM_RAS_END; \
|
||||
mov r1, #0xffffffff; \
|
||||
str r1, [r0];
|
||||
str r1, [r0, #4];
|
||||
|
||||
/*
|
||||
* PULLFRAME - macro to pull a trap frame from the stack in the current mode
|
||||
@ -120,20 +119,19 @@
|
||||
stmia r0, {r13-r14}^; /* Push the user mode registers */ \
|
||||
mov r0, r0; /* NOP for previous instruction */ \
|
||||
ldr r5, =ARM_RAS_START; /* Check if there's any RAS */ \
|
||||
ldr r3, [r5]; \
|
||||
cmp r3, #0; /* Is the update needed ? */ \
|
||||
ldrgt lr, [r0, #16]; \
|
||||
ldrgt r1, =ARM_RAS_END; \
|
||||
ldrgt r4, [r1]; /* Get the end of the RAS */ \
|
||||
movgt r2, #0; /* Reset the magic addresses */ \
|
||||
strgt r2, [r5]; \
|
||||
movgt r2, #0xffffffff; \
|
||||
strgt r2, [r1]; \
|
||||
cmpgt lr, r3; /* Were we in the RAS ? */ \
|
||||
cmpgt r4, lr; \
|
||||
strgt r3, [r0, #16]; /* Yes, update the pc */ \
|
||||
mrs r0, spsr_all; /* Put the SPSR on the stack */ \
|
||||
str r0, [sp, #-4]!
|
||||
ldr r4, [r5, #4]; /* reset it to point at the */ \
|
||||
cmp r4, #0xffffffff; /* end of memory if necessary; */ \
|
||||
movne r1, #0xffffffff; /* leave value in r4 for later */ \
|
||||
strne r1, [r5, #4]; /* comparision against PC. */ \
|
||||
ldr r3, [r5]; /* Retrieve global RAS_START */ \
|
||||
cmp r3, #0; /* and reset it if non-zero. */ \
|
||||
movne r1, #0; /* If non-zero RAS_START and */ \
|
||||
strne r1, [r5]; /* PC was lower than RAS_END, */ \
|
||||
ldrne r1, [r0, #16]; /* adjust the saved PC so that */ \
|
||||
cmpne r4, r1; /* execution later resumes at */ \
|
||||
strhi r3, [r0, #16]; /* the RAS_START location. */ \
|
||||
mrs r0, spsr_all; \
|
||||
str r0, [sp, #-4]!
|
||||
|
||||
/*
|
||||
* PULLFRAMEFROMSVCANDEXIT - macro to pull a trap frame from the stack
|
||||
|
@ -42,9 +42,13 @@
|
||||
* The ARM_TP_ADDRESS points to a special purpose page, which is used as local
|
||||
* store for the ARM per-thread data and Restartable Atomic Sequences support.
|
||||
* Put it just above the "high" vectors' page.
|
||||
* the cpu_switch() code assumes ARM_RAS_START is ARM_TP_ADDRESS + 4, and
|
||||
* The cpu_switch() code assumes ARM_RAS_START is ARM_TP_ADDRESS + 4, and
|
||||
* ARM_RAS_END is ARM_TP_ADDRESS + 8, so if that ever changes, be sure to
|
||||
* update the cpu_switch() (and cpu_throw()) code as well.
|
||||
* In addition, code in arm/include/atomic.h and arm/include/asmacros.h
|
||||
* assumes that ARM_RAS_END is at ARM_RAS_START+4, so be sure to update those
|
||||
* if ARM_RAS_END moves in relation to ARM_RAS_START (look for occurrances
|
||||
* of ldr/str rm,[rn, #4]).
|
||||
*/
|
||||
#define ARM_TP_ADDRESS (ARM_VECTORS_HIGH + 0x1000)
|
||||
#define ARM_RAS_START (ARM_TP_ADDRESS + 4)
|
||||
|
Loading…
Reference in New Issue
Block a user