diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2021-08-02 19:07:30 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2021-08-02 19:07:30 +0000 |
commit | 0746fae866128aa255d86e4fdfd258125bb515f6 (patch) | |
tree | 241aba642e072bc986225be9f8e239fe9a014194 /sys | |
parent | e47013f9403fd52c329308bd57d271547f67e48a (diff) |
Add memory barrier (data FENCE) before making the SBI call to issue a
FENCE.I instruction on the remote harts. According to the RISC-V
ISA documentation this is necessary to make remote harts observe earlier
stores. Also issue the local FENCE.I first; this is what both FreeBSD and
Linux does. Seems to fix at least some of the issue we've seen running
GENERIC.MP on MP machines.
ok jca@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/riscv64/riscv64/pmap.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/sys/arch/riscv64/riscv64/pmap.c b/sys/arch/riscv64/riscv64/pmap.c index 0835a1a4036..e6fe8338ea9 100644 --- a/sys/arch/riscv64/riscv64/pmap.c +++ b/sys/arch/riscv64/riscv64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.18 2021/07/30 13:17:33 kettenis Exp $ */ +/* $OpenBSD: pmap.c,v 1.19 2021/08/02 19:07:29 kettenis Exp $ */ /* * Copyright (c) 2019-2020 Brian Bamsch <bbamsch@google.com> @@ -105,18 +105,29 @@ icache_flush(void) CPU_INFO_ITERATOR cii; struct cpu_info *ci; unsigned long hart_mask = 0; +#endif + + fence_i(); +#ifdef MULTIPROCESSOR CPU_INFO_FOREACH(cii, ci) { if (ci == curcpu()) continue; hart_mask |= (1UL << ci->ci_hartid); } - if (hart_mask != 0) + /* + * From the RISC-V ISA: + * + * To make a store to instruction memory visible to all RISC-V + * harts, the writing hart has to execute a data FENCE before + * requesting that all remote RISC-V harts execute a FENCE.I. + */ + if (hart_mask != 0) { + membar_sync(); sbi_remote_fence_i(&hart_mask); + } #endif - - fence_i(); } struct pmap kernel_pmap_; |