Skip to content

Commit ca35869

Browse files
AndybnACTpalmer-dabbelt
authored andcommitted
riscv: add a data fence for CMODX in the kernel mode
RISC-V spec explicitly calls out that a local fence.i is not enough for the code modification to be visble from a remote hart. In fact, it states: To make a store to instruction memory visible to all RISC-V harts, the writing hart also has to execute a data FENCE before requesting that all remote RISC-V harts execute a FENCE.I. Although current riscv drivers for IPI use ordered MMIO when sending IPIs in order to synchronize the action between previous csd writes, riscv does not restrict itself to any particular flavor of IPI. Any driver or firmware implementation that does not order data writes before the IPI may pose a risk for code-modifying race. Thus, add a fence here to order data writes before making the IPI. Signed-off-by: Andy Chiu <[email protected]> Reviewed-by: Björn Töpel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexandre Ghiti <[email protected]> Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent d1049fc commit ca35869

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

arch/riscv/mm/cacheflush.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,20 @@ void flush_icache_all(void)
2424

2525
if (num_online_cpus() < 2)
2626
return;
27-
else if (riscv_use_sbi_for_rfence())
27+
28+
/*
29+
* Make sure all previous writes to the D$ are ordered before making
30+
* the IPI. The RISC-V spec states that a hart must execute a data fence
31+
* before triggering a remote fence.i in order to make the modification
32+
* visable for remote harts.
33+
*
34+
* IPIs on RISC-V are triggered by MMIO writes to either CLINT or
35+
* S-IMSIC, so the fence ensures previous data writes "happen before"
36+
* the MMIO.
37+
*/
38+
RISCV_FENCE(w, o);
39+
40+
if (riscv_use_sbi_for_rfence())
2841
sbi_remote_fence_i(NULL);
2942
else
3043
on_each_cpu(ipi_remote_fence_i, NULL, 1);

0 commit comments

Comments
 (0)