summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/cpu_switch.S
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-01-20 12:07:49 +0000
committerkib <kib@FreeBSD.org>2009-01-20 12:07:49 +0000
commita23ffa06354566ecd7c1837feb2d6ff743f52646 (patch)
treed4fd728a68b2c986e8e89a6b93747a81de552704 /sys/amd64/amd64/cpu_switch.S
parentb0ac3e6702ec12d4341b573e8e7ca09fdab66091 (diff)
downloadFreeBSD-src-a23ffa06354566ecd7c1837feb2d6ff743f52646.zip
FreeBSD-src-a23ffa06354566ecd7c1837feb2d6ff743f52646.tar.gz
The context switch to the 32bit binary does not properly restore
the fsbase value. The switch loads the fs segment register, that invalidates the value in fsbase msr, thus value in %r9 can not be considered the current value for fsbase anymore. Unconditionally reload fsbase when switching to 32bit binary. PR: 130526 MFC after: 3 weeks
Diffstat (limited to 'sys/amd64/amd64/cpu_switch.S')
-rw-r--r--sys/amd64/amd64/cpu_switch.S3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index 99d6716..baca2db 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -199,6 +199,7 @@ done_load_seg:
cmpq PCB_FSBASE(%r8),%r9
jz 1f
/* Restore userland %fs */
+restore_fsbase:
movl $MSR_FSBASE,%ecx
movl PCB_FSBASE(%r8),%eax
movl PCB_FSBASE+4(%r8),%edx
@@ -281,7 +282,7 @@ load_seg:
movl PCB_DS(%r8),%ds
movl PCB_ES(%r8),%es
movl PCB_FS(%r8),%fs
- jmp done_load_seg
+ jmp restore_fsbase
/* Restore userland %gs while preserving kernel gsbase */
2: movq PCPU(GS32P),%rax
movq PCB_GS32SD(%r8),%rcx
OpenPOWER on IntegriCloud