1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright 2018 Noralf Trønnes
4 */
5
6 #include <linux/dma-buf.h>
7 #include <linux/export.h>
8 #include <linux/module.h>
9 #include <linux/mutex.h>
10 #include <linux/shmem_fs.h>
11 #include <linux/slab.h>
12 #include <linux/vmalloc.h>
13
14 #ifdef CONFIG_X86
15 #include <asm/set_memory.h>
16 #endif
17
18 #include <kunit/visibility.h>
19
20 #include <drm/drm.h>
21 #include <drm/drm_device.h>
22 #include <drm/drm_drv.h>
23 #include <drm/drm_dumb_buffers.h>
24 #include <drm/drm_gem_shmem_helper.h>
25 #include <drm/drm_prime.h>
26 #include <drm/drm_print.h>
27
28 MODULE_IMPORT_NS("DMA_BUF");
29
30 /**
31 * DOC: overview
32 *
33 * This library provides helpers for GEM objects backed by shmem buffers
34 * allocated using anonymous pageable memory.
35 *
36 * Functions that operate on the GEM object receive struct &drm_gem_shmem_object.
37 * For GEM callback helpers in struct &drm_gem_object functions, see likewise
38 * named functions with an _object_ infix (e.g., drm_gem_shmem_object_vmap() wraps
39 * drm_gem_shmem_vmap()). These helpers perform the necessary type conversion.
40 */
41
42 static const struct drm_gem_object_funcs drm_gem_shmem_funcs = {
43 .free = drm_gem_shmem_object_free,
44 .print_info = drm_gem_shmem_object_print_info,
45 .pin = drm_gem_shmem_object_pin,
46 .unpin = drm_gem_shmem_object_unpin,
47 .get_sg_table = drm_gem_shmem_object_get_sg_table,
48 .vmap = drm_gem_shmem_object_vmap,
49 .vunmap = drm_gem_shmem_object_vunmap,
50 .mmap = drm_gem_shmem_object_mmap,
51 .vm_ops = &drm_gem_shmem_vm_ops,
52 };
53
__drm_gem_shmem_init(struct drm_device * dev,struct drm_gem_shmem_object * shmem,size_t size,bool private)54 static int __drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem,
55 size_t size, bool private)
56 {
57 struct drm_gem_object *obj = &shmem->base;
58 int ret = 0;
59
60 if (!obj->funcs)
61 obj->funcs = &drm_gem_shmem_funcs;
62
63 if (private) {
64 drm_gem_private_object_init(dev, obj, size);
65 shmem->map_wc = false; /* dma-buf mappings use always writecombine */
66 } else {
67 ret = drm_gem_object_init(dev, obj, size);
68 }
69 if (ret) {
70 drm_gem_private_object_fini(obj);
71 return ret;
72 }
73
74 ret = drm_gem_create_mmap_offset(obj);
75 if (ret)
76 goto err_release;
77
78 INIT_LIST_HEAD(&shmem->madv_list);
79
80 if (!private) {
81 /*
82 * Our buffers are kept pinned, so allocating them
83 * from the MOVABLE zone is a really bad idea, and
84 * conflicts with CMA. See comments above new_inode()
85 * why this is required _and_ expected if you're
86 * going to pin these pages.
87 */
88 mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER |
89 __GFP_RETRY_MAYFAIL | __GFP_NOWARN);
90 }
91
92 return 0;
93 err_release:
94 drm_gem_object_release(obj);
95 return ret;
96 }
97
98 /**
99 * drm_gem_shmem_init - Initialize an allocated object.
100 * @dev: DRM device
101 * @shmem: shmem GEM object to initialize
102 * @size: Buffer size in bytes
103 *
104 * This function initializes an allocated shmem GEM object.
105 *
106 * Returns:
107 * 0 on success, or a negative error code on failure.
108 */
drm_gem_shmem_init(struct drm_device * dev,struct drm_gem_shmem_object * shmem,size_t size)109 int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size)
110 {
111 return __drm_gem_shmem_init(dev, shmem, size, false);
112 }
113 EXPORT_SYMBOL_GPL(drm_gem_shmem_init);
114
115 static struct drm_gem_shmem_object *
__drm_gem_shmem_create(struct drm_device * dev,size_t size,bool private)116 __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private)
117 {
118 struct drm_gem_shmem_object *shmem;
119 struct drm_gem_object *obj;
120 int ret = 0;
121
122 size = PAGE_ALIGN(size);
123
124 if (dev->driver->gem_create_object) {
125 obj = dev->driver->gem_create_object(dev, size);
126 if (IS_ERR(obj))
127 return ERR_CAST(obj);
128 shmem = to_drm_gem_shmem_obj(obj);
129 } else {
130 shmem = kzalloc_obj(*shmem);
131 if (!shmem)
132 return ERR_PTR(-ENOMEM);
133 obj = &shmem->base;
134 }
135
136 ret = __drm_gem_shmem_init(dev, shmem, size, private);
137 if (ret) {
138 kfree(obj);
139 return ERR_PTR(ret);
140 }
141
142 return shmem;
143 }
144 /**
145 * drm_gem_shmem_create - Allocate an object with the given size
146 * @dev: DRM device
147 * @size: Size of the object to allocate
148 *
149 * This function creates a shmem GEM object.
150 *
151 * Returns:
152 * A struct drm_gem_shmem_object * on success or an ERR_PTR()-encoded negative
153 * error code on failure.
154 */
drm_gem_shmem_create(struct drm_device * dev,size_t size)155 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size)
156 {
157 return __drm_gem_shmem_create(dev, size, false);
158 }
159 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
160
161 /**
162 * __drm_gem_shmem_release_sgt_locked - Unpin and DMA unmap pages, and release the
163 * cached scatter/gather table for an shmem GEM object.
164 * @shmem: shmem GEM object
165 *
166 * If the passed shmem object has an active scatter/gather table for driver
167 * usage, this function will unmap it and release the memory associated with it.
168 * It is the responsibility of the caller to ensure it holds the dma_resv_lock
169 * for this object.
170 *
171 * Drivers should not need to call this function themselves, it is mainly
172 * intended for usage in the Rust shmem bindings.
173 */
__drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object * shmem)174 void __drm_gem_shmem_free_sgt_locked(struct drm_gem_shmem_object *shmem)
175 {
176 dma_resv_assert_held(shmem->base.resv);
177
178 dma_unmap_sgtable(shmem->base.dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
179 sg_free_table(shmem->sgt);
180 kfree(shmem->sgt);
181 shmem->sgt = NULL;
182 }
183 EXPORT_SYMBOL_GPL(__drm_gem_shmem_free_sgt_locked);
184
185 /**
186 * drm_gem_shmem_release - Release resources associated with a shmem GEM object.
187 * @shmem: shmem GEM object
188 *
189 * This function cleans up the GEM object state, but does not free the memory used to store the
190 * object itself. This function is meant to be a dedicated helper for the Rust GEM bindings.
191 */
drm_gem_shmem_release(struct drm_gem_shmem_object * shmem)192 void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem)
193 {
194 struct drm_gem_object *obj = &shmem->base;
195
196 if (drm_gem_is_imported(obj)) {
197 drm_prime_gem_destroy(obj, shmem->sgt);
198 } else {
199 dma_resv_lock(shmem->base.resv, NULL);
200
201 drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count));
202
203 if (shmem->sgt)
204 __drm_gem_shmem_free_sgt_locked(shmem);
205 if (shmem->pages)
206 drm_gem_shmem_put_pages_locked(shmem);
207
208 drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count));
209 drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count));
210
211 dma_resv_unlock(shmem->base.resv);
212 }
213
214 drm_gem_object_release(obj);
215 }
216 EXPORT_SYMBOL_GPL(drm_gem_shmem_release);
217
218 /**
219 * drm_gem_shmem_free - Free resources associated with a shmem GEM object
220 * @shmem: shmem GEM object to free
221 *
222 * This function cleans up the GEM object state and frees the memory used to
223 * store the object itself.
224 */
drm_gem_shmem_free(struct drm_gem_shmem_object * shmem)225 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem)
226 {
227 drm_gem_shmem_release(shmem);
228 kfree(shmem);
229 }
230 EXPORT_SYMBOL_GPL(drm_gem_shmem_free);
231
drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object * shmem)232 static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem)
233 {
234 struct drm_gem_object *obj = &shmem->base;
235 struct page **pages;
236
237 dma_resv_assert_held(shmem->base.resv);
238
239 if (refcount_inc_not_zero(&shmem->pages_use_count))
240 return 0;
241
242 pages = drm_gem_get_pages(obj);
243 if (IS_ERR(pages)) {
244 drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n",
245 PTR_ERR(pages));
246 return PTR_ERR(pages);
247 }
248
249 /*
250 * TODO: Allocating WC pages which are correctly flushed is only
251 * supported on x86. Ideal solution would be a GFP_WC flag, which also
252 * ttm_pool.c could use.
253 */
254 #ifdef CONFIG_X86
255 if (shmem->map_wc)
256 set_pages_array_wc(pages, obj->size >> PAGE_SHIFT);
257 #endif
258
259 shmem->pages = pages;
260
261 refcount_set(&shmem->pages_use_count, 1);
262
263 return 0;
264 }
265
266 /*
267 * drm_gem_shmem_put_pages_locked - Decrease use count on the backing pages for a shmem GEM object
268 * @shmem: shmem GEM object
269 *
270 * This function decreases the use count and puts the backing pages when use drops to zero.
271 */
drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object * shmem)272 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem)
273 {
274 struct drm_gem_object *obj = &shmem->base;
275
276 dma_resv_assert_held(shmem->base.resv);
277
278 if (refcount_dec_and_test(&shmem->pages_use_count)) {
279 #ifdef CONFIG_X86
280 if (shmem->map_wc)
281 set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT);
282 #endif
283
284 drm_gem_put_pages(obj, shmem->pages,
285 shmem->pages_mark_dirty_on_put,
286 shmem->pages_mark_accessed_on_put);
287 shmem->pages = NULL;
288 shmem->pages_mark_accessed_on_put = false;
289 shmem->pages_mark_dirty_on_put = false;
290 }
291 }
292 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked);
293
drm_gem_shmem_pin_locked(struct drm_gem_shmem_object * shmem)294 int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
295 {
296 int ret;
297
298 dma_resv_assert_held(shmem->base.resv);
299
300 drm_WARN_ON(shmem->base.dev, drm_gem_is_imported(&shmem->base));
301
302 if (refcount_inc_not_zero(&shmem->pages_pin_count))
303 return 0;
304
305 ret = drm_gem_shmem_get_pages_locked(shmem);
306 if (!ret)
307 refcount_set(&shmem->pages_pin_count, 1);
308
309 return ret;
310 }
311 EXPORT_SYMBOL(drm_gem_shmem_pin_locked);
312
drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object * shmem)313 void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
314 {
315 dma_resv_assert_held(shmem->base.resv);
316
317 if (refcount_dec_and_test(&shmem->pages_pin_count))
318 drm_gem_shmem_put_pages_locked(shmem);
319 }
320 EXPORT_SYMBOL(drm_gem_shmem_unpin_locked);
321
322 /**
323 * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
324 * @shmem: shmem GEM object
325 *
326 * This function makes sure the backing pages are pinned in memory while the
327 * buffer is exported.
328 *
329 * Returns:
330 * 0 on success or a negative error code on failure.
331 */
drm_gem_shmem_pin(struct drm_gem_shmem_object * shmem)332 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem)
333 {
334 struct drm_gem_object *obj = &shmem->base;
335 int ret;
336
337 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj));
338
339 if (refcount_inc_not_zero(&shmem->pages_pin_count))
340 return 0;
341
342 ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
343 if (ret)
344 return ret;
345 ret = drm_gem_shmem_pin_locked(shmem);
346 dma_resv_unlock(shmem->base.resv);
347
348 return ret;
349 }
350 EXPORT_SYMBOL_GPL(drm_gem_shmem_pin);
351
352 /**
353 * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object
354 * @shmem: shmem GEM object
355 *
356 * This function removes the requirement that the backing pages are pinned in
357 * memory.
358 */
drm_gem_shmem_unpin(struct drm_gem_shmem_object * shmem)359 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem)
360 {
361 struct drm_gem_object *obj = &shmem->base;
362
363 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj));
364
365 if (refcount_dec_not_one(&shmem->pages_pin_count))
366 return;
367
368 dma_resv_lock(shmem->base.resv, NULL);
369 drm_gem_shmem_unpin_locked(shmem);
370 dma_resv_unlock(shmem->base.resv);
371 }
372 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin);
373
374 /*
375 * drm_gem_shmem_vmap_locked - Create a virtual mapping for a shmem GEM object
376 * @shmem: shmem GEM object
377 * @map: Returns the kernel virtual address of the SHMEM GEM object's backing
378 * store.
379 *
380 * This function makes sure that a contiguous kernel virtual address mapping
381 * exists for the buffer backing the shmem GEM object. It hides the differences
382 * between dma-buf imported and natively allocated objects.
383 *
384 * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap_locked().
385 *
386 * Returns:
387 * 0 on success or a negative error code on failure.
388 */
drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object * shmem,struct iosys_map * map)389 int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem,
390 struct iosys_map *map)
391 {
392 struct drm_gem_object *obj = &shmem->base;
393 int ret = 0;
394
395 dma_resv_assert_held(obj->resv);
396
397 if (drm_gem_is_imported(obj)) {
398 ret = dma_buf_vmap(obj->import_attach->dmabuf, map);
399 } else {
400 pgprot_t prot = PAGE_KERNEL;
401
402 dma_resv_assert_held(shmem->base.resv);
403
404 if (refcount_inc_not_zero(&shmem->vmap_use_count)) {
405 iosys_map_set_vaddr(map, shmem->vaddr);
406 return 0;
407 }
408
409 ret = drm_gem_shmem_pin_locked(shmem);
410 if (ret)
411 return ret;
412
413 if (shmem->map_wc)
414 prot = pgprot_writecombine(prot);
415 shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
416 VM_MAP, prot);
417 if (!shmem->vaddr) {
418 ret = -ENOMEM;
419 } else {
420 iosys_map_set_vaddr(map, shmem->vaddr);
421 refcount_set(&shmem->vmap_use_count, 1);
422 shmem->pages_mark_accessed_on_put = true;
423 shmem->pages_mark_dirty_on_put = true;
424 }
425 }
426
427 if (ret) {
428 drm_dbg_kms(obj->dev, "Failed to vmap pages, error %d\n", ret);
429 goto err_put_pages;
430 }
431
432 return 0;
433
434 err_put_pages:
435 if (!drm_gem_is_imported(obj))
436 drm_gem_shmem_unpin_locked(shmem);
437
438 return ret;
439 }
440 EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap_locked);
441
442 /*
443 * drm_gem_shmem_vunmap_locked - Unmap a virtual mapping for a shmem GEM object
444 * @shmem: shmem GEM object
445 * @map: Kernel virtual address where the SHMEM GEM object was mapped
446 *
447 * This function cleans up a kernel virtual address mapping acquired by
448 * drm_gem_shmem_vmap_locked(). The mapping is only removed when the use count
449 * drops to zero.
450 *
451 * This function hides the differences between dma-buf imported and natively
452 * allocated objects.
453 */
drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object * shmem,struct iosys_map * map)454 void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem,
455 struct iosys_map *map)
456 {
457 struct drm_gem_object *obj = &shmem->base;
458
459 dma_resv_assert_held(obj->resv);
460
461 if (drm_gem_is_imported(obj)) {
462 dma_buf_vunmap(obj->import_attach->dmabuf, map);
463 } else {
464 dma_resv_assert_held(shmem->base.resv);
465
466 if (refcount_dec_and_test(&shmem->vmap_use_count)) {
467 vunmap(shmem->vaddr);
468 shmem->vaddr = NULL;
469
470 drm_gem_shmem_unpin_locked(shmem);
471 }
472 }
473 }
474 EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap_locked);
475
476 /**
477 * drm_gem_shmem_create_with_handle - Allocate an object with the given size and
478 * returns a GEM handle
479 * @file_priv: DRM file structure to create the dumb buffer for
480 * @dev: DRM device
481 * @size: Size of the object to allocate
482 * @handle: Returns the GEM handle on success
483 *
484 * Allocates an shmem GEM buffer using drm_gem_shmem_create() and returns
485 * a GEM handle to it.
486 *
487 * Returns:
488 * Zero on success, or an error code otherwise.
489 */
drm_gem_shmem_create_with_handle(struct drm_file * file_priv,struct drm_device * dev,size_t size,uint32_t * handle)490 int drm_gem_shmem_create_with_handle(struct drm_file *file_priv,
491 struct drm_device *dev, size_t size,
492 uint32_t *handle)
493 {
494 struct drm_gem_shmem_object *shmem;
495 int ret;
496
497 shmem = drm_gem_shmem_create(dev, size);
498 if (IS_ERR(shmem))
499 return PTR_ERR(shmem);
500
501 /*
502 * Allocate an id of idr table where the obj is registered
503 * and handle has the id what user can see.
504 */
505 ret = drm_gem_handle_create(file_priv, &shmem->base, handle);
506 /* drop reference from allocate - handle holds it now. */
507 drm_gem_object_put(&shmem->base);
508
509 return ret;
510 }
511 EXPORT_SYMBOL_GPL(drm_gem_shmem_create_with_handle);
512
513 /* Update madvise status, returns true if not purged, else
514 * false or -errno.
515 */
drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object * shmem,int madv)516 int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv)
517 {
518 dma_resv_assert_held(shmem->base.resv);
519
520 if (shmem->madv >= 0)
521 shmem->madv = madv;
522
523 madv = shmem->madv;
524
525 return (madv >= 0);
526 }
527 EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked);
528
drm_gem_shmem_purge_locked(struct drm_gem_shmem_object * shmem)529 void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem)
530 {
531 struct drm_gem_object *obj = &shmem->base;
532 struct drm_device *dev = obj->dev;
533
534 dma_resv_assert_held(shmem->base.resv);
535
536 drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem));
537
538 dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0);
539 sg_free_table(shmem->sgt);
540 kfree(shmem->sgt);
541 shmem->sgt = NULL;
542
543 drm_gem_shmem_put_pages_locked(shmem);
544
545 shmem->madv = -1;
546
547 drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping);
548 drm_gem_free_mmap_offset(obj);
549
550 /* Our goal here is to return as much of the memory as
551 * is possible back to the system as we are called from OOM.
552 * To do this we must instruct the shmfs to drop all of its
553 * backing pages, *now*.
554 */
555 shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1);
556
557 invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1);
558 }
559 EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked);
560
561 /**
562 * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object
563 * @file: DRM file structure to create the dumb buffer for
564 * @dev: DRM device
565 * @args: IOCTL data
566 *
567 * This function computes the pitch of the dumb buffer and rounds it up to an
568 * integer number of bytes per pixel. Drivers for hardware that doesn't have
569 * any additional restrictions on the pitch can directly use this function as
570 * their &drm_driver.dumb_create callback.
571 *
572 * For hardware with additional restrictions, drivers can adjust the fields
573 * set up by userspace before calling into this function.
574 *
575 * Returns:
576 * 0 on success or a negative error code on failure.
577 */
drm_gem_shmem_dumb_create(struct drm_file * file,struct drm_device * dev,struct drm_mode_create_dumb * args)578 int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev,
579 struct drm_mode_create_dumb *args)
580 {
581 int ret;
582
583 ret = drm_mode_size_dumb(dev, args, 0, 0);
584 if (ret)
585 return ret;
586
587 return drm_gem_shmem_create_with_handle(file, dev, args->size, &args->handle);
588 }
589 EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create);
590
drm_gem_shmem_record_mkwrite(struct vm_fault * vmf)591 static void drm_gem_shmem_record_mkwrite(struct vm_fault *vmf)
592 {
593 struct vm_area_struct *vma = vmf->vma;
594 struct drm_gem_object *obj = vma->vm_private_data;
595 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
596 loff_t num_pages = obj->size >> PAGE_SHIFT;
597 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */
598
599 if (drm_WARN_ON(obj->dev, !shmem->pages || page_offset >= num_pages))
600 return;
601
602 file_update_time(vma->vm_file);
603 folio_mark_dirty(page_folio(shmem->pages[page_offset]));
604 }
605
try_insert_pfn(struct vm_fault * vmf,unsigned int order,unsigned long pfn)606 static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order,
607 unsigned long pfn)
608 {
609 if (!order) {
610 return vmf_insert_pfn(vmf->vma, vmf->address, pfn);
611 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
612 } else if (order == PMD_ORDER) {
613 unsigned long paddr = pfn << PAGE_SHIFT;
614 struct vm_area_struct *vma = vmf->vma;
615 unsigned long start = ALIGN_DOWN(vmf->address, PMD_SIZE);
616 unsigned long end = start + PMD_SIZE;
617 bool in_range = vma->vm_start <= start && end <= vma->vm_end;
618 bool aligned = (vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK);
619
620 if (aligned && in_range &&
621 folio_test_pmd_mappable(page_folio(pfn_to_page(pfn)))) {
622 vm_fault_t ret;
623
624 pfn &= PMD_MASK >> PAGE_SHIFT;
625
626 /* Unlike PTEs which are automatically upgraded to
627 * writeable entries, the PMD upgrades go through
628 * .huge_fault(). Make sure we pass the "write" info
629 * along in that case.
630 * This also means we have to record the write fault
631 * here, instead of in .pfn_mkwrite().
632 */
633 ret = vmf_insert_pfn_pmd(vmf, pfn,
634 vmf->flags & FAULT_FLAG_WRITE);
635 if (ret == VM_FAULT_NOPAGE && (vmf->flags & FAULT_FLAG_WRITE))
636 drm_gem_shmem_record_mkwrite(vmf);
637
638 return ret;
639 }
640 #endif
641 }
642 return VM_FAULT_FALLBACK;
643 }
644
drm_gem_shmem_any_fault(struct vm_fault * vmf,unsigned int order)645 static vm_fault_t drm_gem_shmem_any_fault(struct vm_fault *vmf, unsigned int order)
646 {
647 struct vm_area_struct *vma = vmf->vma;
648 struct drm_gem_object *obj = vma->vm_private_data;
649 struct drm_device *dev = obj->dev;
650 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
651 loff_t num_pages = obj->size >> PAGE_SHIFT;
652 vm_fault_t ret = VM_FAULT_SIGBUS;
653 struct page **pages = shmem->pages;
654 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */
655 struct page *page;
656 struct folio *folio;
657 unsigned long pfn;
658
659 if (order && order != PMD_ORDER)
660 return VM_FAULT_FALLBACK;
661
662 dma_resv_lock(obj->resv, NULL);
663
664 if (page_offset >= num_pages || drm_WARN_ON_ONCE(dev, !shmem->pages) ||
665 shmem->madv < 0)
666 goto out;
667
668 page = pages[page_offset];
669 if (drm_WARN_ON_ONCE(dev, !page))
670 goto out;
671 folio = page_folio(page);
672
673 pfn = page_to_pfn(page);
674
675 ret = try_insert_pfn(vmf, order, pfn);
676 if (ret == VM_FAULT_NOPAGE)
677 folio_mark_accessed(folio);
678
679 out:
680 dma_resv_unlock(obj->resv);
681
682 return ret;
683 }
684
drm_gem_shmem_fault(struct vm_fault * vmf)685 static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
686 {
687 return drm_gem_shmem_any_fault(vmf, 0);
688 }
689
drm_gem_shmem_vm_open(struct vm_area_struct * vma)690 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma)
691 {
692 struct drm_gem_object *obj = vma->vm_private_data;
693 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
694
695 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj));
696
697 dma_resv_lock(shmem->base.resv, NULL);
698
699 /*
700 * We should have already pinned the pages when the buffer was first
701 * mmap'd, vm_open() just grabs an additional reference for the new
702 * mm the vma is getting copied into (ie. on fork()).
703 */
704 drm_WARN_ON_ONCE(obj->dev,
705 !refcount_inc_not_zero(&shmem->pages_use_count));
706
707 dma_resv_unlock(shmem->base.resv);
708
709 drm_gem_vm_open(vma);
710 }
711
drm_gem_shmem_vm_close(struct vm_area_struct * vma)712 static void drm_gem_shmem_vm_close(struct vm_area_struct *vma)
713 {
714 struct drm_gem_object *obj = vma->vm_private_data;
715 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
716
717 dma_resv_lock(shmem->base.resv, NULL);
718 drm_gem_shmem_put_pages_locked(shmem);
719 dma_resv_unlock(shmem->base.resv);
720
721 drm_gem_vm_close(vma);
722 }
723
drm_gem_shmem_pfn_mkwrite(struct vm_fault * vmf)724 static vm_fault_t drm_gem_shmem_pfn_mkwrite(struct vm_fault *vmf)
725 {
726 drm_gem_shmem_record_mkwrite(vmf);
727 return 0;
728 }
729
730 const struct vm_operations_struct drm_gem_shmem_vm_ops = {
731 .fault = drm_gem_shmem_fault,
732 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
733 .huge_fault = drm_gem_shmem_any_fault,
734 #endif
735 .open = drm_gem_shmem_vm_open,
736 .close = drm_gem_shmem_vm_close,
737 .pfn_mkwrite = drm_gem_shmem_pfn_mkwrite,
738 };
739 EXPORT_SYMBOL_GPL(drm_gem_shmem_vm_ops);
740
741 /**
742 * drm_gem_shmem_mmap - Memory-map a shmem GEM object
743 * @shmem: shmem GEM object
744 * @vma: VMA for the area to be mapped
745 *
746 * This function implements an augmented version of the GEM DRM file mmap
747 * operation for shmem objects.
748 *
749 * Returns:
750 * 0 on success or a negative error code on failure.
751 */
drm_gem_shmem_mmap(struct drm_gem_shmem_object * shmem,struct vm_area_struct * vma)752 int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma)
753 {
754 struct drm_gem_object *obj = &shmem->base;
755 int ret;
756
757 if (drm_gem_is_imported(obj)) {
758 /* Reset both vm_ops and vm_private_data, so we don't end up with
759 * vm_ops pointing to our implementation if the dma-buf backend
760 * doesn't set those fields.
761 */
762 vma->vm_private_data = NULL;
763 vma->vm_ops = NULL;
764
765 ret = dma_buf_mmap(obj->dma_buf, vma, 0);
766
767 /* Drop the reference drm_gem_mmap_obj() acquired.*/
768 if (!ret)
769 drm_gem_object_put(obj);
770
771 return ret;
772 }
773
774 if (vma_is_cow_mapping(vma))
775 return -EINVAL;
776
777 dma_resv_lock(shmem->base.resv, NULL);
778 ret = drm_gem_shmem_get_pages_locked(shmem);
779 dma_resv_unlock(shmem->base.resv);
780
781 if (ret)
782 return ret;
783
784 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP);
785 vma->vm_page_prot = vma_get_page_prot(vma);
786 if (shmem->map_wc)
787 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
788
789 return 0;
790 }
791 EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap);
792
793 /**
794 * drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs
795 * @shmem: shmem GEM object
796 * @p: DRM printer
797 * @indent: Tab indentation level
798 */
drm_gem_shmem_print_info(const struct drm_gem_shmem_object * shmem,struct drm_printer * p,unsigned int indent)799 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem,
800 struct drm_printer *p, unsigned int indent)
801 {
802 if (drm_gem_is_imported(&shmem->base))
803 return;
804
805 drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count));
806 drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count));
807 drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count));
808 drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr);
809 }
810 EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info);
811
812 /**
813 * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned
814 * pages for a shmem GEM object
815 * @shmem: shmem GEM object
816 *
817 * This function exports a scatter/gather table suitable for PRIME usage by
818 * calling the standard DMA mapping API.
819 *
820 * Drivers who need to acquire an scatter/gather table for objects need to call
821 * drm_gem_shmem_get_pages_sgt() instead.
822 *
823 * Returns:
824 * A pointer to the scatter/gather table of pinned pages or error pointer on failure.
825 */
drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object * shmem)826 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem)
827 {
828 struct drm_gem_object *obj = &shmem->base;
829
830 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj));
831
832 return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT);
833 }
834 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table);
835
drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object * shmem)836 static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem)
837 {
838 struct drm_gem_object *obj = &shmem->base;
839 int ret;
840 struct sg_table *sgt;
841
842 if (shmem->sgt)
843 return shmem->sgt;
844
845 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj));
846
847 ret = drm_gem_shmem_get_pages_locked(shmem);
848 if (ret)
849 return ERR_PTR(ret);
850
851 sgt = drm_gem_shmem_get_sg_table(shmem);
852 if (IS_ERR(sgt)) {
853 ret = PTR_ERR(sgt);
854 goto err_put_pages;
855 }
856 /* Map the pages for use by the h/w. */
857 ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0);
858 if (ret)
859 goto err_free_sgt;
860
861 shmem->sgt = sgt;
862
863 return sgt;
864
865 err_free_sgt:
866 sg_free_table(sgt);
867 kfree(sgt);
868 err_put_pages:
869 drm_gem_shmem_put_pages_locked(shmem);
870 return ERR_PTR(ret);
871 }
872
873 /**
874 * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a
875 * scatter/gather table for a shmem GEM object.
876 * @shmem: shmem GEM object
877 *
878 * This function returns a scatter/gather table suitable for driver usage. If
879 * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg
880 * table created.
881 *
882 * This is the main function for drivers to get at backing storage, and it hides
883 * and difference between dma-buf imported and natively allocated objects.
884 * drm_gem_shmem_get_sg_table() should not be directly called by drivers.
885 *
886 * Returns:
887 * A pointer to the scatter/gather table of pinned pages or errno on failure.
888 */
drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object * shmem)889 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem)
890 {
891 int ret;
892 struct sg_table *sgt;
893
894 ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
895 if (ret)
896 return ERR_PTR(ret);
897 sgt = drm_gem_shmem_get_pages_sgt_locked(shmem);
898 dma_resv_unlock(shmem->base.resv);
899
900 return sgt;
901 }
902 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt);
903
904 /**
905 * drm_gem_shmem_prime_import_sg_table - Produce a shmem GEM object from
906 * another driver's scatter/gather table of pinned pages
907 * @dev: Device to import into
908 * @attach: DMA-BUF attachment
909 * @sgt: Scatter/gather table of pinned pages
910 *
911 * This function imports a scatter/gather table exported via DMA-BUF by
912 * another driver. Drivers that use the shmem helpers should set this as their
913 * &drm_driver.gem_prime_import_sg_table callback.
914 *
915 * Returns:
916 * A pointer to a newly created GEM object or an ERR_PTR-encoded negative
917 * error code on failure.
918 */
919 struct drm_gem_object *
drm_gem_shmem_prime_import_sg_table(struct drm_device * dev,struct dma_buf_attachment * attach,struct sg_table * sgt)920 drm_gem_shmem_prime_import_sg_table(struct drm_device *dev,
921 struct dma_buf_attachment *attach,
922 struct sg_table *sgt)
923 {
924 size_t size = PAGE_ALIGN(attach->dmabuf->size);
925 struct drm_gem_shmem_object *shmem;
926
927 shmem = __drm_gem_shmem_create(dev, size, true);
928 if (IS_ERR(shmem))
929 return ERR_CAST(shmem);
930
931 shmem->sgt = sgt;
932
933 drm_dbg_prime(dev, "size = %zu\n", size);
934
935 return &shmem->base;
936 }
937 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table);
938
939 /**
940 * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table
941 * @dev: Device to import into
942 * @dma_buf: dma-buf object to import
943 *
944 * Drivers that use the shmem helpers but also wants to import dmabuf without
945 * mapping its sg_table can use this as their &drm_driver.gem_prime_import
946 * implementation.
947 */
drm_gem_shmem_prime_import_no_map(struct drm_device * dev,struct dma_buf * dma_buf)948 struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev,
949 struct dma_buf *dma_buf)
950 {
951 struct dma_buf_attachment *attach;
952 struct drm_gem_shmem_object *shmem;
953 struct drm_gem_object *obj;
954 size_t size;
955 int ret;
956
957 if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) {
958 /*
959 * Importing dmabuf exported from our own gem increases
960 * refcount on gem itself instead of f_count of dmabuf.
961 */
962 obj = dma_buf->priv;
963 drm_gem_object_get(obj);
964 return obj;
965 }
966
967 attach = dma_buf_attach(dma_buf, dev->dev);
968 if (IS_ERR(attach))
969 return ERR_CAST(attach);
970
971 get_dma_buf(dma_buf);
972
973 size = PAGE_ALIGN(attach->dmabuf->size);
974
975 shmem = __drm_gem_shmem_create(dev, size, true);
976 if (IS_ERR(shmem)) {
977 ret = PTR_ERR(shmem);
978 goto fail_detach;
979 }
980
981 drm_dbg_prime(dev, "size = %zu\n", size);
982
983 shmem->base.import_attach = attach;
984 shmem->base.resv = dma_buf->resv;
985
986 return &shmem->base;
987
988 fail_detach:
989 dma_buf_detach(dma_buf, attach);
990 dma_buf_put(dma_buf);
991
992 return ERR_PTR(ret);
993 }
994 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map);
995
996 /*
997 * Kunit helpers
998 */
999
1000 #if IS_ENABLED(CONFIG_KUNIT)
drm_gem_shmem_vmap(struct drm_gem_shmem_object * shmem,struct iosys_map * map)1001 int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map)
1002 {
1003 struct drm_gem_object *obj = &shmem->base;
1004 int ret;
1005
1006 ret = dma_resv_lock_interruptible(obj->resv, NULL);
1007 if (ret)
1008 return ret;
1009 ret = drm_gem_shmem_vmap_locked(shmem, map);
1010 dma_resv_unlock(obj->resv);
1011
1012 return ret;
1013 }
1014 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vmap);
1015
drm_gem_shmem_vunmap(struct drm_gem_shmem_object * shmem,struct iosys_map * map)1016 void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map)
1017 {
1018 struct drm_gem_object *obj = &shmem->base;
1019
1020 dma_resv_lock_interruptible(obj->resv, NULL);
1021 drm_gem_shmem_vunmap_locked(shmem, map);
1022 dma_resv_unlock(obj->resv);
1023 }
1024 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vunmap);
1025
drm_gem_shmem_madvise(struct drm_gem_shmem_object * shmem,int madv)1026 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv)
1027 {
1028 struct drm_gem_object *obj = &shmem->base;
1029 int ret;
1030
1031 ret = dma_resv_lock_interruptible(obj->resv, NULL);
1032 if (ret)
1033 return ret;
1034 ret = drm_gem_shmem_madvise_locked(shmem, madv);
1035 dma_resv_unlock(obj->resv);
1036
1037 return ret;
1038 }
1039 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_madvise);
1040
drm_gem_shmem_purge(struct drm_gem_shmem_object * shmem)1041 int drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem)
1042 {
1043 struct drm_gem_object *obj = &shmem->base;
1044 int ret;
1045
1046 ret = dma_resv_lock_interruptible(obj->resv, NULL);
1047 if (ret)
1048 return ret;
1049 drm_gem_shmem_purge_locked(shmem);
1050 dma_resv_unlock(obj->resv);
1051
1052 return 0;
1053 }
1054 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_purge);
1055 #endif
1056
1057 MODULE_DESCRIPTION("DRM SHMEM memory-management helpers");
1058 MODULE_IMPORT_NS("DMA_BUF");
1059 MODULE_LICENSE("GPL");
1060