Fix a race condition in IPI handlers of save/drop fpstate, from OpenBSD.
Reported and tested by martin@.
This commit is contained in:
parent
33928e0f83
commit
0a332c0d29
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore.s,v 1.271 2008/03/17 04:04:00 nakayama Exp $ */
|
||||
/* $NetBSD: locore.s,v 1.272 2008/03/17 23:54:03 nakayama Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2002 Eduardo Horvath
|
||||
|
@ -9512,18 +9512,23 @@ Lkcerr:
|
|||
/*
|
||||
* IPI handler to store the current FPU state.
|
||||
* void sparc64_ipi_save_fpstate(void *);
|
||||
*
|
||||
* On entry:
|
||||
* %g2 = lwp
|
||||
*/
|
||||
ENTRY(sparc64_ipi_save_fpstate)
|
||||
sethi %hi(FPLWP), %g1
|
||||
LDPTR [%g1 + %lo(FPLWP)], %g3
|
||||
cmp %g3, %g2
|
||||
bne,pn CCCR, 7f ! skip if fplwp != %g2
|
||||
LDPTR [%g3 + L_FPSTATE], %g3
|
||||
|
||||
mov CTX_SECONDARY, %g5
|
||||
ldxa [%g5] ASI_DMMU, %g6
|
||||
membar #LoadStore
|
||||
stxa %g0, [%g5] ASI_DMMU
|
||||
membar #Sync
|
||||
|
||||
sethi %hi(FPLWP), %g1
|
||||
LDPTR [%g1 + %lo(FPLWP)], %g3
|
||||
LDPTR [%g3 + L_FPSTATE], %g3
|
||||
|
||||
rdpr %pstate, %g2 ! enable FP before we begin
|
||||
rd %fprs, %g5
|
||||
wr %g0, FPRS_FEF, %fprs
|
||||
|
@ -9564,6 +9569,7 @@ ENTRY(sparc64_ipi_save_fpstate)
|
|||
STPTR %g0, [%g1 + %lo(FPLWP)] ! fplwp = NULL
|
||||
stxa %g6, [%g5] ASI_DMMU
|
||||
membar #Sync
|
||||
7:
|
||||
IPIEVC_INC(IPI_EVCNT_FPU_SYNCH,%g2,%g3)
|
||||
ba,a ret_from_intr_vector
|
||||
nop
|
||||
|
@ -9631,16 +9637,20 @@ ENTRY(sparc64_ipi_save_fpstate)
|
|||
/*
|
||||
* IPI handler to drop the current FPU state.
|
||||
* void sparc64_ipi_drop_fpstate(void *);
|
||||
*
|
||||
* On entry:
|
||||
* %g2 = lwp
|
||||
*/
|
||||
ENTRY(sparc64_ipi_drop_fpstate)
|
||||
rdpr %pstate, %g1
|
||||
wr %g0, FPRS_FEF, %fprs
|
||||
or %g1, PSTATE_PEF, %g1
|
||||
wrpr %g1, 0, %pstate
|
||||
sethi %hi(FPLWP), %g1
|
||||
set FPLWP, %g1
|
||||
CASPTR [%g1] ASI_N, %g2, %g0 ! fplwp = NULL if fplwp == %g2
|
||||
IPIEVC_INC(IPI_EVCNT_FPU_FLUSH,%g2,%g3)
|
||||
ba ret_from_intr_vector
|
||||
STPTR %g0, [%g1 + %lo(FPLWP)] ! fplwp = NULL
|
||||
ba,a ret_from_intr_vector
|
||||
nop
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vm_machdep.c,v 1.79 2008/03/14 15:39:18 nakayama Exp $ */
|
||||
/* $NetBSD: vm_machdep.c,v 1.80 2008/03/17 23:54:03 nakayama Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996-2002 Eduardo Horvath. All rights reserved.
|
||||
|
@ -50,7 +50,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.79 2008/03/14 15:39:18 nakayama Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.80 2008/03/17 23:54:03 nakayama Exp $");
|
||||
|
||||
#include "opt_multiprocessor.h"
|
||||
#include "opt_coredump.h"
|
||||
|
@ -334,7 +334,7 @@ fpusave_lwp(struct lwp *l, bool save)
|
|||
continue;
|
||||
sparc64_send_ipi(ci->ci_cpuid, save ?
|
||||
sparc64_ipi_save_fpstate :
|
||||
sparc64_ipi_drop_fpstate, 0, 0);
|
||||
sparc64_ipi_drop_fpstate, (uintptr_t)l, 0);
|
||||
|
||||
spincount = 0;
|
||||
while (ci->ci_fplwp == l) {
|
||||
|
|
Loading…
Reference in New Issue