tlbflush.c 1.2 KB

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