diff options
author | cognet <cognet@FreeBSD.org> | 2009-02-12 23:23:30 +0000 |
---|---|---|
committer | cognet <cognet@FreeBSD.org> | 2009-02-12 23:23:30 +0000 |
commit | a4557d874cea19c85b904233ff0bc7ec8fc632ee (patch) | |
tree | 12b428cc8123665fb6db4a1437aa7d2d1f139c8c /sys/arm | |
parent | fd95932030a1e694173ce5b6c7d417ad5938b302 (diff) | |
download | FreeBSD-src-a4557d874cea19c85b904233ff0bc7ec8fc632ee.zip FreeBSD-src-a4557d874cea19c85b904233ff0bc7ec8fc632ee.tar.gz |
To prevent various race conditions in the RAS code, store and restore the
values in ARM_RAS_START and ARM_RAS_END at context switch time.
MFC after: 1 week
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/arm/genassym.c | 2 | ||||
-rw-r--r-- | sys/arm/arm/swtch.S | 20 | ||||
-rw-r--r-- | sys/arm/include/proc.h | 2 | ||||
-rw-r--r-- | sys/arm/include/sysarch.h | 3 |
4 files changed, 23 insertions, 4 deletions
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c index ba75886..40b2988 100644 --- a/sys/arm/arm/genassym.c +++ b/sys/arm/arm/genassym.c @@ -96,6 +96,8 @@ ASSYM(TD_FRAME, offsetof(struct thread, td_frame)); ASSYM(TD_MD, offsetof(struct thread, td_md)); ASSYM(TD_LOCK, offsetof(struct thread, td_lock)); ASSYM(MD_TP, offsetof(struct mdthread, md_tp)); +ASSYM(MD_RAS_START, offsetof(struct mdthread, md_ras_start)); +ASSYM(MD_RAS_END, offsetof(struct mdthread, md_ras_end)); ASSYM(TF_R0, offsetof(struct trapframe, tf_r0)); ASSYM(TF_R1, offsetof(struct trapframe, tf_r1)); diff --git a/sys/arm/arm/swtch.S b/sys/arm/arm/swtch.S index 8f0f9b2..e164196 100644 --- a/sys/arm/arm/swtch.S +++ b/sys/arm/arm/swtch.S @@ -205,8 +205,12 @@ ENTRY(cpu_throw) /* Set the new tp */ ldr r6, [r5, #(TD_MD + MD_TP)] - ldr r5, =ARM_TP_ADDRESS - strt r6, [r5] + ldr r4, =ARM_TP_ADDRESS + str r6, [r4] + ldr r6, [r5, #(TD_MD + MD_RAS_START)] + str r6, [r4, #4] /* ARM_RAS_START */ + ldr r6, [r5, #(TD_MD + MD_RAS_END)] + str r6, [r4, #4] /* ARM_RAS_END */ /* Hook in a new pcb */ ldr r6, .Lcurpcb @@ -265,12 +269,20 @@ ENTRY(cpu_switch) */ /* Store the old tp */ ldr r3, =ARM_TP_ADDRESS - ldrt r9, [r3] + ldr r9, [r3] str r9, [r0, #(TD_MD + MD_TP)] + ldr r9, [r3, #4] + str r9, [r0, #(TD_MD + MD_RAS_START)] + ldr r9, [r3, #8] + str r9, [r0, #(TD_MD + MD_RAS_END)] /* Set the new tp */ ldr r9, [r1, #(TD_MD + MD_TP)] - strt r9, [r3] + str r9, [r3] + ldr r9, [r1, #(TD_MD + MD_RAS_START)] + str r9, [r3, #4] + ldr r9, [r1, #(TD_MD + MD_RAS_END)] + str r9, [r3, #8] /* Get the user structure for the new process in r9 */ ldr r9, [r1, #(TD_PCB)] diff --git a/sys/arm/include/proc.h b/sys/arm/include/proc.h index 597c75c..c7b2a4e 100644 --- a/sys/arm/include/proc.h +++ b/sys/arm/include/proc.h @@ -51,6 +51,8 @@ struct mdthread { int md_ptrace_instr; int md_ptrace_addr; void *md_tp; + void *md_ras_start; + void *md_ras_end; }; struct mdproc { diff --git a/sys/arm/include/sysarch.h b/sys/arm/include/sysarch.h index 5623fd7..12db4df 100644 --- a/sys/arm/include/sysarch.h +++ b/sys/arm/include/sysarch.h @@ -42,6 +42,9 @@ * 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 + * 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. */ #define ARM_TP_ADDRESS (ARM_VECTORS_HIGH + 0x1000) #define ARM_RAS_START (ARM_TP_ADDRESS + 4) |