From 8cd7b31e76b5c70f34bf98af365b95bd4a7cd88b Mon Sep 17 00:00:00 2001 From: Visa Hankala Date: Mon, 6 May 2019 12:57:57 +0000 Subject: 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@ --- sys/arch/mips64/mips64/cpu.c | 8 +++++++- sys/arch/mips64/mips64/sendsig.c | 8 +++++++- sys/arch/mips64/mips64/trap.c | 9 ++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) (limited to 'sys/arch') 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); -- cgit v1.2.3