From a43268a7464c3240c1d9b860bd32d4f656a6dfea Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Thu, 12 Feb 2009 23:23:30 +0000 Subject: [PATCH] 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 --- sys/arm/arm/genassym.c | 2 ++ sys/arm/arm/swtch.S | 20 ++++++++++++++++---- sys/arm/include/proc.h | 2 ++ 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 ba75886490e..40b29883bda 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 8f0f9b26571..e1641960e4a 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 597c75ceaed..c7b2a4ef5c9 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 5623fd72f1e..12db4df6e24 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)