summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2014-02-06 05:14:13 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2014-02-06 05:14:13 +0000
commit348b6bf477bd296c7bff6fb4e3cd4192354ed8a4 (patch)
treeca00dc523271128d731e872a1dccb10442f385bd /sys/arch
parent7aecf01e8f773728603eacad2d199dc695e3953f (diff)
Fix an MP race in the fpu context saving code; from NetBSD.
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/alpha/alpha/fp_complete.c4
-rw-r--r--sys/arch/alpha/alpha/trap.c11
2 files changed, 9 insertions, 6 deletions
diff --git a/sys/arch/alpha/alpha/fp_complete.c b/sys/arch/alpha/alpha/fp_complete.c
index ee94b2da568..20618bac338 100644
--- a/sys/arch/alpha/alpha/fp_complete.c
+++ b/sys/arch/alpha/alpha/fp_complete.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fp_complete.c,v 1.8 2008/10/07 22:06:29 martynas Exp $ */
+/* $OpenBSD: fp_complete.c,v 1.9 2014/02/06 05:14:12 miod Exp $ */
/* $NetBSD: fp_complete.c,v 1.5 2002/01/18 22:15:56 ross Exp $ */
/*-
@@ -398,6 +398,7 @@ alpha_write_fp_c(struct proc *p, u_int64_t fp_c)
return;
p->p_md.md_flags = (md_flags & ~MDP_FP_C) | fp_c;
alpha_enable_fp(p, 1);
+ alpha_pal_wrfen(1);
fp_c_to_fpcr(p);
alpha_pal_wrfen(0);
}
@@ -574,6 +575,7 @@ alpha_fp_complete_at(alpha_instruction *trigger_pc, struct proc *p,
return SIGSEGV;
}
alpha_enable_fp(p, 1);
+ alpha_pal_wrfen(1);
/*
* If necessary, lie about the dynamic rounding mode so emulation
* software need go to only one place for it, and so we don't have to
diff --git a/sys/arch/alpha/alpha/trap.c b/sys/arch/alpha/alpha/trap.c
index f44f28fb875..4c945408157 100644
--- a/sys/arch/alpha/alpha/trap.c
+++ b/sys/arch/alpha/alpha/trap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: trap.c,v 1.68 2014/02/04 21:52:43 miod Exp $ */
+/* $OpenBSD: trap.c,v 1.69 2014/02/06 05:14:12 miod Exp $ */
/* $NetBSD: trap.c,v 1.52 2000/05/24 16:48:33 thorpej Exp $ */
/*-
@@ -355,7 +355,6 @@ trap(a0, a1, a2, entry, framep)
case ALPHA_IF_CODE_FEN:
alpha_enable_fp(p, 0);
- alpha_pal_wrfen(0);
goto out;
default:
@@ -689,14 +688,16 @@ alpha_enable_fp(struct proc *p, int check)
#endif
p->p_addr->u_pcb.pcb_fpcpu = ci;
ci->ci_fpcurproc = p;
-#if defined(MULTIPROCESSOR)
- alpha_pal_swpipl(s);
-#endif
atomic_add_int(&uvmexp.fpswtch, 1);
p->p_md.md_flags |= MDP_FPUSED;
alpha_pal_wrfen(1);
restorefpstate(&p->p_addr->u_pcb.pcb_fp);
+ alpha_pal_wrfen(0);
+
+#if defined(MULTIPROCESSOR)
+ alpha_pal_swpipl(s);
+#endif
}
/*