diff options
author | jkim <jkim@FreeBSD.org> | 2010-07-26 19:53:09 +0000 |
---|---|---|
committer | jkim <jkim@FreeBSD.org> | 2010-07-26 19:53:09 +0000 |
commit | 48a6a38cdceac157ad249834defe382c21e39f7d (patch) | |
tree | 9183d2c80109a896ebadce43f6a4516a52e9f275 /sys/amd64/amd64 | |
parent | 488a727a00e4e0a41095d9f56222741550a97d92 (diff) | |
download | FreeBSD-src-48a6a38cdceac157ad249834defe382c21e39f7d.zip FreeBSD-src-48a6a38cdceac157ad249834defe382c21e39f7d.tar.gz |
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
Diffstat (limited to 'sys/amd64/amd64')
-rw-r--r-- | sys/amd64/amd64/cpu_switch.S | 7 | ||||
-rw-r--r-- | sys/amd64/amd64/genassym.c | 1 | ||||
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 7 |
3 files changed, 10 insertions, 5 deletions
diff --git a/sys/amd64/amd64/cpu_switch.S b/sys/amd64/amd64/cpu_switch.S index 6b5c663..bba435d 100644 --- a/sys/amd64/amd64/cpu_switch.S +++ b/sys/amd64/amd64/cpu_switch.S @@ -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) diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c index 9d78309..95a0ef0 100644 --- a/sys/amd64/amd64/genassym.c +++ b/sys/amd64/amd64/genassym.c @@ -140,6 +140,7 @@ ASSYM(PCB_DR2, offsetof(struct pcb, pcb_dr2)); 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); diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 02e7505..0bda9fe 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -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)) |