summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2021-08-02 19:07:30 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2021-08-02 19:07:30 +0000
commit0746fae866128aa255d86e4fdfd258125bb515f6 (patch)
tree241aba642e072bc986225be9f8e239fe9a014194 /sys
parente47013f9403fd52c329308bd57d271547f67e48a (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.c19
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_;