summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-08-03 15:32:08 +0000
committerjkim <jkim@FreeBSD.org>2010-08-03 15:32:08 +0000
commitc530d20c6a35314172f8e6e2efcd2a25e999b397 (patch)
tree1276c6922c556f30fde3cb5ef2233685cf3dd7c5 /sys/amd64
parent3327e8714209c4d4c9bb58dd4c03090e6e6eee25 (diff)
downloadFreeBSD-src-c530d20c6a35314172f8e6e2efcd2a25e999b397.zip
FreeBSD-src-c530d20c6a35314172f8e6e2efcd2a25e999b397.tar.gz
savectx() has not been used for fork(2) for about 15 years. [1]
Do not clobber FPU thread's PCB as it is more harmful. When we resume CPU, unconditionally reload FPU state. Pointed out by: bde [1]
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/acpica/acpi_switch.S76
-rw-r--r--sys/amd64/acpica/acpi_wakecode.S4
-rw-r--r--sys/amd64/amd64/cpu_switch.S92
3 files changed, 65 insertions, 107 deletions
diff --git a/sys/amd64/acpica/acpi_switch.S b/sys/amd64/acpica/acpi_switch.S
index d98df85..2b2887b 100644
--- a/sys/amd64/acpica/acpi_switch.S
+++ b/sys/amd64/acpica/acpi_switch.S
@@ -34,11 +34,11 @@
#include "acpi_wakedata.h"
#include "assym.s"
-#define WAKEUP_CTX(member) wakeup_ ## member - wakeup_ctx(%rdi)
+#define WAKEUP_CTX(member) wakeup_ ## member - wakeup_ctx(%rsi)
ENTRY(acpi_restorecpu)
/* Switch to KPML4phys. */
- movq %rsi, %rax
+ movq %rdi, %rax
movq %rax, %cr3
/* Restore GDT. */
@@ -47,7 +47,7 @@ ENTRY(acpi_restorecpu)
1:
/* Fetch PCB. */
- movq WAKEUP_CTX(pcb), %rsi
+ movq WAKEUP_CTX(pcb), %rdi
/* Force kernel segment registers. */
movl $KDSEL, %eax
@@ -60,16 +60,16 @@ ENTRY(acpi_restorecpu)
movw %ax, %gs
movl $MSR_FSBASE, %ecx
- movl PCB_FSBASE(%rsi), %eax
- movl 4 + PCB_FSBASE(%rsi), %edx
+ movl PCB_FSBASE(%rdi), %eax
+ movl 4 + PCB_FSBASE(%rdi), %edx
wrmsr
movl $MSR_GSBASE, %ecx
- movl PCB_GSBASE(%rsi), %eax
- movl 4 + PCB_GSBASE(%rsi), %edx
+ movl PCB_GSBASE(%rdi), %eax
+ movl 4 + PCB_GSBASE(%rdi), %edx
wrmsr
movl $MSR_KGSBASE, %ecx
- movl PCB_KGSBASE(%rsi), %eax
- movl 4 + PCB_KGSBASE(%rsi), %edx
+ movl PCB_KGSBASE(%rdi), %eax
+ movl 4 + PCB_KGSBASE(%rdi), %edx
wrmsr
/* Restore EFER. */
@@ -101,20 +101,20 @@ ENTRY(acpi_restorecpu)
wrmsr
/* Restore CR0 except for FPU mode. */
- movq PCB_CR0(%rsi), %rax
+ movq PCB_CR0(%rdi), %rax
movq %rax, %rcx
andq $~(CR0_EM | CR0_TS), %rax
movq %rax, %cr0
/* Restore CR2 and CR4. */
- movq PCB_CR2(%rsi), %rax
+ movq PCB_CR2(%rdi), %rax
movq %rax, %cr2
- movq PCB_CR4(%rsi), %rax
+ movq PCB_CR4(%rdi), %rax
movq %rax, %cr4
/* Restore descriptor tables. */
- lidt PCB_IDT(%rsi)
- lldt PCB_LDT(%rsi)
+ lidt PCB_IDT(%rdi)
+ lldt PCB_LDT(%rdi)
#define SDT_SYSTSS 9
#define SDT_SYSBSY 11
@@ -122,58 +122,44 @@ ENTRY(acpi_restorecpu)
/* Clear "task busy" bit and reload TR. */
movq PCPU(TSS), %rax
andb $(~SDT_SYSBSY | SDT_SYSTSS), 5(%rax)
- movw PCB_TR(%rsi), %ax
+ movw PCB_TR(%rdi), %ax
ltr %ax
#undef SDT_SYSTSS
#undef SDT_SYSBSY
/* Restore other callee saved registers. */
- movq PCB_R15(%rsi), %r15
- movq PCB_R14(%rsi), %r14
- movq PCB_R13(%rsi), %r13
- movq PCB_R12(%rsi), %r12
- movq PCB_RBP(%rsi), %rbp
- movq PCB_RSP(%rsi), %rsp
- movq PCB_RBX(%rsi), %rbx
+ movq PCB_R15(%rdi), %r15
+ movq PCB_R14(%rdi), %r14
+ movq PCB_R13(%rdi), %r13
+ movq PCB_R12(%rdi), %r12
+ movq PCB_RBP(%rdi), %rbp
+ movq PCB_RSP(%rdi), %rsp
+ movq PCB_RBX(%rdi), %rbx
/* Restore debug registers. */
- movq PCB_DR0(%rsi), %rax
+ movq PCB_DR0(%rdi), %rax
movq %rax, %dr0
- movq PCB_DR1(%rsi), %rax
+ movq PCB_DR1(%rdi), %rax
movq %rax, %dr1
- movq PCB_DR2(%rsi), %rax
+ movq PCB_DR2(%rdi), %rax
movq %rax, %dr2
- movq PCB_DR3(%rsi), %rax
+ movq PCB_DR3(%rdi), %rax
movq %rax, %dr3
- movq PCB_DR6(%rsi), %rax
+ movq PCB_DR6(%rdi), %rax
movq %rax, %dr6
- movq PCB_DR7(%rsi), %rax
+ movq PCB_DR7(%rdi), %rax
movq %rax, %dr7
-#define __INITIAL_FPUCW__ 0x037f
-#define __INITIAL_MXCSR__ 0x1f80
-
- /* Initialize FPU and restore state if necessary. */
+ /* Restore FPU state. */
fninit
- movw $__INITIAL_FPUCW__, -2(%rsp)
- fldcw -2(%rsp)
- movl $__INITIAL_MXCSR__, -4(%rsp)
- ldmxcsr -4(%rsp)
- movq PCPU(FPCURTHREAD), %rax
- testq %rax, %rax
- je 1f
- fxrstor PCB_USERFPU(%rsi)
-1:
-
-#undef __INITIAL_FPUCW__
-#undef __INITIAL_MXCSR__
+ fxrstor PCB_USERFPU(%rdi)
/* Reload CR0. */
movq %rcx, %cr0
/* Restore return address. */
- movq PCB_RIP(%rsi), %rax
+ movq PCB_RIP(%rdi), %rax
movq %rax, (%rsp)
/* Indicate the CPU is resumed. */
diff --git a/sys/amd64/acpica/acpi_wakecode.S b/sys/amd64/acpica/acpi_wakecode.S
index 6d55149..e131c97 100644
--- a/sys/amd64/acpica/acpi_wakecode.S
+++ b/sys/amd64/acpica/acpi_wakecode.S
@@ -210,8 +210,8 @@ wakeup_64:
mov %ax, %ds
/* Restore arguments and return. */
- movq wakeup_ctx - wakeup_start(%rbx), %rdi
- movq wakeup_kpml4 - wakeup_start(%rbx), %rsi
+ movq wakeup_kpml4 - wakeup_start(%rbx), %rdi
+ movq wakeup_ctx - wakeup_start(%rbx), %rsi
movq wakeup_retaddr - wakeup_start(%rbx), %rax
jmp *%rax
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S
index e4355e6..b294864 100644
--- a/sys/amd64/amd64/cpu_switch.S
+++ b/sys/amd64/amd64/cpu_switch.S
@@ -302,93 +302,65 @@ END(cpu_switch)
* Update pcb, saving current processor state.
*/
ENTRY(savectx)
- /* Fetch PCB. */
- movq %rdi,%rsi
-
/* Save caller's return address. */
movq (%rsp),%rax
- movq %rax,PCB_RIP(%rsi)
-
- movq %rbx,PCB_RBX(%rsi)
- movq %rsp,PCB_RSP(%rsi)
- movq %rbp,PCB_RBP(%rsi)
- movq %r12,PCB_R12(%rsi)
- movq %r13,PCB_R13(%rsi)
- movq %r14,PCB_R14(%rsi)
- movq %r15,PCB_R15(%rsi)
-
+ movq %rax,PCB_RIP(%rdi)
+
+ movq %rbx,PCB_RBX(%rdi)
+ movq %rsp,PCB_RSP(%rdi)
+ movq %rbp,PCB_RBP(%rdi)
+ movq %r12,PCB_R12(%rdi)
+ movq %r13,PCB_R13(%rdi)
+ movq %r14,PCB_R14(%rdi)
+ movq %r15,PCB_R15(%rdi)
+
+ movq %cr0,%rsi
+ movq %rsi,PCB_CR0(%rdi)
movq %cr2,%rax
- movq %rax,PCB_CR2(%rsi)
+ movq %rax,PCB_CR2(%rdi)
movq %cr3,%rax
- movq %rax,PCB_CR3(%rsi)
+ movq %rax,PCB_CR3(%rdi)
movq %cr4,%rax
- movq %rax,PCB_CR4(%rsi)
+ movq %rax,PCB_CR4(%rdi)
movq %dr0,%rax
- movq %rax,PCB_DR0(%rsi)
+ movq %rax,PCB_DR0(%rdi)
movq %dr1,%rax
- movq %rax,PCB_DR1(%rsi)
+ movq %rax,PCB_DR1(%rdi)
movq %dr2,%rax
- movq %rax,PCB_DR2(%rsi)
+ movq %rax,PCB_DR2(%rdi)
movq %dr3,%rax
- movq %rax,PCB_DR3(%rsi)
+ movq %rax,PCB_DR3(%rdi)
movq %dr6,%rax
- movq %rax,PCB_DR6(%rsi)
+ movq %rax,PCB_DR6(%rdi)
movq %dr7,%rax
- movq %rax,PCB_DR7(%rsi)
+ movq %rax,PCB_DR7(%rdi)
movl $MSR_FSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
- movq %rax,PCB_FSBASE(%rsi)
+ movq %rax,PCB_FSBASE(%rdi)
movl $MSR_GSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
- movq %rax,PCB_GSBASE(%rsi)
+ movq %rax,PCB_GSBASE(%rdi)
movl $MSR_KGSBASE,%ecx
rdmsr
shlq $32,%rdx
leaq (%rax,%rdx),%rax
- movq %rax,PCB_KGSBASE(%rsi)
-
- sgdt PCB_GDT(%rsi)
- sidt PCB_IDT(%rsi)
- sldt PCB_LDT(%rsi)
- str PCB_TR(%rsi)
-
- movq %cr0,%rax
- movq %rax,PCB_CR0(%rsi)
- leaq PCB_USERFPU(%rsi),%rdi
- pushfq
- cli
+ movq %rax,PCB_KGSBASE(%rdi)
+
+ sgdt PCB_GDT(%rdi)
+ sidt PCB_IDT(%rdi)
+ sldt PCB_LDT(%rdi)
+ str PCB_TR(%rdi)
+
clts
- fxsave (%rdi)
- movq %rax,%cr0
+ fxsave PCB_USERFPU(%rdi)
+ movq %rsi,%cr0 /* The previous %cr0 is saved in %rsi. */
- /*
- * If fpcurthread == NULL, then the fpu h/w state is irrelevant and the
- * state had better already be in the pcb. This is true for forks
- * but not for dumps (the old book-keeping with FP flags in the pcb
- * always lost for dumps because the dump pcb has 0 flags).
- *
- * If fpcurthread != NULL, then we have to copy the fpu h/w state to
- * fpcurthread's pcb, or reload from the requested pcb. Copying is
- * easier because we would have to handle h/w bugs for reloading.
- */
- movq PCPU(FPCURTHREAD),%rax
- testq %rax,%rax
- je 1f
-
- /* arg 1 (%rdi) already loaded */
- movq TD_PCB(%rax),%rax
- movq PCB_SAVEFPU(%rax),%rsi /* arg 2 */
- movq $PCB_SAVEFPU_SIZE,%rdx /* arg 3 */
- call bcopy
-1:
- popfq
movl $1,%eax
-
ret
END(savectx)
OpenPOWER on IntegriCloud