Re: [patches] [PATCH 3/4] RISC-V: Flush I$ when making a dirty page executable

From: Palmer Dabbelt
Date: Thu Nov 30 2017 - 17:50:25 EST


On Thu, 30 Nov 2017 12:32:04 PST (-0800), Olof Johansson wrote:
Hi,

On Mon, Nov 20, 2017 at 10:57 AM, Palmer Dabbelt <palmer@xxxxxxxxxx> wrote:
From: Andrew Waterman <andrew@xxxxxxxxxx>

The RISC-V ISA allows for instruction caches that are not coherent WRT
stores, even on a single hart. As a result, we need to explicitly flush
the instruction cache whenever marking a dirty page as executable in
order to preserve the correct system behavior.

Local instruction caches aren't that scary (our implementations actually
flush the cache, but RISC-V is defined to allow higher-performance
implementations to exist), but RISC-V defines no way to perform an
instruction cache shootdown. When explicitly asked to do so we can
shoot down remote instruction caches via an IPI, but this is a bit on
the slow side.

Instead of requiring an IPI to all harts whenever marking a page as
executable, we simply flush the currently running harts. In order to
maintain correct behavior, we additionally mark every other hart as
needing a deferred instruction cache which will be taken before anything
runs on it.

Signed-off-by: Andrew Waterman <andrew@xxxxxxxxxx>
Signed-off-by: Palmer Dabbelt <palmer@xxxxxxxxxx>
---
arch/riscv/include/asm/cacheflush.h | 24 ++++++++++++---
arch/riscv/include/asm/mmu.h | 4 +++
arch/riscv/include/asm/mmu_context.h | 44 +++++++++++++++++++++++++++
arch/riscv/include/asm/pgtable.h | 58 ++++++++++++++++++++----------------
arch/riscv/include/asm/tlbflush.h | 2 ++
arch/riscv/kernel/smp.c | 48 +++++++++++++++++++++++++++++
arch/riscv/mm/Makefile | 2 ++
arch/riscv/mm/cacheflush.c | 23 ++++++++++++++
8 files changed, 175 insertions(+), 30 deletions(-)
create mode 100644 arch/riscv/mm/cacheflush.c

[...]

diff --git a/arch/riscv/mm/Makefile b/arch/riscv/mm/Makefile
index 81f7d9ce6d88..786b5fdec0fd 100644
--- a/arch/riscv/mm/Makefile
+++ b/arch/riscv/mm/Makefile
@@ -2,3 +2,5 @@ obj-y += init.o
obj-y += fault.o
obj-y += extable.o
obj-y += ioremap.o
+obj-y += dma.o
+obj-y += cacheflush.o

Looks like dma.c didn't make it into this patch (and didn't already
exist), so builds fail with:

make[3]: *** No rule to make target 'arch/riscv/mm/dma.o', needed by
'arch/riscv/mm/built-in.o'.

Ah, thanks for catching that. I'll fix up the patch.