diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-06 12:57:57 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2019-05-06 12:57:57 +0000 |
commit | 8cd7b31e76b5c70f34bf98af365b95bd4a7cd88b (patch) | |
tree | 9c4876a0a1903741e1540a5c481a452373a84518 /sys/arch | |
parent | d117054c8a6eed492576a3cb544bcba6a4333083 (diff) |
Enforce store/load order when setting or clearing AST flag on mips64
Make sure that any preceding stores become visible to other CPUs before
setting the AST flag in need_resched() and signotify(). This should
prevent a very unlikely case with inter-CPU ASTs where the receiving
CPU uses stale state.
When clearing the AST flag in ast(), ensure that the clearing store
is performed before any other memory accesses in the AST handler.
Otherwise, there is a slight risk of losing an AST request that gets
posted while the handler is running.
OK guenther@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/mips64/mips64/cpu.c | 8 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/sendsig.c | 8 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/trap.c | 9 |
3 files changed, 22 insertions, 3 deletions
diff --git a/sys/arch/mips64/mips64/cpu.c b/sys/arch/mips64/mips64/cpu.c index 336aaf85091..571a1b83838 100644 --- a/sys/arch/mips64/mips64/cpu.c +++ b/sys/arch/mips64/mips64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.72 2019/05/05 13:36:28 visa Exp $ */ +/* $OpenBSD: cpu.c,v 1.73 2019/05/06 12:57:56 visa Exp $ */ /* * Copyright (c) 1997-2004 Opsycon AB (www.opsycon.se) @@ -478,6 +478,12 @@ need_resched(struct cpu_info *ci) ci->ci_want_resched = 1; if (ci->ci_curproc != NULL) { + /* + * Ensure that preceding stores are visible to other CPUs + * before setting the AST flag. + */ + membar_producer(); + aston(ci->ci_curproc); cpu_unidle(ci); } diff --git a/sys/arch/mips64/mips64/sendsig.c b/sys/arch/mips64/mips64/sendsig.c index 1473df83211..3d9d2f3fd04 100644 --- a/sys/arch/mips64/mips64/sendsig.c +++ b/sys/arch/mips64/mips64/sendsig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sendsig.c,v 1.31 2019/05/05 13:28:14 visa Exp $ */ +/* $OpenBSD: sendsig.c,v 1.32 2019/05/06 12:57:56 visa Exp $ */ /* * Copyright (c) 1990 The Regents of the University of California. @@ -233,6 +233,12 @@ sys_sigreturn(struct proc *p, void *v, register_t *retval) void signotify(struct proc *p) { + /* + * Ensure that preceding stores are visible to other CPUs + * before setting the AST flag. + */ + membar_producer(); + aston(p); cpu_unidle(p->p_cpu); } diff --git a/sys/arch/mips64/mips64/trap.c b/sys/arch/mips64/mips64/trap.c index b9d29fb5784..8731c3e65a3 100644 --- a/sys/arch/mips64/mips64/trap.c +++ b/sys/arch/mips64/mips64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.133 2018/06/13 14:38:42 visa Exp $ */ +/* $OpenBSD: trap.c,v 1.134 2019/05/06 12:57:56 visa Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -151,6 +151,13 @@ ast(void) p->p_md.md_astpending = 0; + /* + * Make sure the AST flag gets cleared before handling the AST. + * Otherwise there is a risk of losing an AST that was sent + * by another CPU. + */ + membar_enter(); + atomic_inc_int(&uvmexp.softs); mi_ast(p, ci->ci_want_resched); userret(p); |