blob: 720b443c4528f7b2a0d141b8d480c6c2785bff82 [file] [log] [blame]
David Brazdil0f672f62019-12-10 10:32:29 +00001// SPDX-License-Identifier: GPL-2.0
2
3#include <linux/mm.h>
4#include <linux/smp.h>
Olivier Deprez157378f2022-04-04 15:47:50 +02005#include <linux/sched.h>
David Brazdil0f672f62019-12-10 10:32:29 +00006#include <asm/sbi.h>
7
8void flush_tlb_all(void)
9{
10 sbi_remote_sfence_vma(NULL, 0, -1);
11}
12
Olivier Deprez157378f2022-04-04 15:47:50 +020013/*
14 * This function must not be called with cmask being null.
15 * Kernel may panic if cmask is NULL.
16 */
David Brazdil0f672f62019-12-10 10:32:29 +000017static void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start,
18 unsigned long size)
19{
20 struct cpumask hmask;
Olivier Deprez157378f2022-04-04 15:47:50 +020021 unsigned int cpuid;
David Brazdil0f672f62019-12-10 10:32:29 +000022
Olivier Deprez157378f2022-04-04 15:47:50 +020023 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();
David Brazdil0f672f62019-12-10 10:32:29 +000040}
41
42void flush_tlb_mm(struct mm_struct *mm)
43{
44 __sbi_tlb_flush_range(mm_cpumask(mm), 0, -1);
45}
46
47void 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
52void 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}