Merge tag 'ecryptfs-5.6-rc3-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / arch / riscv / mm / tlbflush.c
1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/mm.h>
4 #include <linux/smp.h>
5 #include <linux/sched.h>
6 #include <asm/sbi.h>
7
8 void flush_tlb_all(void)
9 {
10         sbi_remote_sfence_vma(NULL, 0, -1);
11 }
12
13 /*
14  * This function must not be called with cmask being null.
15  * Kernel may panic if cmask is NULL.
16  */
17 static void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start,
18                                   unsigned long size)
19 {
20         struct cpumask hmask;
21         unsigned int cpuid;
22
23         if (cpumask_empty(cmask))
24                 return;
25
26         cpuid = get_cpu();
27
28         if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) {
29                 /* local cpu is the only cpu present in cpumask */
30                 if (size <= PAGE_SIZE)
31                         local_flush_tlb_page(start);
32                 else
33                         local_flush_tlb_all();
34         } else {
35                 riscv_cpuid_to_hartid_mask(cmask, &hmask);
36                 sbi_remote_sfence_vma(cpumask_bits(&hmask), start, size);
37         }
38
39         put_cpu();
40 }
41
42 void flush_tlb_mm(struct mm_struct *mm)
43 {
44         __sbi_tlb_flush_range(mm_cpumask(mm), 0, -1);
45 }
46
47 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
48 {
49         __sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), addr, PAGE_SIZE);
50 }
51
52 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
53                      unsigned long end)
54 {
55         __sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), start, end - start);
56 }