summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64
diff options
context:
space:
mode:
authorjkim <jkim@FreeBSD.org>2010-07-26 19:53:09 +0000
committerjkim <jkim@FreeBSD.org>2010-07-26 19:53:09 +0000
commit48a6a38cdceac157ad249834defe382c21e39f7d (patch)
tree9183d2c80109a896ebadce43f6a4516a52e9f275 /sys/amd64/amd64
parent488a727a00e4e0a41095d9f56222741550a97d92 (diff)
downloadFreeBSD-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.S7
-rw-r--r--sys/amd64/amd64/genassym.c1
-rw-r--r--sys/amd64/amd64/mp_machdep.c7
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))
OpenPOWER on IntegriCloud