cma_heap.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * DMABUF CMA heap exporter
  4. *
  5. * Copyright (C) 2012, 2019, 2020 Linaro Ltd.
  6. * Author: <benjamin.gaignard@linaro.org> for ST-Ericsson.
  7. *
  8. * Also utilizing parts of Andrew Davis' SRAM heap:
  9. * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
  10. * Andrew F. Davis <afd@ti.com>
  11. */
  12. #define pr_fmt(fmt) "cma_heap: " fmt
  13. #include <linux/cma.h>
  14. #include <linux/dma-buf.h>
  15. #include <linux/dma-buf/heaps/cma.h>
  16. #include <linux/dma-heap.h>
  17. #include <linux/dma-map-ops.h>
  18. #include <linux/err.h>
  19. #include <linux/highmem.h>
  20. #include <linux/io.h>
  21. #include <linux/mm.h>
  22. #include <linux/module.h>
  23. #include <linux/of.h>
  24. #include <linux/of_reserved_mem.h>
  25. #include <linux/scatterlist.h>
  26. #include <linux/slab.h>
  27. #include <linux/vmalloc.h>
  28. #define DEFAULT_CMA_NAME "default_cma_region"
  29. static struct cma *dma_areas[MAX_CMA_AREAS] __initdata;
  30. static unsigned int dma_areas_num __initdata;
  31. int __init dma_heap_cma_register_heap(struct cma *cma)
  32. {
  33. if (dma_areas_num >= ARRAY_SIZE(dma_areas))
  34. return -EINVAL;
  35. dma_areas[dma_areas_num++] = cma;
  36. return 0;
  37. }
  38. struct cma_heap {
  39. struct dma_heap *heap;
  40. struct cma *cma;
  41. };
  42. struct cma_heap_buffer {
  43. struct cma_heap *heap;
  44. struct list_head attachments;
  45. struct mutex lock;
  46. unsigned long len;
  47. struct page *cma_pages;
  48. struct page **pages;
  49. pgoff_t pagecount;
  50. int vmap_cnt;
  51. void *vaddr;
  52. };
  53. struct dma_heap_attachment {
  54. struct device *dev;
  55. struct sg_table table;
  56. struct list_head list;
  57. bool mapped;
  58. };
  59. static int cma_heap_attach(struct dma_buf *dmabuf,
  60. struct dma_buf_attachment *attachment)
  61. {
  62. struct cma_heap_buffer *buffer = dmabuf->priv;
  63. struct dma_heap_attachment *a;
  64. int ret;
  65. a = kzalloc_obj(*a);
  66. if (!a)
  67. return -ENOMEM;
  68. ret = sg_alloc_table_from_pages(&a->table, buffer->pages,
  69. buffer->pagecount, 0,
  70. buffer->pagecount << PAGE_SHIFT,
  71. GFP_KERNEL);
  72. if (ret) {
  73. kfree(a);
  74. return ret;
  75. }
  76. a->dev = attachment->dev;
  77. INIT_LIST_HEAD(&a->list);
  78. a->mapped = false;
  79. attachment->priv = a;
  80. mutex_lock(&buffer->lock);
  81. list_add(&a->list, &buffer->attachments);
  82. mutex_unlock(&buffer->lock);
  83. return 0;
  84. }
  85. static void cma_heap_detach(struct dma_buf *dmabuf,
  86. struct dma_buf_attachment *attachment)
  87. {
  88. struct cma_heap_buffer *buffer = dmabuf->priv;
  89. struct dma_heap_attachment *a = attachment->priv;
  90. mutex_lock(&buffer->lock);
  91. list_del(&a->list);
  92. mutex_unlock(&buffer->lock);
  93. sg_free_table(&a->table);
  94. kfree(a);
  95. }
  96. static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachment,
  97. enum dma_data_direction direction)
  98. {
  99. struct dma_heap_attachment *a = attachment->priv;
  100. struct sg_table *table = &a->table;
  101. int ret;
  102. ret = dma_map_sgtable(attachment->dev, table, direction, 0);
  103. if (ret)
  104. return ERR_PTR(-ENOMEM);
  105. a->mapped = true;
  106. return table;
  107. }
  108. static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment,
  109. struct sg_table *table,
  110. enum dma_data_direction direction)
  111. {
  112. struct dma_heap_attachment *a = attachment->priv;
  113. a->mapped = false;
  114. dma_unmap_sgtable(attachment->dev, table, direction, 0);
  115. }
  116. static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf,
  117. enum dma_data_direction direction)
  118. {
  119. struct cma_heap_buffer *buffer = dmabuf->priv;
  120. struct dma_heap_attachment *a;
  121. mutex_lock(&buffer->lock);
  122. if (buffer->vmap_cnt)
  123. invalidate_kernel_vmap_range(buffer->vaddr, buffer->len);
  124. list_for_each_entry(a, &buffer->attachments, list) {
  125. if (!a->mapped)
  126. continue;
  127. dma_sync_sgtable_for_cpu(a->dev, &a->table, direction);
  128. }
  129. mutex_unlock(&buffer->lock);
  130. return 0;
  131. }
  132. static int cma_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf,
  133. enum dma_data_direction direction)
  134. {
  135. struct cma_heap_buffer *buffer = dmabuf->priv;
  136. struct dma_heap_attachment *a;
  137. mutex_lock(&buffer->lock);
  138. if (buffer->vmap_cnt)
  139. flush_kernel_vmap_range(buffer->vaddr, buffer->len);
  140. list_for_each_entry(a, &buffer->attachments, list) {
  141. if (!a->mapped)
  142. continue;
  143. dma_sync_sgtable_for_device(a->dev, &a->table, direction);
  144. }
  145. mutex_unlock(&buffer->lock);
  146. return 0;
  147. }
  148. static vm_fault_t cma_heap_vm_fault(struct vm_fault *vmf)
  149. {
  150. struct vm_area_struct *vma = vmf->vma;
  151. struct cma_heap_buffer *buffer = vma->vm_private_data;
  152. if (vmf->pgoff >= buffer->pagecount)
  153. return VM_FAULT_SIGBUS;
  154. return vmf_insert_pfn(vma, vmf->address, page_to_pfn(buffer->pages[vmf->pgoff]));
  155. }
  156. static const struct vm_operations_struct dma_heap_vm_ops = {
  157. .fault = cma_heap_vm_fault,
  158. };
  159. static int cma_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma)
  160. {
  161. struct cma_heap_buffer *buffer = dmabuf->priv;
  162. if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0)
  163. return -EINVAL;
  164. vm_flags_set(vma, VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
  165. vma->vm_ops = &dma_heap_vm_ops;
  166. vma->vm_private_data = buffer;
  167. return 0;
  168. }
  169. static void *cma_heap_do_vmap(struct cma_heap_buffer *buffer)
  170. {
  171. void *vaddr;
  172. vaddr = vmap(buffer->pages, buffer->pagecount, VM_MAP, PAGE_KERNEL);
  173. if (!vaddr)
  174. return ERR_PTR(-ENOMEM);
  175. return vaddr;
  176. }
  177. static int cma_heap_vmap(struct dma_buf *dmabuf, struct iosys_map *map)
  178. {
  179. struct cma_heap_buffer *buffer = dmabuf->priv;
  180. void *vaddr;
  181. int ret = 0;
  182. mutex_lock(&buffer->lock);
  183. if (buffer->vmap_cnt) {
  184. buffer->vmap_cnt++;
  185. iosys_map_set_vaddr(map, buffer->vaddr);
  186. goto out;
  187. }
  188. vaddr = cma_heap_do_vmap(buffer);
  189. if (IS_ERR(vaddr)) {
  190. ret = PTR_ERR(vaddr);
  191. goto out;
  192. }
  193. buffer->vaddr = vaddr;
  194. buffer->vmap_cnt++;
  195. iosys_map_set_vaddr(map, buffer->vaddr);
  196. out:
  197. mutex_unlock(&buffer->lock);
  198. return ret;
  199. }
  200. static void cma_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map)
  201. {
  202. struct cma_heap_buffer *buffer = dmabuf->priv;
  203. mutex_lock(&buffer->lock);
  204. if (!--buffer->vmap_cnt) {
  205. vunmap(buffer->vaddr);
  206. buffer->vaddr = NULL;
  207. }
  208. mutex_unlock(&buffer->lock);
  209. iosys_map_clear(map);
  210. }
  211. static void cma_heap_dma_buf_release(struct dma_buf *dmabuf)
  212. {
  213. struct cma_heap_buffer *buffer = dmabuf->priv;
  214. struct cma_heap *cma_heap = buffer->heap;
  215. if (buffer->vmap_cnt > 0) {
  216. WARN(1, "%s: buffer still mapped in the kernel\n", __func__);
  217. vunmap(buffer->vaddr);
  218. buffer->vaddr = NULL;
  219. }
  220. /* free page list */
  221. kfree(buffer->pages);
  222. /* release memory */
  223. cma_release(cma_heap->cma, buffer->cma_pages, buffer->pagecount);
  224. kfree(buffer);
  225. }
  226. static const struct dma_buf_ops cma_heap_buf_ops = {
  227. .attach = cma_heap_attach,
  228. .detach = cma_heap_detach,
  229. .map_dma_buf = cma_heap_map_dma_buf,
  230. .unmap_dma_buf = cma_heap_unmap_dma_buf,
  231. .begin_cpu_access = cma_heap_dma_buf_begin_cpu_access,
  232. .end_cpu_access = cma_heap_dma_buf_end_cpu_access,
  233. .mmap = cma_heap_mmap,
  234. .vmap = cma_heap_vmap,
  235. .vunmap = cma_heap_vunmap,
  236. .release = cma_heap_dma_buf_release,
  237. };
  238. static struct dma_buf *cma_heap_allocate(struct dma_heap *heap,
  239. unsigned long len,
  240. u32 fd_flags,
  241. u64 heap_flags)
  242. {
  243. struct cma_heap *cma_heap = dma_heap_get_drvdata(heap);
  244. struct cma_heap_buffer *buffer;
  245. DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
  246. size_t size = PAGE_ALIGN(len);
  247. pgoff_t pagecount = size >> PAGE_SHIFT;
  248. unsigned long align = get_order(size);
  249. struct page *cma_pages;
  250. struct dma_buf *dmabuf;
  251. int ret = -ENOMEM;
  252. pgoff_t pg;
  253. buffer = kzalloc_obj(*buffer);
  254. if (!buffer)
  255. return ERR_PTR(-ENOMEM);
  256. INIT_LIST_HEAD(&buffer->attachments);
  257. mutex_init(&buffer->lock);
  258. buffer->len = size;
  259. if (align > CONFIG_CMA_ALIGNMENT)
  260. align = CONFIG_CMA_ALIGNMENT;
  261. cma_pages = cma_alloc(cma_heap->cma, pagecount, align, false);
  262. if (!cma_pages)
  263. goto free_buffer;
  264. /* Clear the cma pages */
  265. if (PageHighMem(cma_pages)) {
  266. unsigned long nr_clear_pages = pagecount;
  267. struct page *page = cma_pages;
  268. while (nr_clear_pages > 0) {
  269. void *vaddr = kmap_local_page(page);
  270. clear_page(vaddr);
  271. kunmap_local(vaddr);
  272. /*
  273. * Avoid wasting time zeroing memory if the process
  274. * has been killed by SIGKILL.
  275. */
  276. if (fatal_signal_pending(current))
  277. goto free_cma;
  278. page++;
  279. nr_clear_pages--;
  280. }
  281. } else {
  282. memset(page_address(cma_pages), 0, size);
  283. }
  284. buffer->pages = kmalloc_objs(*buffer->pages, pagecount);
  285. if (!buffer->pages) {
  286. ret = -ENOMEM;
  287. goto free_cma;
  288. }
  289. for (pg = 0; pg < pagecount; pg++)
  290. buffer->pages[pg] = &cma_pages[pg];
  291. buffer->cma_pages = cma_pages;
  292. buffer->heap = cma_heap;
  293. buffer->pagecount = pagecount;
  294. /* create the dmabuf */
  295. exp_info.exp_name = dma_heap_get_name(heap);
  296. exp_info.ops = &cma_heap_buf_ops;
  297. exp_info.size = buffer->len;
  298. exp_info.flags = fd_flags;
  299. exp_info.priv = buffer;
  300. dmabuf = dma_buf_export(&exp_info);
  301. if (IS_ERR(dmabuf)) {
  302. ret = PTR_ERR(dmabuf);
  303. goto free_pages;
  304. }
  305. return dmabuf;
  306. free_pages:
  307. kfree(buffer->pages);
  308. free_cma:
  309. cma_release(cma_heap->cma, cma_pages, pagecount);
  310. free_buffer:
  311. kfree(buffer);
  312. return ERR_PTR(ret);
  313. }
  314. static const struct dma_heap_ops cma_heap_ops = {
  315. .allocate = cma_heap_allocate,
  316. };
  317. static int __init __add_cma_heap(struct cma *cma, const char *name)
  318. {
  319. struct dma_heap_export_info exp_info;
  320. struct cma_heap *cma_heap;
  321. cma_heap = kzalloc_obj(*cma_heap);
  322. if (!cma_heap)
  323. return -ENOMEM;
  324. cma_heap->cma = cma;
  325. exp_info.name = name;
  326. exp_info.ops = &cma_heap_ops;
  327. exp_info.priv = cma_heap;
  328. cma_heap->heap = dma_heap_add(&exp_info);
  329. if (IS_ERR(cma_heap->heap)) {
  330. int ret = PTR_ERR(cma_heap->heap);
  331. kfree(cma_heap);
  332. return ret;
  333. }
  334. return 0;
  335. }
  336. static int __init add_cma_heaps(void)
  337. {
  338. struct cma *default_cma = dev_get_cma_area(NULL);
  339. unsigned int i;
  340. int ret;
  341. if (default_cma) {
  342. ret = __add_cma_heap(default_cma, DEFAULT_CMA_NAME);
  343. if (ret)
  344. return ret;
  345. }
  346. for (i = 0; i < dma_areas_num; i++) {
  347. struct cma *cma = dma_areas[i];
  348. ret = __add_cma_heap(cma, cma_get_name(cma));
  349. if (ret) {
  350. pr_warn("Failed to add CMA heap %s", cma_get_name(cma));
  351. continue;
  352. }
  353. }
  354. return 0;
  355. }
  356. module_init(add_cma_heaps);
  357. MODULE_DESCRIPTION("DMA-BUF CMA Heap");