pgtable-generic.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * mm/pgtable-generic.c
  3. *
  4. * Generic pgtable methods declared in asm-generic/pgtable.h
  5. *
  6. * Copyright (C) 2010 Linus Torvalds
  7. */
  8. #include <asm/tlb.h>
  9. #include <asm-generic/pgtable.h>
  10. #ifndef __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
  11. /*
  12. * Only sets the access flags (dirty, accessed, and
  13. * writable). Furthermore, we know it always gets set to a "more
  14. * permissive" setting, which allows most architectures to optimize
  15. * this. We return whether the PTE actually changed, which in turn
  16. * instructs the caller to do things like update__mmu_cache. This
  17. * used to be done in the caller, but sparc needs minor faults to
  18. * force that call on sun4c so we changed this macro slightly
  19. */
  20. int ptep_set_access_flags(struct vm_area_struct *vma,
  21. unsigned long address, pte_t *ptep,
  22. pte_t entry, int dirty)
  23. {
  24. int changed = !pte_same(*ptep, entry);
  25. if (changed) {
  26. set_pte_at(vma->vm_mm, address, ptep, entry);
  27. flush_tlb_page(vma, address);
  28. }
  29. return changed;
  30. }
  31. #endif
  32. #ifndef __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
  33. int pmdp_set_access_flags(struct vm_area_struct *vma,
  34. unsigned long address, pmd_t *pmdp,
  35. pmd_t entry, int dirty)
  36. {
  37. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  38. int changed = !pmd_same(*pmdp, entry);
  39. VM_BUG_ON(address & ~HPAGE_PMD_MASK);
  40. if (changed) {
  41. set_pmd_at(vma->vm_mm, address, pmdp, entry);
  42. flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
  43. }
  44. return changed;
  45. #else /* CONFIG_TRANSPARENT_HUGEPAGE */
  46. BUG();
  47. return 0;
  48. #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  49. }
  50. #endif
  51. #ifndef __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
  52. int ptep_clear_flush_young(struct vm_area_struct *vma,
  53. unsigned long address, pte_t *ptep)
  54. {
  55. int young;
  56. young = ptep_test_and_clear_young(vma, address, ptep);
  57. if (young)
  58. flush_tlb_page(vma, address);
  59. return young;
  60. }
  61. #endif
  62. #ifndef __HAVE_ARCH_PMDP_CLEAR_YOUNG_FLUSH
  63. int pmdp_clear_flush_young(struct vm_area_struct *vma,
  64. unsigned long address, pmd_t *pmdp)
  65. {
  66. int young;
  67. #ifndef CONFIG_TRANSPARENT_HUGEPAGE
  68. BUG();
  69. #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  70. VM_BUG_ON(address & ~HPAGE_PMD_MASK);
  71. young = pmdp_test_and_clear_young(vma, address, pmdp);
  72. if (young)
  73. flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
  74. return young;
  75. }
  76. #endif
  77. #ifndef __HAVE_ARCH_PTEP_CLEAR_FLUSH
  78. pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long address,
  79. pte_t *ptep)
  80. {
  81. pte_t pte;
  82. pte = ptep_get_and_clear((vma)->vm_mm, address, ptep);
  83. flush_tlb_page(vma, address);
  84. return pte;
  85. }
  86. #endif
  87. #ifndef __HAVE_ARCH_PMDP_CLEAR_FLUSH
  88. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  89. pmd_t pmdp_clear_flush(struct vm_area_struct *vma, unsigned long address,
  90. pmd_t *pmdp)
  91. {
  92. pmd_t pmd;
  93. VM_BUG_ON(address & ~HPAGE_PMD_MASK);
  94. pmd = pmdp_get_and_clear(vma->vm_mm, address, pmdp);
  95. flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
  96. return pmd;
  97. }
  98. #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  99. #endif
  100. #ifndef __HAVE_ARCH_PMDP_SPLITTING_FLUSH
  101. #ifdef CONFIG_TRANSPARENT_HUGEPAGE
  102. pmd_t pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
  103. pmd_t *pmdp)
  104. {
  105. pmd_t pmd = pmd_mksplitting(*pmdp);
  106. VM_BUG_ON(address & ~HPAGE_PMD_MASK);
  107. set_pmd_at(vma->vm_mm, address, pmdp, pmd);
  108. /* tlb flush only to serialize against gup-fast */
  109. flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
  110. }
  111. #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
  112. #endif