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_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 */ 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 */ 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 */ 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 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 */ 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 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 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 */ 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 */ 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 */ 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 */ 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 static int 477 drm_gem_shmem_create_with_handle(struct drm_file *file_priv, 478 struct drm_device *dev, size_t size, 479 uint32_t *handle) 480 { 481 struct drm_gem_shmem_object *shmem; 482 int ret; 483 484 shmem = drm_gem_shmem_create(dev, size); 485 if (IS_ERR(shmem)) 486 return PTR_ERR(shmem); 487 488 /* 489 * Allocate an id of idr table where the obj is registered 490 * and handle has the id what user can see. 491 */ 492 ret = drm_gem_handle_create(file_priv, &shmem->base, handle); 493 /* drop reference from allocate - handle holds it now. */ 494 drm_gem_object_put(&shmem->base); 495 496 return ret; 497 } 498 499 /* Update madvise status, returns true if not purged, else 500 * false or -errno. 501 */ 502 int drm_gem_shmem_madvise_locked(struct drm_gem_shmem_object *shmem, int madv) 503 { 504 dma_resv_assert_held(shmem->base.resv); 505 506 if (shmem->madv >= 0) 507 shmem->madv = madv; 508 509 madv = shmem->madv; 510 511 return (madv >= 0); 512 } 513 EXPORT_SYMBOL_GPL(drm_gem_shmem_madvise_locked); 514 515 void drm_gem_shmem_purge_locked(struct drm_gem_shmem_object *shmem) 516 { 517 struct drm_gem_object *obj = &shmem->base; 518 struct drm_device *dev = obj->dev; 519 520 dma_resv_assert_held(shmem->base.resv); 521 522 drm_WARN_ON(obj->dev, !drm_gem_shmem_is_purgeable(shmem)); 523 524 dma_unmap_sgtable(dev->dev, shmem->sgt, DMA_BIDIRECTIONAL, 0); 525 sg_free_table(shmem->sgt); 526 kfree(shmem->sgt); 527 shmem->sgt = NULL; 528 529 drm_gem_shmem_put_pages_locked(shmem); 530 531 shmem->madv = -1; 532 533 drm_vma_node_unmap(&obj->vma_node, dev->anon_inode->i_mapping); 534 drm_gem_free_mmap_offset(obj); 535 536 /* Our goal here is to return as much of the memory as 537 * is possible back to the system as we are called from OOM. 538 * To do this we must instruct the shmfs to drop all of its 539 * backing pages, *now*. 540 */ 541 shmem_truncate_range(file_inode(obj->filp), 0, (loff_t)-1); 542 543 invalidate_mapping_pages(file_inode(obj->filp)->i_mapping, 0, (loff_t)-1); 544 } 545 EXPORT_SYMBOL_GPL(drm_gem_shmem_purge_locked); 546 547 /** 548 * drm_gem_shmem_dumb_create - Create a dumb shmem buffer object 549 * @file: DRM file structure to create the dumb buffer for 550 * @dev: DRM device 551 * @args: IOCTL data 552 * 553 * This function computes the pitch of the dumb buffer and rounds it up to an 554 * integer number of bytes per pixel. Drivers for hardware that doesn't have 555 * any additional restrictions on the pitch can directly use this function as 556 * their &drm_driver.dumb_create callback. 557 * 558 * For hardware with additional restrictions, drivers can adjust the fields 559 * set up by userspace before calling into this function. 560 * 561 * Returns: 562 * 0 on success or a negative error code on failure. 563 */ 564 int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev, 565 struct drm_mode_create_dumb *args) 566 { 567 int ret; 568 569 ret = drm_mode_size_dumb(dev, args, 0, 0); 570 if (ret) 571 return ret; 572 573 return drm_gem_shmem_create_with_handle(file, dev, args->size, &args->handle); 574 } 575 EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create); 576 577 static void drm_gem_shmem_record_mkwrite(struct vm_fault *vmf) 578 { 579 struct vm_area_struct *vma = vmf->vma; 580 struct drm_gem_object *obj = vma->vm_private_data; 581 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 582 loff_t num_pages = obj->size >> PAGE_SHIFT; 583 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ 584 585 if (drm_WARN_ON(obj->dev, !shmem->pages || page_offset >= num_pages)) 586 return; 587 588 file_update_time(vma->vm_file); 589 folio_mark_dirty(page_folio(shmem->pages[page_offset])); 590 } 591 592 static vm_fault_t try_insert_pfn(struct vm_fault *vmf, unsigned int order, 593 unsigned long pfn) 594 { 595 if (!order) { 596 return vmf_insert_pfn(vmf->vma, vmf->address, pfn); 597 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 598 } else if (order == PMD_ORDER) { 599 unsigned long paddr = pfn << PAGE_SHIFT; 600 bool aligned = (vmf->address & ~PMD_MASK) == (paddr & ~PMD_MASK); 601 602 if (aligned && 603 folio_test_pmd_mappable(page_folio(pfn_to_page(pfn)))) { 604 vm_fault_t ret; 605 606 pfn &= PMD_MASK >> PAGE_SHIFT; 607 608 /* Unlike PTEs which are automatically upgraded to 609 * writeable entries, the PMD upgrades go through 610 * .huge_fault(). Make sure we pass the "write" info 611 * along in that case. 612 * This also means we have to record the write fault 613 * here, instead of in .pfn_mkwrite(). 614 */ 615 ret = vmf_insert_pfn_pmd(vmf, pfn, 616 vmf->flags & FAULT_FLAG_WRITE); 617 if (ret == VM_FAULT_NOPAGE && (vmf->flags & FAULT_FLAG_WRITE)) 618 drm_gem_shmem_record_mkwrite(vmf); 619 620 return ret; 621 } 622 #endif 623 } 624 return VM_FAULT_FALLBACK; 625 } 626 627 static vm_fault_t drm_gem_shmem_any_fault(struct vm_fault *vmf, unsigned int order) 628 { 629 struct vm_area_struct *vma = vmf->vma; 630 struct drm_gem_object *obj = vma->vm_private_data; 631 struct drm_device *dev = obj->dev; 632 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 633 loff_t num_pages = obj->size >> PAGE_SHIFT; 634 vm_fault_t ret = VM_FAULT_SIGBUS; 635 struct page **pages = shmem->pages; 636 pgoff_t page_offset = vmf->pgoff - vma->vm_pgoff; /* page offset within VMA */ 637 struct page *page; 638 struct folio *folio; 639 unsigned long pfn; 640 641 if (order && order != PMD_ORDER) 642 return VM_FAULT_FALLBACK; 643 644 dma_resv_lock(obj->resv, NULL); 645 646 if (page_offset >= num_pages || drm_WARN_ON_ONCE(dev, !shmem->pages) || 647 shmem->madv < 0) 648 goto out; 649 650 page = pages[page_offset]; 651 if (drm_WARN_ON_ONCE(dev, !page)) 652 goto out; 653 folio = page_folio(page); 654 655 pfn = page_to_pfn(page); 656 657 ret = try_insert_pfn(vmf, order, pfn); 658 if (ret == VM_FAULT_NOPAGE) 659 folio_mark_accessed(folio); 660 661 out: 662 dma_resv_unlock(obj->resv); 663 664 return ret; 665 } 666 667 static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) 668 { 669 return drm_gem_shmem_any_fault(vmf, 0); 670 } 671 672 static void drm_gem_shmem_vm_open(struct vm_area_struct *vma) 673 { 674 struct drm_gem_object *obj = vma->vm_private_data; 675 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 676 677 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 678 679 dma_resv_lock(shmem->base.resv, NULL); 680 681 /* 682 * We should have already pinned the pages when the buffer was first 683 * mmap'd, vm_open() just grabs an additional reference for the new 684 * mm the vma is getting copied into (ie. on fork()). 685 */ 686 drm_WARN_ON_ONCE(obj->dev, 687 !refcount_inc_not_zero(&shmem->pages_use_count)); 688 689 dma_resv_unlock(shmem->base.resv); 690 691 drm_gem_vm_open(vma); 692 } 693 694 static void drm_gem_shmem_vm_close(struct vm_area_struct *vma) 695 { 696 struct drm_gem_object *obj = vma->vm_private_data; 697 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj); 698 699 dma_resv_lock(shmem->base.resv, NULL); 700 drm_gem_shmem_put_pages_locked(shmem); 701 dma_resv_unlock(shmem->base.resv); 702 703 drm_gem_vm_close(vma); 704 } 705 706 static vm_fault_t drm_gem_shmem_pfn_mkwrite(struct vm_fault *vmf) 707 { 708 drm_gem_shmem_record_mkwrite(vmf); 709 return 0; 710 } 711 712 const struct vm_operations_struct drm_gem_shmem_vm_ops = { 713 .fault = drm_gem_shmem_fault, 714 #ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP 715 .huge_fault = drm_gem_shmem_any_fault, 716 #endif 717 .open = drm_gem_shmem_vm_open, 718 .close = drm_gem_shmem_vm_close, 719 .pfn_mkwrite = drm_gem_shmem_pfn_mkwrite, 720 }; 721 EXPORT_SYMBOL_GPL(drm_gem_shmem_vm_ops); 722 723 /** 724 * drm_gem_shmem_mmap - Memory-map a shmem GEM object 725 * @shmem: shmem GEM object 726 * @vma: VMA for the area to be mapped 727 * 728 * This function implements an augmented version of the GEM DRM file mmap 729 * operation for shmem objects. 730 * 731 * Returns: 732 * 0 on success or a negative error code on failure. 733 */ 734 int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct vm_area_struct *vma) 735 { 736 struct drm_gem_object *obj = &shmem->base; 737 int ret; 738 739 if (drm_gem_is_imported(obj)) { 740 /* Reset both vm_ops and vm_private_data, so we don't end up with 741 * vm_ops pointing to our implementation if the dma-buf backend 742 * doesn't set those fields. 743 */ 744 vma->vm_private_data = NULL; 745 vma->vm_ops = NULL; 746 747 ret = dma_buf_mmap(obj->dma_buf, vma, 0); 748 749 /* Drop the reference drm_gem_mmap_obj() acquired.*/ 750 if (!ret) 751 drm_gem_object_put(obj); 752 753 return ret; 754 } 755 756 if (is_cow_mapping(vma->vm_flags)) 757 return -EINVAL; 758 759 dma_resv_lock(shmem->base.resv, NULL); 760 ret = drm_gem_shmem_get_pages_locked(shmem); 761 dma_resv_unlock(shmem->base.resv); 762 763 if (ret) 764 return ret; 765 766 vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP); 767 vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); 768 if (shmem->map_wc) 769 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 770 771 return 0; 772 } 773 EXPORT_SYMBOL_GPL(drm_gem_shmem_mmap); 774 775 /** 776 * drm_gem_shmem_print_info() - Print &drm_gem_shmem_object info for debugfs 777 * @shmem: shmem GEM object 778 * @p: DRM printer 779 * @indent: Tab indentation level 780 */ 781 void drm_gem_shmem_print_info(const struct drm_gem_shmem_object *shmem, 782 struct drm_printer *p, unsigned int indent) 783 { 784 if (drm_gem_is_imported(&shmem->base)) 785 return; 786 787 drm_printf_indent(p, indent, "pages_pin_count=%u\n", refcount_read(&shmem->pages_pin_count)); 788 drm_printf_indent(p, indent, "pages_use_count=%u\n", refcount_read(&shmem->pages_use_count)); 789 drm_printf_indent(p, indent, "vmap_use_count=%u\n", refcount_read(&shmem->vmap_use_count)); 790 drm_printf_indent(p, indent, "vaddr=%p\n", shmem->vaddr); 791 } 792 EXPORT_SYMBOL_GPL(drm_gem_shmem_print_info); 793 794 /** 795 * drm_gem_shmem_get_sg_table - Provide a scatter/gather table of pinned 796 * pages for a shmem GEM object 797 * @shmem: shmem GEM object 798 * 799 * This function exports a scatter/gather table suitable for PRIME usage by 800 * calling the standard DMA mapping API. 801 * 802 * Drivers who need to acquire an scatter/gather table for objects need to call 803 * drm_gem_shmem_get_pages_sgt() instead. 804 * 805 * Returns: 806 * A pointer to the scatter/gather table of pinned pages or error pointer on failure. 807 */ 808 struct sg_table *drm_gem_shmem_get_sg_table(struct drm_gem_shmem_object *shmem) 809 { 810 struct drm_gem_object *obj = &shmem->base; 811 812 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 813 814 return drm_prime_pages_to_sg(obj->dev, shmem->pages, obj->size >> PAGE_SHIFT); 815 } 816 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_sg_table); 817 818 static struct sg_table *drm_gem_shmem_get_pages_sgt_locked(struct drm_gem_shmem_object *shmem) 819 { 820 struct drm_gem_object *obj = &shmem->base; 821 int ret; 822 struct sg_table *sgt; 823 824 if (shmem->sgt) 825 return shmem->sgt; 826 827 drm_WARN_ON(obj->dev, drm_gem_is_imported(obj)); 828 829 ret = drm_gem_shmem_get_pages_locked(shmem); 830 if (ret) 831 return ERR_PTR(ret); 832 833 sgt = drm_gem_shmem_get_sg_table(shmem); 834 if (IS_ERR(sgt)) { 835 ret = PTR_ERR(sgt); 836 goto err_put_pages; 837 } 838 /* Map the pages for use by the h/w. */ 839 ret = dma_map_sgtable(obj->dev->dev, sgt, DMA_BIDIRECTIONAL, 0); 840 if (ret) 841 goto err_free_sgt; 842 843 shmem->sgt = sgt; 844 845 return sgt; 846 847 err_free_sgt: 848 sg_free_table(sgt); 849 kfree(sgt); 850 err_put_pages: 851 drm_gem_shmem_put_pages_locked(shmem); 852 return ERR_PTR(ret); 853 } 854 855 /** 856 * drm_gem_shmem_get_pages_sgt - Pin pages, dma map them, and return a 857 * scatter/gather table for a shmem GEM object. 858 * @shmem: shmem GEM object 859 * 860 * This function returns a scatter/gather table suitable for driver usage. If 861 * the sg table doesn't exist, the pages are pinned, dma-mapped, and a sg 862 * table created. 863 * 864 * This is the main function for drivers to get at backing storage, and it hides 865 * and difference between dma-buf imported and natively allocated objects. 866 * drm_gem_shmem_get_sg_table() should not be directly called by drivers. 867 * 868 * Returns: 869 * A pointer to the scatter/gather table of pinned pages or errno on failure. 870 */ 871 struct sg_table *drm_gem_shmem_get_pages_sgt(struct drm_gem_shmem_object *shmem) 872 { 873 int ret; 874 struct sg_table *sgt; 875 876 ret = dma_resv_lock_interruptible(shmem->base.resv, NULL); 877 if (ret) 878 return ERR_PTR(ret); 879 sgt = drm_gem_shmem_get_pages_sgt_locked(shmem); 880 dma_resv_unlock(shmem->base.resv); 881 882 return sgt; 883 } 884 EXPORT_SYMBOL_GPL(drm_gem_shmem_get_pages_sgt); 885 886 /** 887 * drm_gem_shmem_prime_import_sg_table - Produce a shmem GEM object from 888 * another driver's scatter/gather table of pinned pages 889 * @dev: Device to import into 890 * @attach: DMA-BUF attachment 891 * @sgt: Scatter/gather table of pinned pages 892 * 893 * This function imports a scatter/gather table exported via DMA-BUF by 894 * another driver. Drivers that use the shmem helpers should set this as their 895 * &drm_driver.gem_prime_import_sg_table callback. 896 * 897 * Returns: 898 * A pointer to a newly created GEM object or an ERR_PTR-encoded negative 899 * error code on failure. 900 */ 901 struct drm_gem_object * 902 drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, 903 struct dma_buf_attachment *attach, 904 struct sg_table *sgt) 905 { 906 size_t size = PAGE_ALIGN(attach->dmabuf->size); 907 struct drm_gem_shmem_object *shmem; 908 909 shmem = __drm_gem_shmem_create(dev, size, true); 910 if (IS_ERR(shmem)) 911 return ERR_CAST(shmem); 912 913 shmem->sgt = sgt; 914 915 drm_dbg_prime(dev, "size = %zu\n", size); 916 917 return &shmem->base; 918 } 919 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_sg_table); 920 921 /** 922 * drm_gem_shmem_prime_import_no_map - Import dmabuf without mapping its sg_table 923 * @dev: Device to import into 924 * @dma_buf: dma-buf object to import 925 * 926 * Drivers that use the shmem helpers but also wants to import dmabuf without 927 * mapping its sg_table can use this as their &drm_driver.gem_prime_import 928 * implementation. 929 */ 930 struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev, 931 struct dma_buf *dma_buf) 932 { 933 struct dma_buf_attachment *attach; 934 struct drm_gem_shmem_object *shmem; 935 struct drm_gem_object *obj; 936 size_t size; 937 int ret; 938 939 if (drm_gem_is_prime_exported_dma_buf(dev, dma_buf)) { 940 /* 941 * Importing dmabuf exported from our own gem increases 942 * refcount on gem itself instead of f_count of dmabuf. 943 */ 944 obj = dma_buf->priv; 945 drm_gem_object_get(obj); 946 return obj; 947 } 948 949 attach = dma_buf_attach(dma_buf, dev->dev); 950 if (IS_ERR(attach)) 951 return ERR_CAST(attach); 952 953 get_dma_buf(dma_buf); 954 955 size = PAGE_ALIGN(attach->dmabuf->size); 956 957 shmem = __drm_gem_shmem_create(dev, size, true); 958 if (IS_ERR(shmem)) { 959 ret = PTR_ERR(shmem); 960 goto fail_detach; 961 } 962 963 drm_dbg_prime(dev, "size = %zu\n", size); 964 965 shmem->base.import_attach = attach; 966 shmem->base.resv = dma_buf->resv; 967 968 return &shmem->base; 969 970 fail_detach: 971 dma_buf_detach(dma_buf, attach); 972 dma_buf_put(dma_buf); 973 974 return ERR_PTR(ret); 975 } 976 EXPORT_SYMBOL_GPL(drm_gem_shmem_prime_import_no_map); 977 978 /* 979 * Kunit helpers 980 */ 981 982 #if IS_ENABLED(CONFIG_KUNIT) 983 int drm_gem_shmem_vmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map) 984 { 985 struct drm_gem_object *obj = &shmem->base; 986 int ret; 987 988 ret = dma_resv_lock_interruptible(obj->resv, NULL); 989 if (ret) 990 return ret; 991 ret = drm_gem_shmem_vmap_locked(shmem, map); 992 dma_resv_unlock(obj->resv); 993 994 return ret; 995 } 996 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vmap); 997 998 void drm_gem_shmem_vunmap(struct drm_gem_shmem_object *shmem, struct iosys_map *map) 999 { 1000 struct drm_gem_object *obj = &shmem->base; 1001 1002 dma_resv_lock_interruptible(obj->resv, NULL); 1003 drm_gem_shmem_vunmap_locked(shmem, map); 1004 dma_resv_unlock(obj->resv); 1005 } 1006 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_vunmap); 1007 1008 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv) 1009 { 1010 struct drm_gem_object *obj = &shmem->base; 1011 int ret; 1012 1013 ret = dma_resv_lock_interruptible(obj->resv, NULL); 1014 if (ret) 1015 return ret; 1016 ret = drm_gem_shmem_madvise_locked(shmem, madv); 1017 dma_resv_unlock(obj->resv); 1018 1019 return ret; 1020 } 1021 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_madvise); 1022 1023 int drm_gem_shmem_purge(struct drm_gem_shmem_object *shmem) 1024 { 1025 struct drm_gem_object *obj = &shmem->base; 1026 int ret; 1027 1028 ret = dma_resv_lock_interruptible(obj->resv, NULL); 1029 if (ret) 1030 return ret; 1031 drm_gem_shmem_purge_locked(shmem); 1032 dma_resv_unlock(obj->resv); 1033 1034 return 0; 1035 } 1036 EXPORT_SYMBOL_IF_KUNIT(drm_gem_shmem_purge); 1037 #endif 1038 1039 MODULE_DESCRIPTION("DRM SHMEM memory-management helpers"); 1040 MODULE_IMPORT_NS("DMA_BUF"); 1041 MODULE_LICENSE("GPL"); 1042