svn commit: r210804 - in head/sys/amd64: acpica amd64

Jung-uk Kim jkim at FreeBSD.org
Tue Aug 3 15:32:09 UTC 2010


Author: jkim
Date: Tue Aug  3 15:32:08 2010
New Revision: 210804
URL: http://svn.freebsd.org/changeset/base/210804

Log:
  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]

Modified:
  head/sys/amd64/acpica/acpi_switch.S
  head/sys/amd64/acpica/acpi_wakecode.S
  head/sys/amd64/amd64/cpu_switch.S

Modified: head/sys/amd64/acpica/acpi_switch.S
==============================================================================
--- head/sys/amd64/acpica/acpi_switch.S	Tue Aug  3 15:07:38 2010	(r210803)
+++ head/sys/amd64/acpica/acpi_switch.S	Tue Aug  3 15:32:08 2010	(r210804)
@@ -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. */

Modified: head/sys/amd64/acpica/acpi_wakecode.S
==============================================================================
--- head/sys/amd64/acpica/acpi_wakecode.S	Tue Aug  3 15:07:38 2010	(r210803)
+++ head/sys/amd64/acpica/acpi_wakecode.S	Tue Aug  3 15:32:08 2010	(r210804)
@@ -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
 

Modified: head/sys/amd64/amd64/cpu_switch.S
==============================================================================
--- head/sys/amd64/amd64/cpu_switch.S	Tue Aug  3 15:07:38 2010	(r210803)
+++ head/sys/amd64/amd64/cpu_switch.S	Tue Aug  3 15:32:08 2010	(r210804)
@@ -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	%rax,PCB_RIP(%rdi)
 
-	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	%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)
+	movq	%rax,PCB_KGSBASE(%rdi)
+
+	sgdt	PCB_GDT(%rdi)
+	sidt	PCB_IDT(%rdi)
+	sldt	PCB_LDT(%rdi)
+	str	PCB_TR(%rdi)
 
-	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
 	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)


More information about the svn-src-all mailing list