xref: /kernel/linux/linux-5.10/arch/riscv/mm/tlbflush.c (revision 8c2ecf20)
18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/mm.h>
48c2ecf20Sopenharmony_ci#include <linux/smp.h>
58c2ecf20Sopenharmony_ci#include <linux/sched.h>
68c2ecf20Sopenharmony_ci#include <asm/sbi.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_civoid flush_tlb_all(void)
98c2ecf20Sopenharmony_ci{
108c2ecf20Sopenharmony_ci	sbi_remote_sfence_vma(NULL, 0, -1);
118c2ecf20Sopenharmony_ci}
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci/*
148c2ecf20Sopenharmony_ci * This function must not be called with cmask being null.
158c2ecf20Sopenharmony_ci * Kernel may panic if cmask is NULL.
168c2ecf20Sopenharmony_ci */
178c2ecf20Sopenharmony_cistatic void __sbi_tlb_flush_range(struct cpumask *cmask, unsigned long start,
188c2ecf20Sopenharmony_ci				  unsigned long size)
198c2ecf20Sopenharmony_ci{
208c2ecf20Sopenharmony_ci	struct cpumask hmask;
218c2ecf20Sopenharmony_ci	unsigned int cpuid;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	if (cpumask_empty(cmask))
248c2ecf20Sopenharmony_ci		return;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	cpuid = get_cpu();
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_ci	if (cpumask_any_but(cmask, cpuid) >= nr_cpu_ids) {
298c2ecf20Sopenharmony_ci		/* local cpu is the only cpu present in cpumask */
308c2ecf20Sopenharmony_ci		if (size <= PAGE_SIZE)
318c2ecf20Sopenharmony_ci			local_flush_tlb_page(start);
328c2ecf20Sopenharmony_ci		else
338c2ecf20Sopenharmony_ci			local_flush_tlb_all();
348c2ecf20Sopenharmony_ci	} else {
358c2ecf20Sopenharmony_ci		riscv_cpuid_to_hartid_mask(cmask, &hmask);
368c2ecf20Sopenharmony_ci		sbi_remote_sfence_vma(cpumask_bits(&hmask), start, size);
378c2ecf20Sopenharmony_ci	}
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	put_cpu();
408c2ecf20Sopenharmony_ci}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_civoid flush_tlb_mm(struct mm_struct *mm)
438c2ecf20Sopenharmony_ci{
448c2ecf20Sopenharmony_ci	__sbi_tlb_flush_range(mm_cpumask(mm), 0, -1);
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_civoid flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
488c2ecf20Sopenharmony_ci{
498c2ecf20Sopenharmony_ci	__sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), addr, PAGE_SIZE);
508c2ecf20Sopenharmony_ci}
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_civoid flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
538c2ecf20Sopenharmony_ci		     unsigned long end)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	__sbi_tlb_flush_range(mm_cpumask(vma->vm_mm), start, end - start);
568c2ecf20Sopenharmony_ci}
57