diff options
author | Andrew Waterman <andrew@sifive.com> | 2017-10-25 23:30:32 +0200 |
---|---|---|
committer | Palmer Dabbelt <palmer@sifive.com> | 2017-11-30 21:58:25 +0100 |
commit | 08f051eda33b51e8ee0f45f05bcfe49d0f0caf6b (patch) | |
tree | 46a1e3577de686377e859c7f346299e9ea726260 /arch/riscv/include/asm/tlbflush.h | |
parent | RISC-V: Add VDSO entries for clock_get/gettimeofday/getcpu (diff) | |
download | linux-08f051eda33b51e8ee0f45f05bcfe49d0f0caf6b.tar.xz linux-08f051eda33b51e8ee0f45f05bcfe49d0f0caf6b.zip |
RISC-V: Flush I$ when making a dirty page executable
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@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'arch/riscv/include/asm/tlbflush.h')
-rw-r--r-- | arch/riscv/include/asm/tlbflush.h | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h index 5ee4ae370b5e..77edf2826c1f 100644 --- a/arch/riscv/include/asm/tlbflush.h +++ b/arch/riscv/include/asm/tlbflush.h @@ -17,6 +17,8 @@ #ifdef CONFIG_MMU +#include <linux/mm_types.h> + /* Flush entire local TLB */ static inline void local_flush_tlb_all(void) { |