1
2
3
4
5
6
7#ifndef _ASM_RISCV_TLBFLUSH_H
8#define _ASM_RISCV_TLBFLUSH_H
9
10#include <linux/mm_types.h>
11#include <asm/smp.h>
12
13
14
15
16
17static inline void local_flush_tlb_all(void)
18{
19 __asm__ __volatile__ ("sfence.vma" : : : "memory");
20}
21
22
23static inline void local_flush_tlb_page(unsigned long addr)
24{
25 __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
26}
27
28#ifndef CONFIG_SMP
29
30#define flush_tlb_all() local_flush_tlb_all()
31#define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
32
33static inline void flush_tlb_range(struct vm_area_struct *vma,
34 unsigned long start, unsigned long end)
35{
36 local_flush_tlb_all();
37}
38
39#define flush_tlb_mm(mm) flush_tlb_all()
40
41#else
42
43#include <asm/sbi.h>
44
45static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start,
46 unsigned long size)
47{
48 struct cpumask hmask;
49
50 cpumask_clear(&hmask);
51 riscv_cpuid_to_hartid_mask(cmask, &hmask);
52 sbi_remote_sfence_vma(hmask.bits, start, size);
53}
54
55#define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1)
56#define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
57#define flush_tlb_range(vma, start, end) \
58 remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start))
59#define flush_tlb_mm(mm) \
60 remote_sfence_vma(mm_cpumask(mm), 0, -1)
61
62#endif
63
64
65static inline void flush_tlb_kernel_range(unsigned long start,
66 unsigned long end)
67{
68 flush_tlb_all();
69}
70
71#endif
72