From owner-svn-src-all@FreeBSD.ORG Mon Jul 26 19:53:10 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4980F1065673; Mon, 26 Jul 2010 19:53:10 +0000 (UTC) (envelope-from jkim@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 37EC58FC22; Mon, 26 Jul 2010 19:53:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o6QJrA9B069194; Mon, 26 Jul 2010 19:53:10 GMT (envelope-from jkim@svn.freebsd.org) Received: (from jkim@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o6QJrAFd069188; Mon, 26 Jul 2010 19:53:10 GMT (envelope-from jkim@svn.freebsd.org) Message-Id: <201007261953.o6QJrAFd069188@svn.freebsd.org> From: Jung-uk Kim Date: Mon, 26 Jul 2010 19:53:10 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r210514 - in head/sys/amd64: acpica amd64 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 26 Jul 2010 19:53:10 -0000 Author: jkim Date: Mon Jul 26 19:53:09 2010 New Revision: 210514 URL: http://svn.freebsd.org/changeset/base/210514 Log: Re-implement FPU suspend/resume for amd64. This removes superfluous uses of critical_enter(9) and critical_exit(9) by fpugetregs() and fpusetregs(). Also, we do not touch PCB flags any more. MFC after: 1 month Modified: head/sys/amd64/acpica/acpi_switch.S head/sys/amd64/acpica/acpi_wakeup.c head/sys/amd64/amd64/cpu_switch.S head/sys/amd64/amd64/genassym.c head/sys/amd64/amd64/mp_machdep.c Modified: head/sys/amd64/acpica/acpi_switch.S ============================================================================== --- head/sys/amd64/acpica/acpi_switch.S Mon Jul 26 18:55:18 2010 (r210513) +++ head/sys/amd64/acpica/acpi_switch.S Mon Jul 26 19:53:09 2010 (r210514) @@ -102,9 +102,12 @@ ENTRY(acpi_restorecpu) movl WAKEUP_CTX(sfmask), %eax wrmsr - /* Restore CR0, CR2 and CR4. */ + /* Restore CR0 except for FPU mode. */ movq WAKEUP_XPCB(CR0), %rax + andq $~(CR0_EM | CR0_TS), %rax movq %rax, %cr0 + + /* Restore CR2 and CR4. */ movq WAKEUP_XPCB(CR2), %rax movq %rax, %cr2 movq WAKEUP_XPCB(CR4), %rax @@ -149,6 +152,17 @@ ENTRY(acpi_restorecpu) movq WAKEUP_PCB(DR7), %rax movq %rax, %dr7 + /* Restore FPU state. */ + movq PCPU(FPCURTHREAD), %rax + testq %rax, %rax + je 1f + fxrstor WAKEUP_PCB(USER_FPU) +1: + + /* Restore CR0 with FPU mode. */ + movq WAKEUP_XPCB(CR0), %rax + movq %rax, %cr0 + /* Restore return address. */ movq WAKEUP_PCB(RIP), %rax movq %rax, (%rsp) Modified: head/sys/amd64/acpica/acpi_wakeup.c ============================================================================== --- head/sys/amd64/acpica/acpi_wakeup.c Mon Jul 26 18:55:18 2010 (r210513) +++ head/sys/amd64/acpica/acpi_wakeup.c Mon Jul 26 19:53:09 2010 (r210514) @@ -216,7 +216,6 @@ acpi_wakeup_cpus(struct acpi_softc *sc, int acpi_sleep_machdep(struct acpi_softc *sc, int state) { - struct savefpu *stopfpu; #ifdef SMP cpumask_t wakeup_cpus; #endif @@ -246,10 +245,7 @@ acpi_sleep_machdep(struct acpi_softc *sc cr3 = rcr3(); load_cr3(KPML4phys); - stopfpu = &stopxpcbs[0]->xpcb_pcb.pcb_user_save; if (acpi_savecpu(stopxpcbs[0])) { - fpugetregs(curthread, stopfpu); - #ifdef SMP if (wakeup_cpus != 0 && suspend_cpus(wakeup_cpus) == 0) { device_printf(sc->acpi_dev, @@ -285,7 +281,6 @@ acpi_sleep_machdep(struct acpi_softc *sc for (;;) ia32_pause(); } else { - fpusetregs(curthread, stopfpu); #ifdef SMP if (wakeup_cpus != 0) acpi_wakeup_cpus(sc, wakeup_cpus); Modified: head/sys/amd64/amd64/cpu_switch.S ============================================================================== --- head/sys/amd64/amd64/cpu_switch.S Mon Jul 26 18:55:18 2010 (r210513) +++ head/sys/amd64/amd64/cpu_switch.S Mon Jul 26 19:53:09 2010 (r210514) @@ -417,6 +417,13 @@ ENTRY(savectx2) leaq (%rax,%rdx),%rax movq %rax,XPCB_KGSBASE(%r8) + movq PCPU(FPCURTHREAD),%rax + testq %rax,%rax + je 1f + clts + fxsave PCB_USER_FPU(%r8) +1: + movl $1, %eax ret END(savectx2) Modified: head/sys/amd64/amd64/genassym.c ============================================================================== --- head/sys/amd64/amd64/genassym.c Mon Jul 26 18:55:18 2010 (r210513) +++ head/sys/amd64/amd64/genassym.c Mon Jul 26 19:53:09 2010 (r210514) @@ -140,6 +140,7 @@ ASSYM(PCB_DR2, offsetof(struct pcb, pcb_ ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3)); ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6)); ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7)); +ASSYM(PCB_USER_FPU, offsetof(struct pcb, pcb_user_save)); ASSYM(PCB_TSSP, offsetof(struct pcb, pcb_tssp)); ASSYM(PCB_FULL_IRET, offsetof(struct pcb, pcb_full_iret)); ASSYM(PCB_DBREGS, PCB_DBREGS); Modified: head/sys/amd64/amd64/mp_machdep.c ============================================================================== --- head/sys/amd64/amd64/mp_machdep.c Mon Jul 26 18:55:18 2010 (r210513) +++ head/sys/amd64/amd64/mp_machdep.c Mon Jul 26 19:53:09 2010 (r210514) @@ -1329,20 +1329,17 @@ cpustop_handler(void) void cpususpend_handler(void) { - struct savefpu *stopfpu; register_t cr3, rf; int cpu = PCPU_GET(cpuid); int cpumask = PCPU_GET(cpumask); rf = intr_disable(); cr3 = rcr3(); - stopfpu = &stopxpcbs[cpu]->xpcb_pcb.pcb_user_save; + if (savectx2(stopxpcbs[cpu])) { - fpugetregs(curthread, stopfpu); wbinvd(); atomic_set_int(&stopped_cpus, cpumask); - } else - fpusetregs(curthread, stopfpu); + } /* Wait for resume */ while (!(started_cpus & cpumask))