/drivers/gpu/drm/drm_gem.c
C | 584 lines | 327 code | 90 blank | 167 comment | 46 complexity | 47be7290b34a7adf0e821b9d11b4ab7d MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
1/* 2 * Copyright 2008 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 * 23 * Authors: 24 * Eric Anholt <eric@anholt.net> 25 * 26 */ 27 28#include <linux/types.h> 29#include <linux/slab.h> 30#include <linux/mm.h> 31#include <linux/uaccess.h> 32#include <linux/fs.h> 33#include <linux/file.h> 34#include <linux/module.h> 35#include <linux/mman.h> 36#include <linux/pagemap.h> 37#include <linux/shmem_fs.h> 38#include "drmP.h" 39 40/** @file drm_gem.c 41 * 42 * This file provides some of the base ioctls and library routines for 43 * the graphics memory manager implemented by each device driver. 44 * 45 * Because various devices have different requirements in terms of 46 * synchronization and migration strategies, implementing that is left up to 47 * the driver, and all that the general API provides should be generic -- 48 * allocating objects, reading/writing data with the cpu, freeing objects. 49 * Even there, platform-dependent optimizations for reading/writing data with 50 * the CPU mean we'll likely hook those out to driver-specific calls. However, 51 * the DRI2 implementation wants to have at least allocate/mmap be generic. 52 * 53 * The goal was to have swap-backed object allocation managed through 54 * struct file. However, file descriptors as handles to a struct file have 55 * two major failings: 56 * - Process limits prevent more than 1024 or so being used at a time by 57 * default. 58 * - Inability to allocate high fds will aggravate the X Server's select() 59 * handling, and likely that of many GL client applications as well. 60 * 61 * This led to a plan of using our own integer IDs (called handles, following 62 * DRM terminology) to mimic fds, and implement the fd syscalls we need as 63 * ioctls. The objects themselves will still include the struct file so 64 * that we can transition to fds if the required kernel infrastructure shows 65 * up at a later date, and as our interface with shmfs for memory allocation. 66 */ 67 68/* 69 * We make up offsets for buffer objects so we can recognize them at 70 * mmap time. 71 */ 72 73/* pgoff in mmap is an unsigned long, so we need to make sure that 74 * the faked up offset will fit 75 */ 76 77#if BITS_PER_LONG == 64 78#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1) 79#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16) 80#else 81#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFUL >> PAGE_SHIFT) + 1) 82#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFUL >> PAGE_SHIFT) * 16) 83#endif 84 85/** 86 * Initialize the GEM device fields 87 */ 88 89int 90drm_gem_init(struct drm_device *dev) 91{ 92 struct drm_gem_mm *mm; 93 94 spin_lock_init(&dev->object_name_lock); 95 idr_init(&dev->object_name_idr); 96 97 mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL); 98 if (!mm) { 99 DRM_ERROR("out of memory\n"); 100 return -ENOMEM; 101 } 102 103 dev->mm_private = mm; 104 105 if (drm_ht_create(&mm->offset_hash, 12)) { 106 kfree(mm); 107 return -ENOMEM; 108 } 109 110 if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START, 111 DRM_FILE_PAGE_OFFSET_SIZE)) { 112 drm_ht_remove(&mm->offset_hash); 113 kfree(mm); 114 return -ENOMEM; 115 } 116 117 return 0; 118} 119 120void 121drm_gem_destroy(struct drm_device *dev) 122{ 123 struct drm_gem_mm *mm = dev->mm_private; 124 125 drm_mm_takedown(&mm->offset_manager); 126 drm_ht_remove(&mm->offset_hash); 127 kfree(mm); 128 dev->mm_private = NULL; 129} 130 131/** 132 * Initialize an already allocate GEM object of the specified size with 133 * shmfs backing store. 134 */ 135int drm_gem_object_init(struct drm_device *dev, 136 struct drm_gem_object *obj, size_t size) 137{ 138 BUG_ON((size & (PAGE_SIZE - 1)) != 0); 139 140 obj->dev = dev; 141 obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE); 142 if (IS_ERR(obj->filp)) 143 return -ENOMEM; 144 145 kref_init(&obj->refcount); 146 atomic_set(&obj->handle_count, 0); 147 obj->size = size; 148 149 return 0; 150} 151EXPORT_SYMBOL(drm_gem_object_init); 152 153/** 154 * Allocate a GEM object of the specified size with shmfs backing store 155 */ 156struct drm_gem_object * 157drm_gem_object_alloc(struct drm_device *dev, size_t size) 158{ 159 struct drm_gem_object *obj; 160 161 obj = kzalloc(sizeof(*obj), GFP_KERNEL); 162 if (!obj) 163 goto free; 164 165 if (drm_gem_object_init(dev, obj, size) != 0) 166 goto free; 167 168 if (dev->driver->gem_init_object != NULL && 169 dev->driver->gem_init_object(obj) != 0) { 170 goto fput; 171 } 172 return obj; 173fput: 174 /* Object_init mangles the global counters - readjust them. */ 175 fput(obj->filp); 176free: 177 kfree(obj); 178 return NULL; 179} 180EXPORT_SYMBOL(drm_gem_object_alloc); 181 182/** 183 * Removes the mapping from handle to filp for this object. 184 */ 185int 186drm_gem_handle_delete(struct drm_file *filp, u32 handle) 187{ 188 struct drm_device *dev; 189 struct drm_gem_object *obj; 190 191 /* This is gross. The idr system doesn't let us try a delete and 192 * return an error code. It just spews if you fail at deleting. 193 * So, we have to grab a lock around finding the object and then 194 * doing the delete on it and dropping the refcount, or the user 195 * could race us to double-decrement the refcount and cause a 196 * use-after-free later. Given the frequency of our handle lookups, 197 * we may want to use ida for number allocation and a hash table 198 * for the pointers, anyway. 199 */ 200 spin_lock(&filp->table_lock); 201 202 /* Check if we currently have a reference on the object */ 203 obj = idr_find(&filp->object_idr, handle); 204 if (obj == NULL) { 205 spin_unlock(&filp->table_lock); 206 return -EINVAL; 207 } 208 dev = obj->dev; 209 210 /* Release reference and decrement refcount. */ 211 idr_remove(&filp->object_idr, handle); 212 spin_unlock(&filp->table_lock); 213 214 drm_gem_object_handle_unreference_unlocked(obj); 215 216 return 0; 217} 218EXPORT_SYMBOL(drm_gem_handle_delete); 219 220/** 221 * Create a handle for this object. This adds a handle reference 222 * to the object, which includes a regular reference count. Callers 223 * will likely want to dereference the object afterwards. 224 */ 225int 226drm_gem_handle_create(struct drm_file *file_priv, 227 struct drm_gem_object *obj, 228 u32 *handlep) 229{ 230 int ret; 231 232 /* 233 * Get the user-visible handle using idr. 234 */ 235again: 236 /* ensure there is space available to allocate a handle */ 237 if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0) 238 return -ENOMEM; 239 240 /* do the allocation under our spinlock */ 241 spin_lock(&file_priv->table_lock); 242 ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep); 243 spin_unlock(&file_priv->table_lock); 244 if (ret == -EAGAIN) 245 goto again; 246 247 if (ret != 0) 248 return ret; 249 250 drm_gem_object_handle_reference(obj); 251 return 0; 252} 253EXPORT_SYMBOL(drm_gem_handle_create); 254 255/** Returns a reference to the object named by the handle. */ 256struct drm_gem_object * 257drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp, 258 u32 handle) 259{ 260 struct drm_gem_object *obj; 261 262 spin_lock(&filp->table_lock); 263 264 /* Check if we currently have a reference on the object */ 265 obj = idr_find(&filp->object_idr, handle); 266 if (obj == NULL) { 267 spin_unlock(&filp->table_lock); 268 return NULL; 269 } 270 271 drm_gem_object_reference(obj); 272 273 spin_unlock(&filp->table_lock); 274 275 return obj; 276} 277EXPORT_SYMBOL(drm_gem_object_lookup); 278 279/** 280 * Releases the handle to an mm object. 281 */ 282int 283drm_gem_close_ioctl(struct drm_device *dev, void *data, 284 struct drm_file *file_priv) 285{ 286 struct drm_gem_close *args = data; 287 int ret; 288 289 if (!(dev->driver->driver_features & DRIVER_GEM)) 290 return -ENODEV; 291 292 ret = drm_gem_handle_delete(file_priv, args->handle); 293 294 return ret; 295} 296 297/** 298 * Create a global name for an object, returning the name. 299 * 300 * Note that the name does not hold a reference; when the object 301 * is freed, the name goes away. 302 */ 303int 304drm_gem_flink_ioctl(struct drm_device *dev, void *data, 305 struct drm_file *file_priv) 306{ 307 struct drm_gem_flink *args = data; 308 struct drm_gem_object *obj; 309 int ret; 310 311 if (!(dev->driver->driver_features & DRIVER_GEM)) 312 return -ENODEV; 313 314 obj = drm_gem_object_lookup(dev, file_priv, args->handle); 315 if (obj == NULL) 316 return -ENOENT; 317 318again: 319 if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) { 320 ret = -ENOMEM; 321 goto err; 322 } 323 324 spin_lock(&dev->object_name_lock); 325 if (!obj->name) { 326 ret = idr_get_new_above(&dev->object_name_idr, obj, 1, 327 &obj->name); 328 args->name = (uint64_t) obj->name; 329 spin_unlock(&dev->object_name_lock); 330 331 if (ret == -EAGAIN) 332 goto again; 333 334 if (ret != 0) 335 goto err; 336 337 /* Allocate a reference for the name table. */ 338 drm_gem_object_reference(obj); 339 } else { 340 args->name = (uint64_t) obj->name; 341 spin_unlock(&dev->object_name_lock); 342 ret = 0; 343 } 344 345err: 346 drm_gem_object_unreference_unlocked(obj); 347 return ret; 348} 349 350/** 351 * Open an object using the global name, returning a handle and the size. 352 * 353 * This handle (of course) holds a reference to the object, so the object 354 * will not go away until the handle is deleted. 355 */ 356int 357drm_gem_open_ioctl(struct drm_device *dev, void *data, 358 struct drm_file *file_priv) 359{ 360 struct drm_gem_open *args = data; 361 struct drm_gem_object *obj; 362 int ret; 363 u32 handle; 364 365 if (!(dev->driver->driver_features & DRIVER_GEM)) 366 return -ENODEV; 367 368 spin_lock(&dev->object_name_lock); 369 obj = idr_find(&dev->object_name_idr, (int) args->name); 370 if (obj) 371 drm_gem_object_reference(obj); 372 spin_unlock(&dev->object_name_lock); 373 if (!obj) 374 return -ENOENT; 375 376 ret = drm_gem_handle_create(file_priv, obj, &handle); 377 drm_gem_object_unreference_unlocked(obj); 378 if (ret) 379 return ret; 380 381 args->handle = handle; 382 args->size = obj->size; 383 384 return 0; 385} 386 387/** 388 * Called at device open time, sets up the structure for handling refcounting 389 * of mm objects. 390 */ 391void 392drm_gem_open(struct drm_device *dev, struct drm_file *file_private) 393{ 394 idr_init(&file_private->object_idr); 395 spin_lock_init(&file_private->table_lock); 396} 397 398/** 399 * Called at device close to release the file's 400 * handle references on objects. 401 */ 402static int 403drm_gem_object_release_handle(int id, void *ptr, void *data) 404{ 405 struct drm_gem_object *obj = ptr; 406 407 drm_gem_object_handle_unreference_unlocked(obj); 408 409 return 0; 410} 411 412/** 413 * Called at close time when the filp is going away. 414 * 415 * Releases any remaining references on objects by this filp. 416 */ 417void 418drm_gem_release(struct drm_device *dev, struct drm_file *file_private) 419{ 420 idr_for_each(&file_private->object_idr, 421 &drm_gem_object_release_handle, NULL); 422 423 idr_remove_all(&file_private->object_idr); 424 idr_destroy(&file_private->object_idr); 425} 426 427void 428drm_gem_object_release(struct drm_gem_object *obj) 429{ 430 fput(obj->filp); 431} 432EXPORT_SYMBOL(drm_gem_object_release); 433 434/** 435 * Called after the last reference to the object has been lost. 436 * Must be called holding struct_ mutex 437 * 438 * Frees the object 439 */ 440void 441drm_gem_object_free(struct kref *kref) 442{ 443 struct drm_gem_object *obj = (struct drm_gem_object *) kref; 444 struct drm_device *dev = obj->dev; 445 446 BUG_ON(!mutex_is_locked(&dev->struct_mutex)); 447 448 if (dev->driver->gem_free_object != NULL) 449 dev->driver->gem_free_object(obj); 450} 451EXPORT_SYMBOL(drm_gem_object_free); 452 453static void drm_gem_object_ref_bug(struct kref *list_kref) 454{ 455 BUG(); 456} 457 458/** 459 * Called after the last handle to the object has been closed 460 * 461 * Removes any name for the object. Note that this must be 462 * called before drm_gem_object_free or we'll be touching 463 * freed memory 464 */ 465void drm_gem_object_handle_free(struct drm_gem_object *obj) 466{ 467 struct drm_device *dev = obj->dev; 468 469 /* Remove any name for this object */ 470 spin_lock(&dev->object_name_lock); 471 if (obj->name) { 472 idr_remove(&dev->object_name_idr, obj->name); 473 obj->name = 0; 474 spin_unlock(&dev->object_name_lock); 475 /* 476 * The object name held a reference to this object, drop 477 * that now. 478 * 479 * This cannot be the last reference, since the handle holds one too. 480 */ 481 kref_put(&obj->refcount, drm_gem_object_ref_bug); 482 } else 483 spin_unlock(&dev->object_name_lock); 484 485} 486EXPORT_SYMBOL(drm_gem_object_handle_free); 487 488void drm_gem_vm_open(struct vm_area_struct *vma) 489{ 490 struct drm_gem_object *obj = vma->vm_private_data; 491 492 drm_gem_object_reference(obj); 493 494 mutex_lock(&obj->dev->struct_mutex); 495 drm_vm_open_locked(vma); 496 mutex_unlock(&obj->dev->struct_mutex); 497} 498EXPORT_SYMBOL(drm_gem_vm_open); 499 500void drm_gem_vm_close(struct vm_area_struct *vma) 501{ 502 struct drm_gem_object *obj = vma->vm_private_data; 503 struct drm_device *dev = obj->dev; 504 505 mutex_lock(&dev->struct_mutex); 506 drm_vm_close_locked(vma); 507 drm_gem_object_unreference(obj); 508 mutex_unlock(&dev->struct_mutex); 509} 510EXPORT_SYMBOL(drm_gem_vm_close); 511 512 513/** 514 * drm_gem_mmap - memory map routine for GEM objects 515 * @filp: DRM file pointer 516 * @vma: VMA for the area to be mapped 517 * 518 * If a driver supports GEM object mapping, mmap calls on the DRM file 519 * descriptor will end up here. 520 * 521 * If we find the object based on the offset passed in (vma->vm_pgoff will 522 * contain the fake offset we created when the GTT map ioctl was called on 523 * the object), we set up the driver fault handler so that any accesses 524 * to the object can be trapped, to perform migration, GTT binding, surface 525 * register allocation, or performance monitoring. 526 */ 527int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) 528{ 529 struct drm_file *priv = filp->private_data; 530 struct drm_device *dev = priv->minor->dev; 531 struct drm_gem_mm *mm = dev->mm_private; 532 struct drm_local_map *map = NULL; 533 struct drm_gem_object *obj; 534 struct drm_hash_item *hash; 535 int ret = 0; 536 537 mutex_lock(&dev->struct_mutex); 538 539 if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) { 540 mutex_unlock(&dev->struct_mutex); 541 return drm_mmap(filp, vma); 542 } 543 544 map = drm_hash_entry(hash, struct drm_map_list, hash)->map; 545 if (!map || 546 ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) { 547 ret = -EPERM; 548 goto out_unlock; 549 } 550 551 /* Check for valid size. */ 552 if (map->size < vma->vm_end - vma->vm_start) { 553 ret = -EINVAL; 554 goto out_unlock; 555 } 556 557 obj = map->handle; 558 if (!obj->dev->driver->gem_vm_ops) { 559 ret = -EINVAL; 560 goto out_unlock; 561 } 562 563 vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; 564 vma->vm_ops = obj->dev->driver->gem_vm_ops; 565 vma->vm_private_data = map->handle; 566 vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); 567 568 /* Take a ref for this mapping of the object, so that the fault 569 * handler can dereference the mmap offset's pointer to the object. 570 * This reference is cleaned up by the corresponding vm_close 571 * (which should happen whether the vma was created by this call, or 572 * by a vm_open due to mremap or partial unmap or whatever). 573 */ 574 drm_gem_object_reference(obj); 575 576 vma->vm_file = filp; /* Needed for drm_vm_open() */ 577 drm_vm_open_locked(vma); 578 579out_unlock: 580 mutex_unlock(&dev->struct_mutex); 581 582 return ret; 583} 584EXPORT_SYMBOL(drm_gem_mmap);