gup.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. #include <linux/mm.h>
  2. #include <linux/uaccess.h>
  3. #include <linux/pagemap.h>
  4. #include <asm/pgtable.h>
  5. static inline pte_t gup_get_pte(pte_t *ptep)
  6. {
  7. return READ_ONCE(*ptep);
  8. }
  9. static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end,
  10. int write, struct page **pages, int *nr)
  11. {
  12. int ret = 0;
  13. pte_t *ptep, *ptem;
  14. ptem = ptep = pte_offset_map(&pmd, addr);
  15. do {
  16. pte_t pte = gup_get_pte(ptep);
  17. struct page *page;
  18. /*
  19. * Similar to the PMD case below, NUMA hinting must take slow
  20. * path using the pte_protnone check.
  21. */
  22. if (pte_protnone(pte))
  23. goto pte_unmap;
  24. if (!pte_present(pte) || pte_special(pte) ||
  25. pte_protnone(pte) || (write && !pte_write(pte)))
  26. goto pte_unmap;
  27. if (pte_special(pte))
  28. goto pte_unmap;
  29. VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
  30. page = pte_page(pte);
  31. if (!page_cache_get_speculative(page))
  32. goto pte_unmap;
  33. if (unlikely(pte_val(pte) != pte_val(*ptep))) {
  34. put_page(page);
  35. goto pte_unmap;
  36. }
  37. SetPageReferenced(page);
  38. pages[*nr] = page;
  39. (*nr)++;
  40. } while (ptep++, addr += PAGE_SIZE, addr != end);
  41. ret = 1;
  42. pte_unmap:
  43. pte_unmap(ptem);
  44. return ret;
  45. }
  46. static int gup_pmd_range(pud_t pud, unsigned long addr, unsigned long end,
  47. int write, struct page **pages, int *nr)
  48. {
  49. unsigned long next;
  50. pmd_t *pmdp;
  51. pmdp = pmd_offset(&pud, addr);
  52. do {
  53. pmd_t pmd = READ_ONCE(*pmdp);
  54. next = pmd_addr_end(addr, end);
  55. if (!pmd_present(pmd))
  56. return 0;
  57. else if (!gup_pte_range(pmd, addr, next, write, pages, nr))
  58. return 0;
  59. } while (pmdp++, addr = next, addr != end);
  60. return 1;
  61. }
  62. static int gup_pud_range(pgd_t *pgd, unsigned long addr, unsigned long end,
  63. int write, struct page **pages, int *nr)
  64. {
  65. unsigned long next;
  66. pud_t *pudp;
  67. pudp = pud_offset(pgd, addr);
  68. do {
  69. pud_t pud = READ_ONCE(*pudp);
  70. next = pud_addr_end(addr, end);
  71. if (pud_none(pud))
  72. return 0;
  73. else if (!gup_pmd_range(pud, addr, next, write, pages, nr))
  74. return 0;
  75. } while (pudp++, addr = next, addr != end);
  76. return 1;
  77. }
  78. static void gup_pgd_range(unsigned long addr, unsigned long end,
  79. int write, struct page **pages, int *nr)
  80. {
  81. unsigned long next;
  82. pgd_t *pgdp;
  83. pgdp = pgd_offset(current->mm, addr);
  84. do {
  85. next = pgd_addr_end(addr, end);
  86. if (pgd_none(*pgdp))
  87. return;
  88. else if (!gup_pud_range(pgdp, addr, next, write, pages, nr))
  89. break;
  90. } while (pgdp++, addr = next, addr != end);
  91. }
  92. bool gup_fast_permitted(unsigned long start, int nr_pages, int write)
  93. {
  94. unsigned long len, end;
  95. len = (unsigned long) nr_pages << PAGE_SHIFT;
  96. end = start + len;
  97. return end >= start;
  98. }
  99. /*
  100. * Like get_user_pages_fast() except its IRQ-safe in that it won't fall
  101. * back to the regular GUP.
  102. */
  103. int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
  104. struct page **pages)
  105. {
  106. unsigned long addr, len, end;
  107. unsigned long flags;
  108. int nr = 0;
  109. start &= PAGE_MASK;
  110. addr = start;
  111. len = (unsigned long) nr_pages << PAGE_SHIFT;
  112. end = start + len;
  113. if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
  114. (void __user *)start, len)))
  115. return 0;
  116. /*
  117. * Disable interrupts. We use the nested form as we can already have
  118. * interrupts disabled by get_futex_key.
  119. *
  120. * With interrupts disabled, we block page table pages from being
  121. * freed from under us. See mmu_gather_tlb in asm-generic/tlb.h
  122. * for more details.
  123. *
  124. * We do not adopt an rcu_read_lock(.) here as we also want to
  125. * block IPIs that come from THPs splitting.
  126. */
  127. if (gup_fast_permitted(start, nr_pages, write)) {
  128. local_irq_save(flags);
  129. gup_pgd_range(addr, end, write, pages, &nr);
  130. local_irq_restore(flags);
  131. }
  132. return nr;
  133. }
  134. int get_user_pages_fast(unsigned long start, int nr_pages, int write,
  135. struct page **pages)
  136. {
  137. unsigned long addr, len, end;
  138. int nr = 0, ret = 0;
  139. start &= PAGE_MASK;
  140. addr = start;
  141. len = (unsigned long) nr_pages << PAGE_SHIFT;
  142. end = start + len;
  143. if (nr_pages <= 0)
  144. return 0;
  145. if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
  146. (void __user *)start, len)))
  147. return -EFAULT;
  148. if (gup_fast_permitted(start, nr_pages, write)) {
  149. local_irq_disable();
  150. gup_pgd_range(addr, end, write, pages, &nr);
  151. local_irq_enable();
  152. ret = nr;
  153. }
  154. if (nr < nr_pages) {
  155. /* Try to get the remaining pages with get_user_pages */
  156. start += nr << PAGE_SHIFT;
  157. pages += nr;
  158. ret = get_user_pages_unlocked(start, nr_pages - nr, pages,
  159. write ? FOLL_WRITE : 0);
  160. /* Have to be a bit careful with return values */
  161. if (nr > 0) {
  162. if (ret < 0)
  163. ret = nr;
  164. else
  165. ret += nr;
  166. }
  167. }
  168. return ret;
  169. }