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 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 */ 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 * 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 */ 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 - Release resources associated with a shmem GEM object. 163 * @shmem: shmem GEM object 164 * 165 * This function cleans up the GEM object state, but does not free the memory used to store the 166 * object itself. This function is meant to be a dedicated helper for the Rust GEM bindings. 167 */ 168 void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem) 169 { 170 struct drm_gem_object *obj = &shmem->base; 171 172 if (drm_gem_is_imported(obj)) { 173 drm_prime_gem_destroy(obj, shmem->sgt); 174 } else { 175 dma_resv_lock(shmem->base.resv, NULL); 176 177 drm_WARN_ON(obj->dev, refcount_read(&shmem->vmap_use_count)); 178 179 if (shmem->sgt) { 180 dma_unmap_sgtable(obj->dev->dev, shmem->sgt, 181 DMA_BIDIRECTIONAL, 0); 182 sg_free_table(shmem->sgt); 183 kfree(shmem->sgt); 184 } 185 if (shmem->pages) 186 drm_gem_shmem_put_pages_locked(shmem); 187 188 drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_use_count)); 189 drm_WARN_ON(obj->dev, refcount_read(&shmem->pages_pin_count)); 190 191 dma_resv_unlock(shmem->base.resv); 192 } 193 194 drm_gem_object_release(obj); 195 } 196 EXPORT_SYMBOL_GPL(drm_gem_shmem_release); 197 198 /** 199 * drm_gem_shmem_free - Free resources associated with a shmem GEM object 200 * @shmem: shmem GEM object to free 201 * 202 * This function cleans up the GEM object state and frees the memory used to 203 * store the object itself. 204 */ 205 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem) 206 { 207 drm_gem_shmem_release(shmem); 208 kfree(shmem); 209 } 210 EXPORT_SYMBOL_GPL(drm_gem_shmem_free); 211 212 static int drm_gem_shmem_get_pages_locked(struct drm_gem_shmem_object *shmem) 213 { 214 struct drm_gem_object *obj = &shmem->base; 215 struct page **pages; 216 217 dma_resv_assert_held(shmem->base.resv); 218 219 if (refcount_inc_not_zero(&shmem->pages_use_count)) 220 return 0; 221 222 pages = drm_gem_get_pages(obj); 223 if (IS_ERR(pages)) { 224 drm_dbg_kms(obj->dev, "Failed to get pages (%ld)\n", 225 PTR_ERR(pages)); 226 return PTR_ERR(pages); 227 } 228 229 /* 230 * TODO: Allocating WC pages which are correctly flushed is only 231 * supported on x86. Ideal solution would be a GFP_WC flag, which also 232 * ttm_pool.c could use. 233 */ 234 #ifdef CONFIG_X86 235 if (shmem->map_wc) 236 set_pages_array_wc(pages, obj->size >> PAGE_SHIFT); 237 #endif 238 239 shmem->pages = pages; 240 241 refcount_set(&shmem->pages_use_count, 1); 242 243 return 0; 244 } 245 246 /* 247 * drm_gem_shmem_put_pages_locked - Decrease use count on the backing pages for a shmem GEM object 248 * @shmem: shmem GEM object 249 * 250 * This function decreases the use count and puts the backing pages when use drops to zero. 251 */ 252 void drm_gem_shmem_put_pages_locked(struct drm_gem_shmem_object *shmem) 253 { 254 struct drm_gem_object *obj = &shmem->base; 255 256 dma_resv_assert_held(shmem->base.resv); 257 258 if (refcount_dec_and_test(&shmem->pages_use_count)) { 259 #ifdef CONFIG_X86 260 if (shmem->map_wc) 261 set_pages_array_wb(shmem->pages, obj->size >> PAGE_SHIFT); 262 #endif 263 264 drm_gem_put_pages(obj, shmem->pages, 265 shmem->pages_mark_dirty_on_put, 266 shmem->pages_mark_accessed_on_put); 267 shmem->pages = NULL; 268 shmem->pages_mark_accessed_on_put = false; 269 shmem->pages_mark_dirty_on_put = false; 270 } 271 } 272 EXPORT_SYMBOL_GPL(drm_gem_shmem_put_pages_locked); 273 274 int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem) 275 { 276 int ret; 277 278 dma_resv_assert_held(shmem->base.resv); 279 280 drm_WARN_ON(shmem->base.dev, drm_gem_is_imported(&shmem->base)); 281 282 if (refcount_inc_not_zero(&shmem->pages_pin_count)) 283 return 0; 284 285 ret = drm_gem_shmem_get_pages_locked(shmem); 286 if (!ret) 287 refcount_set(&shmem->pages_pin_count, 1); 288 289 return ret; 290 } 291 EXPORT_SYMBOL(drm_gem_shmem_pin_locked); 292 293 void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem) 294 { 295 dma_resv_assert_held(shmem->base.resv); 296 297 if (refcount_dec_and_test(&shmem->pages_pin_count)) 298 drm_gem_shmem_put_pages_locked(shmem); 299 } 300 EXPORT_SYMBOL(drm_gem_shmem_unpin_locked); 301 302 /** 303 * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object 304 * @shmem: shmem GEM object 305 * 306 * This function makes sure the backing pages are pinned in memory while the 307 * buffer is exported. 308 * 309 * Returns: 310 * 0 on success or a negative error code on failure. 311 */ 312 int drm_gem_shmem_pin(struct drm_gem_shmem_object *shmem) 313 { 314 struct drm_gem_object *obj = &shmem->base; 315 int ret; 316 317 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 318 319 if (refcount_inc_not_zero(&shmem->pages_pin_count)) 320 return 0; 321 322 ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); 323 if (ret) 324 return ret; 325 ret = drm_gem_shmem_pin_locked(shmem); 326 dma_resv_unlock(shmem->base.resv); 327 328 return ret; 329 } 330 EXPORT_SYMBOL_GPL(drm_gem_shmem_pin); 331 332 /** 333 * drm_gem_shmem_unpin - Unpin backing pages for a shmem GEM object 334 * @shmem: shmem GEM object 335 * 336 * This function removes the requirement that the backing pages are pinned in 337 * memory. 338 */ 339 void drm_gem_shmem_unpin(struct drm_gem_shmem_object *shmem) 340 { 341 struct drm_gem_object *obj = &shmem->base; 342 343 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 344 345 if (refcount_dec_not_one(&shmem->pages_pin_count)) 346 return; 347 348 dma_resv_lock(shmem->base.resv, NULL); 349 drm_gem_shmem_unpin_locked(shmem); 350 dma_resv_unlock(shmem->base.resv); 351 } 352 EXPORT_SYMBOL_GPL(drm_gem_shmem_unpin); 353 354 /* 355 * drm_gem_shmem_vmap_locked - Create a virtual mapping for a shmem GEM object 356 * @shmem: shmem GEM object 357 * @map: Returns the kernel virtual address of the SHMEM GEM object's backing 358 * store. 359 * 360 * This function makes sure that a contiguous kernel virtual address mapping 361 * exists for the buffer backing the shmem GEM object. It hides the differences 362 * between dma-buf imported and natively allocated objects. 363 * 364 * Acquired mappings should be cleaned up by calling drm_gem_shmem_vunmap_locked(). 365 * 366 * Returns: 367 * 0 on success or a negative error code on failure. 368 */ 369 int drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem, 370 struct iosys_map *map) 371 { 372 struct drm_gem_object *obj = &shmem->base; 373 int ret = 0; 374 375 dma_resv_assert_held(obj->resv); 376 377 if (drm_gem_is_imported(obj)) { 378 ret = dma_buf_vmap(obj->import_attach->dmabuf, map); 379 } else { 380 pgprot_t prot = PAGE_KERNEL; 381 382 dma_resv_assert_held(shmem->base.resv); 383 384 if (refcount_inc_not_zero(&shmem->vmap_use_count)) { 385 iosys_map_set_vaddr(map, shmem->vaddr); 386 return 0; 387 } 388 389 ret = drm_gem_shmem_pin_locked(shmem); 390 if (ret) 391 return ret; 392 393 if (shmem->map_wc) 394 prot = pgprot_writecombine(prot); 395 shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, 396 VM_MAP, prot); 397 if (!shmem->vaddr) { 398 ret = -ENOMEM; 399 } else { 400 iosys_map_set_vaddr(map, shmem->vaddr); 401 refcount_set(&shmem->vmap_use_count, 1); 402 shmem->pages_mark_accessed_on_put = true; 403 shmem->pages_mark_dirty_on_put = true; 404 } 405 } 406 407 if (ret) { 408 drm_dbg_kms(obj->dev, "Failed to vmap pages, error %d\n", ret); 409 goto err_put_pages; 410 } 411 412 return 0; 413 414 err_put_pages: 415 if (!drm_gem_is_imported(obj)) 416 drm_gem_shmem_unpin_locked(shmem); 417 418 return ret; 419 } 420 EXPORT_SYMBOL_GPL(drm_gem_shmem_vmap_locked); 421 422 /* 423 * drm_gem_shmem_vunmap_locked - Unmap a virtual mapping for a shmem GEM object 424 * @shmem: shmem GEM object 425 * @map: Kernel virtual address where the SHMEM GEM object was mapped 426 * 427 * This function cleans up a kernel virtual address mapping acquired by 428 * drm_gem_shmem_vmap_locked(). The mapping is only removed when the use count 429 * drops to zero. 430 * 431 * This function hides the differences between dma-buf imported and natively 432 * allocated objects. 433 */ 434 void drm_gem_shmem_vunmap_locked(struct drm_gem_shmem_object *shmem, 435 struct iosys_map *map) 436 { 437 struct drm_gem_object *obj = &shmem->base; 438 439 dma_resv_assert_held(obj->resv); 440 441 if (drm_gem_is_imported(obj)) { 442 dma_buf_vunmap(obj->import_attach->dmabuf, map); 443 } else { 444 dma_resv_assert_held(shmem->base.resv); 445 446 if (refcount_dec_and_test(&shmem->vmap_use_count)) { 447 vunmap(shmem->vaddr); 448 shmem->vaddr = NULL; 449 450 drm_gem_shmem_unpin_locked(shmem); 451 } 452 } 453 } 454 EXPORT_SYMBOL_GPL(drm_gem_shmem_vunmap_locked); 455 456 static int 457 drm_gem_shmem_create_with_handle(struct drm_file *file_priv, 458 struct drm_device *dev, size_t size, 459 uint32_t *handle) 460 { 461 struct drm_gem_shmem_object *shmem; 462 int ret; 463 464 shmem = drm_gem_shmem_create(dev, size); 465 if (IS_ERR(shmem)) 466 return PTR_ERR(shmem); 467 468 /* 469 * Allocate an id of idr table where the obj is registered 470 * and handle has the id what user can see. 471 */ 472 ret = drm_gem_handle_create(file_priv, &shmem->base, handle); 473 /* drop reference from allocate - handle holds it now. */ 474 drm_gem_object_put(&shmem->base); 475 476 return ret; 477 } 478 479 /* Update madvise status, returns true if not purged, else 480 * false or -errno. 481 */ 482 int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) 483 { 484 dma_resv_assert_held(shmem->base.resv); 485 486 if (shmem->madv >= 0) 487 shmem->madv = madv; 488 489 madv = shmem->madv; 490 491 return (madv >= 0); 492 } 493 EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); 494 495 void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) 496 { 497 struct drm_gem_object *obj = &shmem->base; 498 struct drm_device *dev = obj->dev; 499 500 dma_resv_assert_held(shmem->base.resv); 501 502 drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); 503 504 dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0); 505 sg_free_table(shmem->sgt); 506 kfree(shmem->sgt); 507 shmem->sgt = NULL; 508 509 drm_gem_shmem_put_pages_locked(shmem); 510 511 shmem->madv = -1; 512 513 drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping); 514 drm_gem_free_mmap_offset(obj); 515 516 /* Our goal here is to return as much of the memory as 517 * is possible back to the system as we are called from OOM. 518 * To do this we must instruct the shmfs to drop all of its 519 * backing pages, *now*. 520 */ 521 shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1); 522 523 invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); 524 } 525 EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); 526 527 /** 528 * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object 529 * @file: DRM file structure to create the dumb buffer for 530 * @dev: DRM device 531 * @args: IOCTL data 532 * 533 * This function computes the pitch of the dumb buffer and rounds it up to an 534 * integer number of bytes per pixel. Drivers for hardware that doesn't have 535 * any additional restrictions on the pitch can directly use this function as 536 * their &drm_driver.dumb_create callback. 537 * 538 * For hardware with additional restrictions, drivers can adjust the fields 539 * set up by userspace before calling into this function. 540 * 541 * Returns: 542 * 0 on success or a negative error code on failure. 543 */ 544 int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev, 545 struct drm_mode_create_dumb *args) 546 { 547 int ret; 548 549 ret = drm_mode_size_dumb(dev, args, 0, 0); 550 if (ret) 551 return ret; 552 553 return drm_gem_shmem_create_with_handle(file, dev, args->size, &args->handle); 554 } 555 EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create); 556 557 static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order, 558 unsigned long pfn) 559 { 560 if (!order) { 561 return vmf_insert_pfn(vmf->vma, vmf->address, pfn); 562 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 563 } else if (order == PMD_ORDER) { 564 unsigned long paddr = pfn << PAGE_SHIFT; 565 bool aligned = (vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK); 566 567 if (aligned && 568 folio_test_pmd_mappable(page_folio(pfn_to_page(pfn)))) { 569 pfn &= PMD_MASK >> PAGE_SHIFT; 570 return vmf_insert_pfn_pmd(vmf, pfn, false); 571 } 572 #endif 573 } 574 return VM_FAULT_FALLBACK; 575 } 576 577 static vm_fault_t drm_gem_shmem_any_fault(struct vm_fault *vmf, unsigned int order) 578 { 579 struct vm_area_struct *vma = vmf->vma; 580 struct drm_gem_object *obj = vma->vm_private_data; 581 struct drm_device *dev = obj->dev; 582 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 583 loff_t num_pages = obj->size >> PAGE_SHIFT; 584 vm_fault_t ret = VM_FAULT_SIGBUS; 585 struct page **pages = shmem->pages; 586 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ 587 struct page *page; 588 struct folio *folio; 589 unsigned long pfn; 590 591 if (order && order != PMD_ORDER) 592 return VM_FAULT_FALLBACK; 593 594 dma_resv_lock(obj->resv, NULL); 595 596 if (page_offset >= num_pages || drm_WARN_ON_ONCE(dev, !shmem->pages) || 597 shmem->madv < 0) 598 goto out; 599 600 page = pages[page_offset]; 601 if (drm_WARN_ON_ONCE(dev, !page)) 602 goto out; 603 folio = page_folio(page); 604 605 pfn = page_to_pfn(page); 606 607 ret = try_insert_pfn(vmf, order, pfn); 608 if (ret == VM_FAULT_NOPAGE) 609 folio_mark_accessed(folio); 610 611 out: 612 dma_resv_unlock(obj->resv); 613 614 return ret; 615 } 616 617 static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) 618 { 619 return drm_gem_shmem_any_fault(vmf, 0); 620 } 621 622 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) 623 { 624 struct drm_gem_object *obj = vma->vm_private_data; 625 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 626 627 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 628 629 dma_resv_lock(shmem->base.resv, NULL); 630 631 /* 632 * We should have already pinned the pages when the buffer was first 633 * mmap'd, vm_open() just grabs an additional reference for the new 634 * mm the vma is getting copied into (ie. on fork()). 635 */ 636 drm_WARN_ON_ONCE(obj->dev, 637 !refcount_inc_not_zero(&shmem->pages_use_count)); 638 639 dma_resv_unlock(shmem->base.resv); 640 641 drm_gem_vm_open(vma); 642 } 643 644 static void drm_gem_shmem_vm_close(struct vm_area_struct *vma) 645 { 646 struct drm_gem_object *obj = vma->vm_private_data; 647 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 648 649 dma_resv_lock(shmem->base.resv, NULL); 650 drm_gem_shmem_put_pages_locked(shmem); 651 dma_resv_unlock(shmem->base.resv); 652 653 drm_gem_vm_close(vma); 654 } 655 656 static vm_fault_t drm_gem_shmem_pfn_mkwrite(struct vm_fault *vmf) 657 { 658 struct vm_area_struct *vma = vmf->vma; 659 struct drm_gem_object *obj = vma->vm_private_data; 660 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 661 loff_t num_pages = obj->size >> PAGE_SHIFT; 662 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ 663 664 if (drm_WARN_ON(obj->dev, !shmem->pages || page_offset >= num_pages)) 665 return VM_FAULT_SIGBUS; 666 667 file_update_time(vma->vm_file); 668 669 folio_mark_dirty(page_folio(shmem->pages[page_offset])); 670 671 return 0; 672 } 673 674 const struct vm_operations_struct drm_gem_shmem_vm_ops = { 675 .fault = drm_gem_shmem_fault, 676 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 677 .huge_fault = drm_gem_shmem_any_fault, 678 #endif 679 .open = drm_gem_shmem_vm_open, 680 .close = drm_gem_shmem_vm_close, 681 .pfn_mkwrite = drm_gem_shmem_pfn_mkwrite, 682 }; 683 EXPORT_SYMBOL_GPL(drm_gem_shmem_vm_ops); 684 685 /** 686 * drm_gem_shmem_mmap - Memory-map a shmem GEM object 687 * @shmem: shmem GEM object 688 * @vma: VMA for the area to be mapped 689 * 690 * This function implements an augmented version of the GEM DRM file mmap 691 * operation for shmem objects. 692 * 693 * Returns: 694 * 0 on success or a negative error code on failure. 695 */ 696 int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma) 697 { 698 struct drm_gem_object *obj = &shmem->base; 699 int ret; 700 701 if (drm_gem_is_imported(obj)) { 702 /* Reset both vm_ops and vm_private_data, so we don't end up with 703 * vm_ops pointing to our implementation if the dma-buf backend 704 * doesn't set those fields. 705 */ 706 vma->vm_private_data = NULL; 707 vma->vm_ops = NULL; 708 709 ret = dma_buf_mmap(obj->dma_buf, vma, 0); 710 711 /* Drop the reference drm_gem_mmap_obj() acquired.*/ 712 if (!ret) 713 drm_gem_object_put(obj); 714 715 return ret; 716 } 717 718 if (is_cow_mapping(vma->vm_flags)) 719 return -EINVAL; 720 721 dma_resv_lock(shmem->base.resv, NULL); 722 ret = drm_gem_shmem_get_pages_locked(shmem); 723 dma_resv_unlock(shmem->base.resv); 724 725 if (ret) 726 return ret; 727 728 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); 729 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 730 if (shmem->map_wc) 731 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 732 733 return 0; 734 } 735 EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap); 736 737 /** 738 * drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs 739 * @shmem: shmem GEM object 740 * @p: DRM printer 741 * @indent: Tab indentation level 742 */ 743 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, 744 struct drm_printer *p, unsigned int indent) 745 { 746 if (drm_gem_is_imported(&shmem->base)) 747 return; 748 749 drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); 750 drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); 751 drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); 752 drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); 753 } 754 EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); 755 756 /** 757 * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned 758 * pages for a shmem GEM object 759 * @shmem: shmem GEM object 760 * 761 * This function exports a scatter/gather table suitable for PRIME usage by 762 * calling the standard DMA mapping API. 763 * 764 * Drivers who need to acquire an scatter/gather table for objects need to call 765 * drm_gem_shmem_get_pages_sgt() instead. 766 * 767 * Returns: 768 * A pointer to the scatter/gather table of pinned pages or error pointer on failure. 769 */ 770 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) 771 { 772 struct drm_gem_object *obj = &shmem->base; 773 774 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 775 776 return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT); 777 } 778 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); 779 780 static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) 781 { 782 struct drm_gem_object *obj = &shmem->base; 783 int ret; 784 struct sg_table *sgt; 785 786 if (shmem->sgt) 787 return shmem->sgt; 788 789 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 790 791 ret = drm_gem_shmem_get_pages_locked(shmem); 792 if (ret) 793 return ERR_PTR(ret); 794 795 sgt = drm_gem_shmem_get_sg_table(shmem); 796 if (IS_ERR(sgt)) { 797 ret = PTR_ERR(sgt); 798 goto err_put_pages; 799 } 800 /* Map the pages for use by the h/w. */ 801 ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0); 802 if (ret) 803 goto err_free_sgt; 804 805 shmem->sgt = sgt; 806 807 return sgt; 808 809 err_free_sgt: 810 sg_free_table(sgt); 811 kfree(sgt); 812 err_put_pages: 813 drm_gem_shmem_put_pages_locked(shmem); 814 return ERR_PTR(ret); 815 } 816 817 /** 818 * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a 819 * scatter/gather table for a shmem GEM object. 820 * @shmem: shmem GEM object 821 * 822 * This function returns a scatter/gather table suitable for driver usage. If 823 * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg 824 * table created. 825 * 826 * This is the main function for drivers to get at backing storage, and it hides 827 * and difference between dma-buf imported and natively allocated objects. 828 * drm_gem_shmem_get_sg_table() should not be directly called by drivers. 829 * 830 * Returns: 831 * A pointer to the scatter/gather table of pinned pages or errno on failure. 832 */ 833 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) 834 { 835 int ret; 836 struct sg_table *sgt; 837 838 ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); 839 if (ret) 840 return ERR_PTR(ret); 841 sgt = drm_gem_shmem_get_pages_sgt_locked(shmem); 842 dma_resv_unlock(shmem->base.resv); 843 844 return sgt; 845 } 846 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt); 847 848 /** 849 * drm_gem_shmem_prime_import_sg_table - Produce a shmem GEM object from 850 * another driver's scatter/gather table of pinned pages 851 * @dev: Device to import into 852 * @attach: DMA-BUF attachment 853 * @sgt: Scatter/gather table of pinned pages 854 * 855 * This function imports a scatter/gather table exported via DMA-BUF by 856 * another driver. Drivers that use the shmem helpers should set this as their 857 * &drm_driver.gem_prime_import_sg_table callback. 858 * 859 * Returns: 860 * A pointer to a newly created GEM object or an ERR_PTR-encoded negative 861 * error code on failure. 862 */ 863 struct drm_gem_object * 864 drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, 865 struct dma_buf_attachment *attach, 866 struct sg_table *sgt) 867 { 868 size_t size = PAGE_ALIGN(attach->dmabuf->size); 869 struct drm_gem_shmem_object *shmem; 870 871 shmem = __drm_gem_shmem_create(dev, size, true); 872 if (IS_ERR(shmem)) 873 return ERR_CAST(shmem); 874 875 shmem->sgt = sgt; 876 877 drm_dbg_prime(dev, "size = %zu\n", size); 878 879 return &shmem->base; 880 } 881 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table); 882 883 /** 884 * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table 885 * @dev: Device to import into 886 * @dma_buf: dma-buf object to import 887 * 888 * Drivers that use the shmem helpers but also wants to import dmabuf without 889 * mapping its sg_table can use this as their &drm_driver.gem_prime_import 890 * implementation. 891 */ 892 struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev, 893 struct dma_buf *dma_buf) 894 { 895 struct dma_buf_attachment *attach; 896 struct drm_gem_shmem_object *shmem; 897 struct drm_gem_object *obj; 898 size_t size; 899 int ret; 900 901 if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) { 902 /* 903 * Importing dmabuf exported from our own gem increases 904 * refcount on gem itself instead of f_count of dmabuf. 905 */ 906 obj = dma_buf->priv; 907 drm_gem_object_get(obj); 908 return obj; 909 } 910 911 attach = dma_buf_attach(dma_buf, dev->dev); 912 if (IS_ERR(attach)) 913 return ERR_CAST(attach); 914 915 get_dma_buf(dma_buf); 916 917 size = PAGE_ALIGN(attach->dmabuf->size); 918 919 shmem = __drm_gem_shmem_create(dev, size, true); 920 if (IS_ERR(shmem)) { 921 ret = PTR_ERR(shmem); 922 goto fail_detach; 923 } 924 925 drm_dbg_prime(dev, "size = %zu\n", size); 926 927 shmem->base.import_attach = attach; 928 shmem->base.resv = dma_buf->resv; 929 930 return &shmem->base; 931 932 fail_detach: 933 dma_buf_detach(dma_buf, attach); 934 dma_buf_put(dma_buf); 935 936 return ERR_PTR(ret); 937 } 938 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map); 939 940 /* 941 * Kunit helpers 942 */ 943 944 #if IS_ENABLED(CONFIG_KUNIT) 945 int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map) 946 { 947 struct drm_gem_object *obj = &shmem->base; 948 int ret; 949 950 ret = dma_resv_lock_interruptible(obj->resv, NULL); 951 if (ret) 952 return ret; 953 ret = drm_gem_shmem_vmap_locked(shmem, map); 954 dma_resv_unlock(obj->resv); 955 956 return ret; 957 } 958 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vmap); 959 960 void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map) 961 { 962 struct drm_gem_object *obj = &shmem->base; 963 964 dma_resv_lock_interruptible(obj->resv, NULL); 965 drm_gem_shmem_vunmap_locked(shmem, map); 966 dma_resv_unlock(obj->resv); 967 } 968 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vunmap); 969 970 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) 971 { 972 struct drm_gem_object *obj = &shmem->base; 973 int ret; 974 975 ret = dma_resv_lock_interruptible(obj->resv, NULL); 976 if (ret) 977 return ret; 978 ret = drm_gem_shmem_madvise_locked(shmem, madv); 979 dma_resv_unlock(obj->resv); 980 981 return ret; 982 } 983 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_madvise); 984 985 int drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) 986 { 987 struct drm_gem_object *obj = &shmem->base; 988 int ret; 989 990 ret = dma_resv_lock_interruptible(obj->resv, NULL); 991 if (ret) 992 return ret; 993 drm_gem_shmem_purge_locked(shmem); 994 dma_resv_unlock(obj->resv); 995 996 return 0; 997 } 998 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_purge); 999 #endif 1000 1001 MODULE_DESCRIPTION("DRM SHMEM memory-management helpers"); 1002 MODULE_IMPORT_NS("DMA_BUF"); 1003 MODULE_LICENSE("GPL"); 1004