From d0cd85e7c5795d41c8940ea1153a85d381dbc01d Mon Sep 17 00:00:00 2001 From: kettenis Date: Wed, 21 Jul 2010 14:08:09 +0000 Subject: [PATCH] Make sure that the FPU IPIs shoot down the right FPU context and not the FPU context of some random process that happened to be switched onto the FPU after the decision was made to send the IPI. --- sys/arch/amd64/amd64/fpu.c | 5 +++-- sys/arch/amd64/amd64/ipifuncs.c | 8 +++++--- sys/arch/amd64/include/cpu.h | 3 ++- sys/arch/i386/i386/ipifuncs.c | 8 +++++--- sys/arch/i386/include/cpu.h | 3 ++- sys/arch/i386/isa/npx.c | 4 ++-- 6 files changed, 19 insertions(+), 12 deletions(-) diff --git a/sys/arch/amd64/amd64/fpu.c b/sys/arch/amd64/amd64/fpu.c index 51515478f97..fdc075365f1 100644 --- a/sys/arch/amd64/amd64/fpu.c +++ b/sys/arch/amd64/amd64/fpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fpu.c,v 1.16 2010/06/29 21:13:43 thib Exp $ */ +/* $OpenBSD: fpu.c,v 1.17 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: fpu.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /*- @@ -312,8 +312,9 @@ fpusave_proc(struct proc *p, int save) fpusave_cpu(ci, save); splx(s); } else { + oci->ci_fpsaveproc = p; x86_send_ipi(oci, - save ? X86_IPI_SYNCH_FPU : X86_IPI_FLUSH_FPU); + save ? X86_IPI_SYNCH_FPU : X86_IPI_FLUSH_FPU); while (p->p_addr->u_pcb.pcb_fpcpu != NULL) SPINLOCK_SPIN_HOOK; } diff --git a/sys/arch/amd64/amd64/ipifuncs.c b/sys/arch/amd64/amd64/ipifuncs.c index 73fed196631..5738f9df091 100644 --- a/sys/arch/amd64/amd64/ipifuncs.c +++ b/sys/arch/amd64/amd64/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.12 2010/06/26 15:56:40 mlarkin Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.13 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: ipifuncs.c,v 1.1 2003/04/26 18:39:28 fvdl Exp $ */ /*- @@ -110,13 +110,15 @@ x86_64_ipi_halt(struct cpu_info *ci) void x86_64_ipi_flush_fpu(struct cpu_info *ci) { - fpusave_cpu(ci, 0); + if (ci->ci_fpsaveproc == ci->ci_fpcurproc) + fpusave_cpu(ci, 0); } void x86_64_ipi_synch_fpu(struct cpu_info *ci) { - fpusave_cpu(ci, 1); + if (ci->ci_fpsaveproc == ci->ci_fpcurproc) + fpusave_cpu(ci, 1); } #if NMTRR > 0 diff --git a/sys/arch/amd64/include/cpu.h b/sys/arch/amd64/include/cpu.h index 71286c5b7d1..c9730702f2f 100644 --- a/sys/arch/amd64/include/cpu.h +++ b/sys/arch/amd64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.51 2009/12/09 14:27:34 oga Exp $ */ +/* $OpenBSD: cpu.h,v 1.52 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.1 2003/04/26 18:39:39 fvdl Exp $ */ /*- @@ -74,6 +74,7 @@ struct cpu_info { u_int64_t ci_scratch; struct proc *ci_fpcurproc; + struct proc *ci_fpsaveproc; int ci_fpsaving; struct pcb *ci_curpcb; diff --git a/sys/arch/i386/i386/ipifuncs.c b/sys/arch/i386/i386/ipifuncs.c index 3d2dcf64916..064b3ffa242 100644 --- a/sys/arch/i386/i386/ipifuncs.c +++ b/sys/arch/i386/i386/ipifuncs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ipifuncs.c,v 1.17 2010/06/26 15:56:40 mlarkin Exp $ */ +/* $OpenBSD: ipifuncs.c,v 1.18 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: ipifuncs.c,v 1.1.2.3 2000/06/26 02:04:06 sommerfeld Exp $ */ /*- @@ -114,13 +114,15 @@ i386_ipi_halt(struct cpu_info *ci) void i386_ipi_flush_fpu(struct cpu_info *ci) { - npxsave_cpu(ci, 0); + if (ci->ci_fpsaveproc == ci->ci_fpcurproc) + npxsave_cpu(ci, 0); } void i386_ipi_synch_fpu(struct cpu_info *ci) { - npxsave_cpu(ci, 1); + if (ci->ci_fpsaveproc == ci->ci_fpcurproc) + npxsave_cpu(ci, 1); } #endif diff --git a/sys/arch/i386/include/cpu.h b/sys/arch/i386/include/cpu.h index e3944a92479..d6c0e6ef89d 100644 --- a/sys/arch/i386/include/cpu.h +++ b/sys/arch/i386/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.110 2010/05/23 22:41:49 deraadt Exp $ */ +/* $OpenBSD: cpu.h,v 1.111 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: cpu.h,v 1.35 1996/05/05 19:29:26 christos Exp $ */ /*- @@ -92,6 +92,7 @@ struct cpu_info { * Private members. */ struct proc *ci_fpcurproc; /* current owner of the FPU */ + struct proc *ci_fpsaveproc; int ci_fpsaving; /* save in progress */ struct pcb *ci_curpcb; /* VA of current HW PCB */ diff --git a/sys/arch/i386/isa/npx.c b/sys/arch/i386/isa/npx.c index 232886c0788..5f8c73defaf 100644 --- a/sys/arch/i386/isa/npx.c +++ b/sys/arch/i386/isa/npx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: npx.c,v 1.48 2010/06/29 21:13:43 thib Exp $ */ +/* $OpenBSD: npx.c,v 1.49 2010/07/21 14:08:09 kettenis Exp $ */ /* $NetBSD: npx.c,v 1.57 1996/05/12 23:12:24 mycroft Exp $ */ #if 0 @@ -848,9 +848,9 @@ npxsave_proc(struct proc *p, int save) IPRINTF(("%s: fp ipi to %s %s %lx\n", ci->ci_dev.dv_xname, oci->ci_dev.dv_xname, save ? "save" : "flush", (u_long)p)); + oci->ci_fpsaveproc = p; i386_send_ipi(oci, save ? I386_IPI_SYNCH_FPU : I386_IPI_FLUSH_FPU); - while (p->p_addr->u_pcb.pcb_fpcpu != NULL) SPINLOCK_SPIN_HOOK; } -- 2.20.1