iommu-pages.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2024, Google LLC.
  4. * Pasha Tatashin <pasha.tatashin@soleen.com>
  5. */
  6. #include "iommu-pages.h"
  7. #include <linux/dma-mapping.h>
  8. #include <linux/gfp.h>
  9. #include <linux/mm.h>
  10. #define IOPTDESC_MATCH(pg_elm, elm) \
  11. static_assert(offsetof(struct page, pg_elm) == \
  12. offsetof(struct ioptdesc, elm))
  13. IOPTDESC_MATCH(flags, __page_flags);
  14. IOPTDESC_MATCH(lru, iopt_freelist_elm); /* Ensure bit 0 is clear */
  15. IOPTDESC_MATCH(mapping, __page_mapping);
  16. IOPTDESC_MATCH(private, _private);
  17. IOPTDESC_MATCH(page_type, __page_type);
  18. IOPTDESC_MATCH(_refcount, __page_refcount);
  19. #ifdef CONFIG_MEMCG
  20. IOPTDESC_MATCH(memcg_data, memcg_data);
  21. #endif
  22. #undef IOPTDESC_MATCH
  23. static_assert(sizeof(struct ioptdesc) <= sizeof(struct page));
  24. static inline size_t ioptdesc_mem_size(struct ioptdesc *desc)
  25. {
  26. return 1UL << (folio_order(ioptdesc_folio(desc)) + PAGE_SHIFT);
  27. }
  28. /**
  29. * iommu_alloc_pages_node_sz - Allocate a zeroed page of a given size from
  30. * specific NUMA node
  31. * @nid: memory NUMA node id
  32. * @gfp: buddy allocator flags
  33. * @size: Memory size to allocate, rounded up to a power of 2
  34. *
  35. * Returns the virtual address of the allocated page. The page must be freed
  36. * either by calling iommu_free_pages() or via iommu_put_pages_list(). The
  37. * returned allocation is round_up_pow_two(size) big, and is physically aligned
  38. * to its size.
  39. */
  40. void *iommu_alloc_pages_node_sz(int nid, gfp_t gfp, size_t size)
  41. {
  42. struct ioptdesc *iopt;
  43. unsigned long pgcnt;
  44. struct folio *folio;
  45. unsigned int order;
  46. /* This uses page_address() on the memory. */
  47. if (WARN_ON(gfp & __GFP_HIGHMEM))
  48. return NULL;
  49. /*
  50. * Currently sub page allocations result in a full page being returned.
  51. */
  52. order = get_order(size);
  53. /*
  54. * __folio_alloc_node() does not handle NUMA_NO_NODE like
  55. * alloc_pages_node() did.
  56. */
  57. if (nid == NUMA_NO_NODE)
  58. nid = numa_mem_id();
  59. folio = __folio_alloc_node(gfp | __GFP_ZERO, order, nid);
  60. if (unlikely(!folio))
  61. return NULL;
  62. iopt = folio_ioptdesc(folio);
  63. iopt->incoherent = false;
  64. /*
  65. * All page allocations that should be reported to as "iommu-pagetables"
  66. * to userspace must use one of the functions below. This includes
  67. * allocations of page-tables and other per-iommu_domain configuration
  68. * structures.
  69. *
  70. * This is necessary for the proper accounting as IOMMU state can be
  71. * rather large, i.e. multiple gigabytes in size.
  72. */
  73. pgcnt = 1UL << order;
  74. mod_node_page_state(folio_pgdat(folio), NR_IOMMU_PAGES, pgcnt);
  75. lruvec_stat_mod_folio(folio, NR_SECONDARY_PAGETABLE, pgcnt);
  76. return folio_address(folio);
  77. }
  78. EXPORT_SYMBOL_GPL(iommu_alloc_pages_node_sz);
  79. static void __iommu_free_desc(struct ioptdesc *iopt)
  80. {
  81. struct folio *folio = ioptdesc_folio(iopt);
  82. const unsigned long pgcnt = folio_nr_pages(folio);
  83. if (IOMMU_PAGES_USE_DMA_API)
  84. WARN_ON_ONCE(iopt->incoherent);
  85. mod_node_page_state(folio_pgdat(folio), NR_IOMMU_PAGES, -pgcnt);
  86. lruvec_stat_mod_folio(folio, NR_SECONDARY_PAGETABLE, -pgcnt);
  87. folio_put(folio);
  88. }
  89. /**
  90. * iommu_free_pages - free pages
  91. * @virt: virtual address of the page to be freed.
  92. *
  93. * The page must have have been allocated by iommu_alloc_pages_node_sz()
  94. */
  95. void iommu_free_pages(void *virt)
  96. {
  97. if (!virt)
  98. return;
  99. __iommu_free_desc(virt_to_ioptdesc(virt));
  100. }
  101. EXPORT_SYMBOL_GPL(iommu_free_pages);
  102. /**
  103. * iommu_put_pages_list - free a list of pages.
  104. * @list: The list of pages to be freed
  105. *
  106. * Frees a list of pages allocated by iommu_alloc_pages_node_sz(). On return the
  107. * passed list is invalid, the caller must use IOMMU_PAGES_LIST_INIT to reinit
  108. * the list if it expects to use it again.
  109. */
  110. void iommu_put_pages_list(struct iommu_pages_list *list)
  111. {
  112. struct ioptdesc *iopt, *tmp;
  113. list_for_each_entry_safe(iopt, tmp, &list->pages, iopt_freelist_elm)
  114. __iommu_free_desc(iopt);
  115. }
  116. EXPORT_SYMBOL_GPL(iommu_put_pages_list);
  117. /**
  118. * iommu_pages_start_incoherent - Setup the page for cache incoherent operation
  119. * @virt: The page to setup
  120. * @dma_dev: The iommu device
  121. *
  122. * For incoherent memory this will use the DMA API to manage the cache flushing
  123. * on some arches. This is a lot of complexity compared to just calling
  124. * arch_sync_dma_for_device(), but it is what the existing ARM iommu drivers
  125. * have been doing. The DMA API requires keeping track of the DMA map and
  126. * freeing it when required. This keeps track of the dma map inside the ioptdesc
  127. * so that error paths are simple for the caller.
  128. */
  129. int iommu_pages_start_incoherent(void *virt, struct device *dma_dev)
  130. {
  131. struct ioptdesc *iopt = virt_to_ioptdesc(virt);
  132. dma_addr_t dma;
  133. if (WARN_ON(iopt->incoherent))
  134. return -EINVAL;
  135. if (!IOMMU_PAGES_USE_DMA_API) {
  136. iommu_pages_flush_incoherent(dma_dev, virt, 0,
  137. ioptdesc_mem_size(iopt));
  138. } else {
  139. dma = dma_map_single(dma_dev, virt, ioptdesc_mem_size(iopt),
  140. DMA_TO_DEVICE);
  141. if (dma_mapping_error(dma_dev, dma))
  142. return -EINVAL;
  143. /*
  144. * The DMA API is not allowed to do anything other than DMA
  145. * direct. It would be nice to also check
  146. * dev_is_dma_coherent(dma_dev));
  147. */
  148. if (WARN_ON(dma != virt_to_phys(virt))) {
  149. dma_unmap_single(dma_dev, dma, ioptdesc_mem_size(iopt),
  150. DMA_TO_DEVICE);
  151. return -EOPNOTSUPP;
  152. }
  153. }
  154. iopt->incoherent = 1;
  155. return 0;
  156. }
  157. EXPORT_SYMBOL_GPL(iommu_pages_start_incoherent);
  158. /**
  159. * iommu_pages_start_incoherent_list - Make a list of pages incoherent
  160. * @list: The list of pages to setup
  161. * @dma_dev: The iommu device
  162. *
  163. * Perform iommu_pages_start_incoherent() across all of list.
  164. *
  165. * If this fails the caller must call iommu_pages_stop_incoherent_list().
  166. */
  167. int iommu_pages_start_incoherent_list(struct iommu_pages_list *list,
  168. struct device *dma_dev)
  169. {
  170. struct ioptdesc *cur;
  171. int ret;
  172. list_for_each_entry(cur, &list->pages, iopt_freelist_elm) {
  173. if (WARN_ON(cur->incoherent))
  174. continue;
  175. ret = iommu_pages_start_incoherent(
  176. folio_address(ioptdesc_folio(cur)), dma_dev);
  177. if (ret)
  178. return ret;
  179. }
  180. return 0;
  181. }
  182. EXPORT_SYMBOL_GPL(iommu_pages_start_incoherent_list);
  183. /**
  184. * iommu_pages_stop_incoherent_list - Undo incoherence across a list
  185. * @list: The list of pages to release
  186. * @dma_dev: The iommu device
  187. *
  188. * Revert iommu_pages_start_incoherent() across all of the list. Pages that did
  189. * not call or succeed iommu_pages_start_incoherent() will be ignored.
  190. */
  191. #if IOMMU_PAGES_USE_DMA_API
  192. void iommu_pages_stop_incoherent_list(struct iommu_pages_list *list,
  193. struct device *dma_dev)
  194. {
  195. struct ioptdesc *cur;
  196. list_for_each_entry(cur, &list->pages, iopt_freelist_elm) {
  197. struct folio *folio = ioptdesc_folio(cur);
  198. if (!cur->incoherent)
  199. continue;
  200. dma_unmap_single(dma_dev, virt_to_phys(folio_address(folio)),
  201. ioptdesc_mem_size(cur), DMA_TO_DEVICE);
  202. cur->incoherent = 0;
  203. }
  204. }
  205. EXPORT_SYMBOL_GPL(iommu_pages_stop_incoherent_list);
  206. /**
  207. * iommu_pages_free_incoherent - Free an incoherent page
  208. * @virt: virtual address of the page to be freed.
  209. * @dma_dev: The iommu device
  210. *
  211. * If the page is incoherent it made coherent again then freed.
  212. */
  213. void iommu_pages_free_incoherent(void *virt, struct device *dma_dev)
  214. {
  215. struct ioptdesc *iopt = virt_to_ioptdesc(virt);
  216. if (iopt->incoherent) {
  217. dma_unmap_single(dma_dev, virt_to_phys(virt),
  218. ioptdesc_mem_size(iopt), DMA_TO_DEVICE);
  219. iopt->incoherent = 0;
  220. }
  221. __iommu_free_desc(iopt);
  222. }
  223. EXPORT_SYMBOL_GPL(iommu_pages_free_incoherent);
  224. #endif