summaryrefslogtreecommitdiffstats
path: root/arch/riscv/include/asm/tlbflush.h
diff options
context:
space:
mode:
authorSamuel Holland <samuel.holland@sifive.com>2024-03-27 05:49:48 +0100
committerPalmer Dabbelt <palmer@rivosinc.com>2024-04-29 19:49:30 +0200
commit20e03d702e00a3e0269a1d6f9549c2e370492054 (patch)
tree904848ff0e09b77ca7adb7cba0ab63d3683a79e4 /arch/riscv/include/asm/tlbflush.h
parentriscv: mm: Combine the SMP and UP TLB flush code (diff)
downloadlinux-20e03d702e00a3e0269a1d6f9549c2e370492054.tar.xz
linux-20e03d702e00a3e0269a1d6f9549c2e370492054.zip
riscv: Apply SiFive CIP-1200 workaround to single-ASID sfence.vma
commit 3f1e782998cd ("riscv: add ASID-based tlbflushing methods") added calls to the sfence.vma instruction with rs2 != x0. These single-ASID instruction variants are also affected by SiFive errata CIP-1200. Until now, the errata workaround was not needed for the single-ASID sfence.vma variants, because they were only used when the ASID allocator was enabled, and the affected SiFive platforms do not support multiple ASIDs. However, we are going to start using those sfence.vma variants regardless of ASID support, so now we need alternatives covering them. Signed-off-by: Samuel Holland <samuel.holland@sifive.com> Link: https://lore.kernel.org/r/20240327045035.368512-8-samuel.holland@sifive.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch/riscv/include/asm/tlbflush.h')
-rw-r--r--arch/riscv/include/asm/tlbflush.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index 4f86424b1ba5..463b615d7728 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -22,10 +22,27 @@ static inline void local_flush_tlb_all(void)
__asm__ __volatile__ ("sfence.vma" : : : "memory");
}
+static inline void local_flush_tlb_all_asid(unsigned long asid)
+{
+ if (asid != FLUSH_TLB_NO_ASID)
+ ALT_SFENCE_VMA_ASID(asid);
+ else
+ local_flush_tlb_all();
+}
+
/* Flush one page from local TLB */
static inline void local_flush_tlb_page(unsigned long addr)
{
- ALT_FLUSH_TLB_PAGE(__asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory"));
+ ALT_SFENCE_VMA_ADDR(addr);
+}
+
+static inline void local_flush_tlb_page_asid(unsigned long addr,
+ unsigned long asid)
+{
+ if (asid != FLUSH_TLB_NO_ASID)
+ ALT_SFENCE_VMA_ADDR_ASID(addr, asid);
+ else
+ local_flush_tlb_page(addr);
}
void flush_tlb_all(void);