tlbflush.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /*
  2. * Copyright (C) 2009 Chen Liqin <liqin.chen@sunplusct.com>
  3. * Copyright (C) 2012 Regents of the University of California
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License
  7. * as published by the Free Software Foundation, version 2.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #ifndef _ASM_RISCV_TLBFLUSH_H
  15. #define _ASM_RISCV_TLBFLUSH_H
  16. #include <linux/mm_types.h>
  17. #include <asm/smp.h>
  18. /*
  19. * Flush entire local TLB. 'sfence.vma' implicitly fences with the instruction
  20. * cache as well, so a 'fence.i' is not necessary.
  21. */
  22. static inline void local_flush_tlb_all(void)
  23. {
  24. __asm__ __volatile__ ("sfence.vma" : : : "memory");
  25. }
  26. /* Flush one page from local TLB */
  27. static inline void local_flush_tlb_page(unsigned long addr)
  28. {
  29. __asm__ __volatile__ ("sfence.vma %0" : : "r" (addr) : "memory");
  30. }
  31. #ifndef CONFIG_SMP
  32. #define flush_tlb_all() local_flush_tlb_all()
  33. #define flush_tlb_page(vma, addr) local_flush_tlb_page(addr)
  34. static inline void flush_tlb_range(struct vm_area_struct *vma,
  35. unsigned long start, unsigned long end)
  36. {
  37. local_flush_tlb_all();
  38. }
  39. #define flush_tlb_mm(mm) flush_tlb_all()
  40. #else /* CONFIG_SMP */
  41. #include <asm/sbi.h>
  42. static inline void remote_sfence_vma(struct cpumask *cmask, unsigned long start,
  43. unsigned long size)
  44. {
  45. struct cpumask hmask;
  46. cpumask_clear(&hmask);
  47. riscv_cpuid_to_hartid_mask(cmask, &hmask);
  48. sbi_remote_sfence_vma(hmask.bits, start, size);
  49. }
  50. #define flush_tlb_all() sbi_remote_sfence_vma(NULL, 0, -1)
  51. #define flush_tlb_page(vma, addr) flush_tlb_range(vma, addr, 0)
  52. #define flush_tlb_range(vma, start, end) \
  53. remote_sfence_vma(mm_cpumask((vma)->vm_mm), start, (end) - (start))
  54. #define flush_tlb_mm(mm) \
  55. remote_sfence_vma(mm_cpumask(mm), 0, -1)
  56. #endif /* CONFIG_SMP */
  57. /* Flush a range of kernel pages */
  58. static inline void flush_tlb_kernel_range(unsigned long start,
  59. unsigned long end)
  60. {
  61. flush_tlb_all();
  62. }
  63. #endif /* _ASM_RISCV_TLBFLUSH_H */