summaryrefslogtreecommitdiffstats
path: root/sys/powerpc/aim/trap_subr32.S
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2011-06-23 22:21:28 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2011-06-23 22:21:28 +0000
commit1d215b1285ab0897c64a473f1b6b30f0311b87d0 (patch)
tree76a642e618833d9949a5962d0c3847b6ff888af7 /sys/powerpc/aim/trap_subr32.S
parent1f9c357d9bfe97631d50ce6a97e271360f417bbb (diff)
downloadFreeBSD-src-1d215b1285ab0897c64a473f1b6b30f0311b87d0.zip
FreeBSD-src-1d215b1285ab0897c64a473f1b6b30f0311b87d0.tar.gz
Use the ABI-mandated thread pointer register (r2 for ppc32, r13 for ppc64)
instead of a PCPU field for curthread. This averts a race on SMP systems with a high interrupt rate where the thread looking up the value of curthread could be preempted and migrated between obtaining the PCPU pointer and reading the value of pc_curthread, resulting in curthread being observed to be the current thread on the thread's original CPU. This played merry havoc with the system, in particular with mutexes. Many thanks to jhb for helping me work this one out. Note that Book-E is in principle susceptible to the same problem, but has not been modified yet due to lack of Book-E hardware. MFC after: 2 weeks
Diffstat (limited to 'sys/powerpc/aim/trap_subr32.S')
-rw-r--r--sys/powerpc/aim/trap_subr32.S14
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/powerpc/aim/trap_subr32.S b/sys/powerpc/aim/trap_subr32.S
index 80329cd..f00020b 100644
--- a/sys/powerpc/aim/trap_subr32.S
+++ b/sys/powerpc/aim/trap_subr32.S
@@ -155,9 +155,15 @@
stw %r28,FRAME_AIM_DAR+8(1); \
stw %r29,FRAME_AIM_DSISR+8(1); /* save dsisr/srr0/srr1 */ \
stw %r30,FRAME_SRR0+8(1); \
- stw %r31,FRAME_SRR1+8(1)
+ stw %r31,FRAME_SRR1+8(1); \
+ lwz %r2,PC_CURTHREAD(%r2) /* set curthread pointer */
#define FRAME_LEAVE(savearea) \
+/* Disable exceptions: */ \
+ mfmsr %r2; \
+ andi. %r2,%r2,~PSL_EE@l; \
+ mtmsr %r2; \
+ isync; \
/* Now restore regs: */ \
lwz %r2,FRAME_SRR0+8(%r1); \
lwz %r3,FRAME_SRR1+8(%r1); \
@@ -209,7 +215,7 @@
mtsprg3 %r3; \
/* Disable translation, machine check and recoverability: */ \
mfmsr %r2; \
- andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_EE|PSL_ME|PSL_RI)@l; \
+ andi. %r2,%r2,~(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \
mtmsr %r2; \
isync; \
/* Decide whether we return to user mode: */ \
@@ -764,8 +770,8 @@ CNAME(trapexit):
bf 17,1f /* branch if PSL_PR is false */
GET_CPUINFO(%r3) /* get per-CPU pointer */
- lwz %r4, PC_CURTHREAD(%r3) /* deref to get curthread */
- lwz %r4, TD_FLAGS(%r4) /* get thread flags value */
+ lwz %r4, TD_FLAGS(%r2) /* get thread flags value
+ * (r2 is curthread) */
lis %r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@h
ori %r5,%r5, (TDF_ASTPENDING|TDF_NEEDRESCHED)@l
and. %r4,%r4,%r5
OpenPOWER on IntegriCloud