summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2002-11-22 11:43:06 +0000
committerdavidxu <davidxu@FreeBSD.org>2002-11-22 11:43:06 +0000
commited0591ed98516f3316f0375f547836a22be09e9f (patch)
treecd8200d6c38b101fe76cf17a065b8870c70d60f0 /lib
parentf89233ef8d826c7b28410899f4d41e455fd50311 (diff)
downloadFreeBSD-src-ed0591ed98516f3316f0375f547836a22be09e9f.zip
FreeBSD-src-ed0591ed98516f3316f0375f547836a22be09e9f.tar.gz
In _thread_enter_uts, fix eflags saving bug.
In _thread_switch, set current thread pointer in kse mailbox only after all registers copied out of thread mailbox, kernel will do upcall at trap time, if set current thread pointer before loading all registers from thread mailbox, at trap time, the thread mailbox data will be overwritten by kernel, result is junk data is loaded into CPU.
Diffstat (limited to 'lib')
-rw-r--r--lib/libkse/arch/i386/i386/thr_enter_uts.S3
-rw-r--r--lib/libpthread/arch/i386/i386/thr_enter_uts.S3
-rw-r--r--lib/libpthread/arch/i386/i386/thr_switch.S19
3 files changed, 17 insertions, 8 deletions
diff --git a/lib/libkse/arch/i386/i386/thr_enter_uts.S b/lib/libkse/arch/i386/i386/thr_enter_uts.S
index 8d38b0f..10edd3f 100644
--- a/lib/libkse/arch/i386/i386/thr_enter_uts.S
+++ b/lib/libkse/arch/i386/i386/thr_enter_uts.S
@@ -79,7 +79,8 @@ ENTRY(_thread_enter_uts)
*/
fnstcw MC_FP_CW_OFFSET(%edx)
movl $0, MC_OWNEDFP_OFFSET(%edx) /* no FP */
- lahf /* get eflags */
+ pushfl /* get eflags */
+ popl %eax
movl %eax, 68(%edx) /* store eflags */
movl %esp, %eax /* setcontext pushes the return */
addl $4, %eax /* address onto the top of the */
diff --git a/lib/libpthread/arch/i386/i386/thr_enter_uts.S b/lib/libpthread/arch/i386/i386/thr_enter_uts.S
index 8d38b0f..10edd3f 100644
--- a/lib/libpthread/arch/i386/i386/thr_enter_uts.S
+++ b/lib/libpthread/arch/i386/i386/thr_enter_uts.S
@@ -79,7 +79,8 @@ ENTRY(_thread_enter_uts)
*/
fnstcw MC_FP_CW_OFFSET(%edx)
movl $0, MC_OWNEDFP_OFFSET(%edx) /* no FP */
- lahf /* get eflags */
+ pushfl /* get eflags */
+ popl %eax
movl %eax, 68(%edx) /* store eflags */
movl %esp, %eax /* setcontext pushes the return */
addl $4, %eax /* address onto the top of the */
diff --git a/lib/libpthread/arch/i386/i386/thr_switch.S b/lib/libpthread/arch/i386/i386/thr_switch.S
index a529f9d..51dcc2c 100644
--- a/lib/libpthread/arch/i386/i386/thr_switch.S
+++ b/lib/libpthread/arch/i386/i386/thr_switch.S
@@ -54,8 +54,8 @@ ENTRY(_thread_switch)
je 2f
movl $-1, %eax /* bzzzt, invalid context */
jmp 5f
-2: movl 8(%esp), %eax /* get address of curthreadp */
- movl %edx, (%eax) /* we're now the current thread */
+2: movl 8(%esp), %ecx /* get address of curthreadp */
+ movl %edx, %ebx /* save the pointer for later */
/*
* From here on, we don't touch the old stack.
*/
@@ -78,12 +78,19 @@ ENTRY(_thread_switch)
jmp 4f
3: fninit
fldcw MC_FP_CW_OFFSET(%edx)
-4: movl 48(%edx), %eax /* restore ax, bx, cx */
- movl 36(%edx), %ebx
- movl 44(%edx), %ecx
+4: movl 48(%edx), %eax /* restore ax, bx, cx, dx */
pushl 68(%edx) /* flags on stack */
- pushl 40(%edx) /* %edx on stack */
+ pushl 36(%edx) /* %ebx on stack */
+ pushl 44(%edx) /* %ecx on stack */
+ pushl 40(%edx) /* %edx on stack */
+ /*
+ * all registers are now moved out of mailbox
+ * it's now safe to set current thread pointer
+ */
+ movl %ebx,(%ecx)
popl %edx /* %edx off stack */
+ popl %ecx /* %ecx off stack */
+ popl %ebx /* %ebx off stack */
popf /* flags off stack */
5: ret /* %eip off stack */
OpenPOWER on IntegriCloud