drm_property.c (27936B)
1/* 2 * Copyright (c) 2016 Intel Corporation 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that copyright 7 * notice and this permission notice appear in supporting documentation, and 8 * that the name of the copyright holders not be used in advertising or 9 * publicity pertaining to distribution of the software without specific, 10 * written prior permission. The copyright holders make no representations 11 * about the suitability of this software for any purpose. It is provided "as 12 * is" without express or implied warranty. 13 * 14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 20 * OF THIS SOFTWARE. 21 */ 22 23#include <linux/export.h> 24#include <linux/uaccess.h> 25 26#include <drm/drm_crtc.h> 27#include <drm/drm_drv.h> 28#include <drm/drm_file.h> 29#include <drm/drm_framebuffer.h> 30#include <drm/drm_property.h> 31 32#include "drm_crtc_internal.h" 33 34/** 35 * DOC: overview 36 * 37 * Properties as represented by &drm_property are used to extend the modeset 38 * interface exposed to userspace. For the atomic modeset IOCTL properties are 39 * even the only way to transport metadata about the desired new modeset 40 * configuration from userspace to the kernel. Properties have a well-defined 41 * value range, which is enforced by the drm core. See the documentation of the 42 * flags member of &struct drm_property for an overview of the different 43 * property types and ranges. 44 * 45 * Properties don't store the current value directly, but need to be 46 * instantiated by attaching them to a &drm_mode_object with 47 * drm_object_attach_property(). 48 * 49 * Property values are only 64bit. To support bigger piles of data (like gamma 50 * tables, color correction matrices or large structures) a property can instead 51 * point at a &drm_property_blob with that additional data. 52 * 53 * Properties are defined by their symbolic name, userspace must keep a 54 * per-object mapping from those names to the property ID used in the atomic 55 * IOCTL and in the get/set property IOCTL. 56 */ 57 58static bool drm_property_flags_valid(u32 flags) 59{ 60 u32 legacy_type = flags & DRM_MODE_PROP_LEGACY_TYPE; 61 u32 ext_type = flags & DRM_MODE_PROP_EXTENDED_TYPE; 62 63 /* Reject undefined/deprecated flags */ 64 if (flags & ~(DRM_MODE_PROP_LEGACY_TYPE | 65 DRM_MODE_PROP_EXTENDED_TYPE | 66 DRM_MODE_PROP_IMMUTABLE | 67 DRM_MODE_PROP_ATOMIC)) 68 return false; 69 70 /* We want either a legacy type or an extended type, but not both */ 71 if (!legacy_type == !ext_type) 72 return false; 73 74 /* Only one legacy type at a time please */ 75 if (legacy_type && !is_power_of_2(legacy_type)) 76 return false; 77 78 return true; 79} 80 81/** 82 * drm_property_create - create a new property type 83 * @dev: drm device 84 * @flags: flags specifying the property type 85 * @name: name of the property 86 * @num_values: number of pre-defined values 87 * 88 * This creates a new generic drm property which can then be attached to a drm 89 * object with drm_object_attach_property(). The returned property object must 90 * be freed with drm_property_destroy(), which is done automatically when 91 * calling drm_mode_config_cleanup(). 92 * 93 * Returns: 94 * A pointer to the newly created property on success, NULL on failure. 95 */ 96struct drm_property *drm_property_create(struct drm_device *dev, 97 u32 flags, const char *name, 98 int num_values) 99{ 100 struct drm_property *property = NULL; 101 int ret; 102 103 if (WARN_ON(!drm_property_flags_valid(flags))) 104 return NULL; 105 106 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) 107 return NULL; 108 109 property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); 110 if (!property) 111 return NULL; 112 113 property->dev = dev; 114 115 if (num_values) { 116 property->values = kcalloc(num_values, sizeof(uint64_t), 117 GFP_KERNEL); 118 if (!property->values) 119 goto fail; 120 } 121 122 ret = drm_mode_object_add(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); 123 if (ret) 124 goto fail; 125 126 property->flags = flags; 127 property->num_values = num_values; 128 INIT_LIST_HEAD(&property->enum_list); 129 130 strscpy_pad(property->name, name, DRM_PROP_NAME_LEN); 131 132 list_add_tail(&property->head, &dev->mode_config.property_list); 133 134 return property; 135fail: 136 kfree(property->values); 137 kfree(property); 138 return NULL; 139} 140EXPORT_SYMBOL(drm_property_create); 141 142/** 143 * drm_property_create_enum - create a new enumeration property type 144 * @dev: drm device 145 * @flags: flags specifying the property type 146 * @name: name of the property 147 * @props: enumeration lists with property values 148 * @num_values: number of pre-defined values 149 * 150 * This creates a new generic drm property which can then be attached to a drm 151 * object with drm_object_attach_property(). The returned property object must 152 * be freed with drm_property_destroy(), which is done automatically when 153 * calling drm_mode_config_cleanup(). 154 * 155 * Userspace is only allowed to set one of the predefined values for enumeration 156 * properties. 157 * 158 * Returns: 159 * A pointer to the newly created property on success, NULL on failure. 160 */ 161struct drm_property *drm_property_create_enum(struct drm_device *dev, 162 u32 flags, const char *name, 163 const struct drm_prop_enum_list *props, 164 int num_values) 165{ 166 struct drm_property *property; 167 int i, ret; 168 169 flags |= DRM_MODE_PROP_ENUM; 170 171 property = drm_property_create(dev, flags, name, num_values); 172 if (!property) 173 return NULL; 174 175 for (i = 0; i < num_values; i++) { 176 ret = drm_property_add_enum(property, 177 props[i].type, 178 props[i].name); 179 if (ret) { 180 drm_property_destroy(dev, property); 181 return NULL; 182 } 183 } 184 185 return property; 186} 187EXPORT_SYMBOL(drm_property_create_enum); 188 189/** 190 * drm_property_create_bitmask - create a new bitmask property type 191 * @dev: drm device 192 * @flags: flags specifying the property type 193 * @name: name of the property 194 * @props: enumeration lists with property bitflags 195 * @num_props: size of the @props array 196 * @supported_bits: bitmask of all supported enumeration values 197 * 198 * This creates a new bitmask drm property which can then be attached to a drm 199 * object with drm_object_attach_property(). The returned property object must 200 * be freed with drm_property_destroy(), which is done automatically when 201 * calling drm_mode_config_cleanup(). 202 * 203 * Compared to plain enumeration properties userspace is allowed to set any 204 * or'ed together combination of the predefined property bitflag values 205 * 206 * Returns: 207 * A pointer to the newly created property on success, NULL on failure. 208 */ 209struct drm_property *drm_property_create_bitmask(struct drm_device *dev, 210 u32 flags, const char *name, 211 const struct drm_prop_enum_list *props, 212 int num_props, 213 uint64_t supported_bits) 214{ 215 struct drm_property *property; 216 int i, ret; 217 int num_values = hweight64(supported_bits); 218 219 flags |= DRM_MODE_PROP_BITMASK; 220 221 property = drm_property_create(dev, flags, name, num_values); 222 if (!property) 223 return NULL; 224 for (i = 0; i < num_props; i++) { 225 if (!(supported_bits & (1ULL << props[i].type))) 226 continue; 227 228 ret = drm_property_add_enum(property, 229 props[i].type, 230 props[i].name); 231 if (ret) { 232 drm_property_destroy(dev, property); 233 return NULL; 234 } 235 } 236 237 return property; 238} 239EXPORT_SYMBOL(drm_property_create_bitmask); 240 241static struct drm_property *property_create_range(struct drm_device *dev, 242 u32 flags, const char *name, 243 uint64_t min, uint64_t max) 244{ 245 struct drm_property *property; 246 247 property = drm_property_create(dev, flags, name, 2); 248 if (!property) 249 return NULL; 250 251 property->values[0] = min; 252 property->values[1] = max; 253 254 return property; 255} 256 257/** 258 * drm_property_create_range - create a new unsigned ranged property type 259 * @dev: drm device 260 * @flags: flags specifying the property type 261 * @name: name of the property 262 * @min: minimum value of the property 263 * @max: maximum value of the property 264 * 265 * This creates a new generic drm property which can then be attached to a drm 266 * object with drm_object_attach_property(). The returned property object must 267 * be freed with drm_property_destroy(), which is done automatically when 268 * calling drm_mode_config_cleanup(). 269 * 270 * Userspace is allowed to set any unsigned integer value in the (min, max) 271 * range inclusive. 272 * 273 * Returns: 274 * A pointer to the newly created property on success, NULL on failure. 275 */ 276struct drm_property *drm_property_create_range(struct drm_device *dev, 277 u32 flags, const char *name, 278 uint64_t min, uint64_t max) 279{ 280 return property_create_range(dev, DRM_MODE_PROP_RANGE | flags, 281 name, min, max); 282} 283EXPORT_SYMBOL(drm_property_create_range); 284 285/** 286 * drm_property_create_signed_range - create a new signed ranged property type 287 * @dev: drm device 288 * @flags: flags specifying the property type 289 * @name: name of the property 290 * @min: minimum value of the property 291 * @max: maximum value of the property 292 * 293 * This creates a new generic drm property which can then be attached to a drm 294 * object with drm_object_attach_property(). The returned property object must 295 * be freed with drm_property_destroy(), which is done automatically when 296 * calling drm_mode_config_cleanup(). 297 * 298 * Userspace is allowed to set any signed integer value in the (min, max) 299 * range inclusive. 300 * 301 * Returns: 302 * A pointer to the newly created property on success, NULL on failure. 303 */ 304struct drm_property *drm_property_create_signed_range(struct drm_device *dev, 305 u32 flags, const char *name, 306 int64_t min, int64_t max) 307{ 308 return property_create_range(dev, DRM_MODE_PROP_SIGNED_RANGE | flags, 309 name, I642U64(min), I642U64(max)); 310} 311EXPORT_SYMBOL(drm_property_create_signed_range); 312 313/** 314 * drm_property_create_object - create a new object property type 315 * @dev: drm device 316 * @flags: flags specifying the property type 317 * @name: name of the property 318 * @type: object type from DRM_MODE_OBJECT_* defines 319 * 320 * This creates a new generic drm property which can then be attached to a drm 321 * object with drm_object_attach_property(). The returned property object must 322 * be freed with drm_property_destroy(), which is done automatically when 323 * calling drm_mode_config_cleanup(). 324 * 325 * Userspace is only allowed to set this to any property value of the given 326 * @type. Only useful for atomic properties, which is enforced. 327 * 328 * Returns: 329 * A pointer to the newly created property on success, NULL on failure. 330 */ 331struct drm_property *drm_property_create_object(struct drm_device *dev, 332 u32 flags, const char *name, 333 uint32_t type) 334{ 335 struct drm_property *property; 336 337 flags |= DRM_MODE_PROP_OBJECT; 338 339 if (WARN_ON(!(flags & DRM_MODE_PROP_ATOMIC))) 340 return NULL; 341 342 property = drm_property_create(dev, flags, name, 1); 343 if (!property) 344 return NULL; 345 346 property->values[0] = type; 347 348 return property; 349} 350EXPORT_SYMBOL(drm_property_create_object); 351 352/** 353 * drm_property_create_bool - create a new boolean property type 354 * @dev: drm device 355 * @flags: flags specifying the property type 356 * @name: name of the property 357 * 358 * This creates a new generic drm property which can then be attached to a drm 359 * object with drm_object_attach_property(). The returned property object must 360 * be freed with drm_property_destroy(), which is done automatically when 361 * calling drm_mode_config_cleanup(). 362 * 363 * This is implemented as a ranged property with only {0, 1} as valid values. 364 * 365 * Returns: 366 * A pointer to the newly created property on success, NULL on failure. 367 */ 368struct drm_property *drm_property_create_bool(struct drm_device *dev, 369 u32 flags, const char *name) 370{ 371 return drm_property_create_range(dev, flags, name, 0, 1); 372} 373EXPORT_SYMBOL(drm_property_create_bool); 374 375/** 376 * drm_property_add_enum - add a possible value to an enumeration property 377 * @property: enumeration property to change 378 * @value: value of the new enumeration 379 * @name: symbolic name of the new enumeration 380 * 381 * This functions adds enumerations to a property. 382 * 383 * It's use is deprecated, drivers should use one of the more specific helpers 384 * to directly create the property with all enumerations already attached. 385 * 386 * Returns: 387 * Zero on success, error code on failure. 388 */ 389int drm_property_add_enum(struct drm_property *property, 390 uint64_t value, const char *name) 391{ 392 struct drm_property_enum *prop_enum; 393 int index = 0; 394 395 if (WARN_ON(strlen(name) >= DRM_PROP_NAME_LEN)) 396 return -EINVAL; 397 398 if (WARN_ON(!drm_property_type_is(property, DRM_MODE_PROP_ENUM) && 399 !drm_property_type_is(property, DRM_MODE_PROP_BITMASK))) 400 return -EINVAL; 401 402 /* 403 * Bitmask enum properties have the additional constraint of values 404 * from 0 to 63 405 */ 406 if (WARN_ON(drm_property_type_is(property, DRM_MODE_PROP_BITMASK) && 407 value > 63)) 408 return -EINVAL; 409 410 list_for_each_entry(prop_enum, &property->enum_list, head) { 411 if (WARN_ON(prop_enum->value == value)) 412 return -EINVAL; 413 index++; 414 } 415 416 if (WARN_ON(index >= property->num_values)) 417 return -EINVAL; 418 419 prop_enum = kzalloc(sizeof(struct drm_property_enum), GFP_KERNEL); 420 if (!prop_enum) 421 return -ENOMEM; 422 423 strscpy_pad(prop_enum->name, name, DRM_PROP_NAME_LEN); 424 prop_enum->value = value; 425 426 property->values[index] = value; 427 list_add_tail(&prop_enum->head, &property->enum_list); 428 return 0; 429} 430EXPORT_SYMBOL(drm_property_add_enum); 431 432/** 433 * drm_property_destroy - destroy a drm property 434 * @dev: drm device 435 * @property: property to destroy 436 * 437 * This function frees a property including any attached resources like 438 * enumeration values. 439 */ 440void drm_property_destroy(struct drm_device *dev, struct drm_property *property) 441{ 442 struct drm_property_enum *prop_enum, *pt; 443 444 list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) { 445 list_del(&prop_enum->head); 446 kfree(prop_enum); 447 } 448 449 if (property->num_values) 450 kfree(property->values); 451 drm_mode_object_unregister(dev, &property->base); 452 list_del(&property->head); 453 kfree(property); 454} 455EXPORT_SYMBOL(drm_property_destroy); 456 457int drm_mode_getproperty_ioctl(struct drm_device *dev, 458 void *data, struct drm_file *file_priv) 459{ 460 struct drm_mode_get_property *out_resp = data; 461 struct drm_property *property; 462 int enum_count = 0; 463 int value_count = 0; 464 int i, copied; 465 struct drm_property_enum *prop_enum; 466 struct drm_mode_property_enum __user *enum_ptr; 467 uint64_t __user *values_ptr; 468 469 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 470 return -EOPNOTSUPP; 471 472 property = drm_property_find(dev, file_priv, out_resp->prop_id); 473 if (!property) 474 return -ENOENT; 475 476 strscpy_pad(out_resp->name, property->name, DRM_PROP_NAME_LEN); 477 out_resp->flags = property->flags; 478 479 value_count = property->num_values; 480 values_ptr = u64_to_user_ptr(out_resp->values_ptr); 481 482 for (i = 0; i < value_count; i++) { 483 if (i < out_resp->count_values && 484 put_user(property->values[i], values_ptr + i)) { 485 return -EFAULT; 486 } 487 } 488 out_resp->count_values = value_count; 489 490 copied = 0; 491 enum_ptr = u64_to_user_ptr(out_resp->enum_blob_ptr); 492 493 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) || 494 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 495 list_for_each_entry(prop_enum, &property->enum_list, head) { 496 enum_count++; 497 if (out_resp->count_enum_blobs < enum_count) 498 continue; 499 500 if (copy_to_user(&enum_ptr[copied].value, 501 &prop_enum->value, sizeof(uint64_t))) 502 return -EFAULT; 503 504 if (copy_to_user(&enum_ptr[copied].name, 505 &prop_enum->name, DRM_PROP_NAME_LEN)) 506 return -EFAULT; 507 copied++; 508 } 509 out_resp->count_enum_blobs = enum_count; 510 } 511 512 /* 513 * NOTE: The idea seems to have been to use this to read all the blob 514 * property values. But nothing ever added them to the corresponding 515 * list, userspace always used the special-purpose get_blob ioctl to 516 * read the value for a blob property. It also doesn't make a lot of 517 * sense to return values here when everything else is just metadata for 518 * the property itself. 519 */ 520 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) 521 out_resp->count_enum_blobs = 0; 522 523 return 0; 524} 525 526static void drm_property_free_blob(struct kref *kref) 527{ 528 struct drm_property_blob *blob = 529 container_of(kref, struct drm_property_blob, base.refcount); 530 531 mutex_lock(&blob->dev->mode_config.blob_lock); 532 list_del(&blob->head_global); 533 mutex_unlock(&blob->dev->mode_config.blob_lock); 534 535 drm_mode_object_unregister(blob->dev, &blob->base); 536 537 kvfree(blob); 538} 539 540/** 541 * drm_property_create_blob - Create new blob property 542 * @dev: DRM device to create property for 543 * @length: Length to allocate for blob data 544 * @data: If specified, copies data into blob 545 * 546 * Creates a new blob property for a specified DRM device, optionally 547 * copying data. Note that blob properties are meant to be invariant, hence the 548 * data must be filled out before the blob is used as the value of any property. 549 * 550 * Returns: 551 * New blob property with a single reference on success, or an ERR_PTR 552 * value on failure. 553 */ 554struct drm_property_blob * 555drm_property_create_blob(struct drm_device *dev, size_t length, 556 const void *data) 557{ 558 struct drm_property_blob *blob; 559 int ret; 560 561 if (!length || length > INT_MAX - sizeof(struct drm_property_blob)) 562 return ERR_PTR(-EINVAL); 563 564 blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL); 565 if (!blob) 566 return ERR_PTR(-ENOMEM); 567 568 /* This must be explicitly initialised, so we can safely call list_del 569 * on it in the removal handler, even if it isn't in a file list. */ 570 INIT_LIST_HEAD(&blob->head_file); 571 blob->data = (void *)blob + sizeof(*blob); 572 blob->length = length; 573 blob->dev = dev; 574 575 if (data) 576 memcpy(blob->data, data, length); 577 578 ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB, 579 true, drm_property_free_blob); 580 if (ret) { 581 kvfree(blob); 582 return ERR_PTR(-EINVAL); 583 } 584 585 mutex_lock(&dev->mode_config.blob_lock); 586 list_add_tail(&blob->head_global, 587 &dev->mode_config.property_blob_list); 588 mutex_unlock(&dev->mode_config.blob_lock); 589 590 return blob; 591} 592EXPORT_SYMBOL(drm_property_create_blob); 593 594/** 595 * drm_property_blob_put - release a blob property reference 596 * @blob: DRM blob property 597 * 598 * Releases a reference to a blob property. May free the object. 599 */ 600void drm_property_blob_put(struct drm_property_blob *blob) 601{ 602 if (!blob) 603 return; 604 605 drm_mode_object_put(&blob->base); 606} 607EXPORT_SYMBOL(drm_property_blob_put); 608 609void drm_property_destroy_user_blobs(struct drm_device *dev, 610 struct drm_file *file_priv) 611{ 612 struct drm_property_blob *blob, *bt; 613 614 /* 615 * When the file gets released that means no one else can access the 616 * blob list any more, so no need to grab dev->blob_lock. 617 */ 618 list_for_each_entry_safe(blob, bt, &file_priv->blobs, head_file) { 619 list_del_init(&blob->head_file); 620 drm_property_blob_put(blob); 621 } 622} 623 624/** 625 * drm_property_blob_get - acquire blob property reference 626 * @blob: DRM blob property 627 * 628 * Acquires a reference to an existing blob property. Returns @blob, which 629 * allows this to be used as a shorthand in assignments. 630 */ 631struct drm_property_blob *drm_property_blob_get(struct drm_property_blob *blob) 632{ 633 drm_mode_object_get(&blob->base); 634 return blob; 635} 636EXPORT_SYMBOL(drm_property_blob_get); 637 638/** 639 * drm_property_lookup_blob - look up a blob property and take a reference 640 * @dev: drm device 641 * @id: id of the blob property 642 * 643 * If successful, this takes an additional reference to the blob property. 644 * callers need to make sure to eventually unreferenced the returned property 645 * again, using drm_property_blob_put(). 646 * 647 * Return: 648 * NULL on failure, pointer to the blob on success. 649 */ 650struct drm_property_blob *drm_property_lookup_blob(struct drm_device *dev, 651 uint32_t id) 652{ 653 struct drm_mode_object *obj; 654 struct drm_property_blob *blob = NULL; 655 656 obj = __drm_mode_object_find(dev, NULL, id, DRM_MODE_OBJECT_BLOB); 657 if (obj) 658 blob = obj_to_blob(obj); 659 return blob; 660} 661EXPORT_SYMBOL(drm_property_lookup_blob); 662 663/** 664 * drm_property_replace_global_blob - replace existing blob property 665 * @dev: drm device 666 * @replace: location of blob property pointer to be replaced 667 * @length: length of data for new blob, or 0 for no data 668 * @data: content for new blob, or NULL for no data 669 * @obj_holds_id: optional object for property holding blob ID 670 * @prop_holds_id: optional property holding blob ID 671 * @return 0 on success or error on failure 672 * 673 * This function will replace a global property in the blob list, optionally 674 * updating a property which holds the ID of that property. 675 * 676 * If length is 0 or data is NULL, no new blob will be created, and the holding 677 * property, if specified, will be set to 0. 678 * 679 * Access to the replace pointer is assumed to be protected by the caller, e.g. 680 * by holding the relevant modesetting object lock for its parent. 681 * 682 * For example, a drm_connector has a 'PATH' property, which contains the ID 683 * of a blob property with the value of the MST path information. Calling this 684 * function with replace pointing to the connector's path_blob_ptr, length and 685 * data set for the new path information, obj_holds_id set to the connector's 686 * base object, and prop_holds_id set to the path property name, will perform 687 * a completely atomic update. The access to path_blob_ptr is protected by the 688 * caller holding a lock on the connector. 689 */ 690int drm_property_replace_global_blob(struct drm_device *dev, 691 struct drm_property_blob **replace, 692 size_t length, 693 const void *data, 694 struct drm_mode_object *obj_holds_id, 695 struct drm_property *prop_holds_id) 696{ 697 struct drm_property_blob *new_blob = NULL; 698 struct drm_property_blob *old_blob = NULL; 699 int ret; 700 701 WARN_ON(replace == NULL); 702 703 old_blob = *replace; 704 705 if (length && data) { 706 new_blob = drm_property_create_blob(dev, length, data); 707 if (IS_ERR(new_blob)) 708 return PTR_ERR(new_blob); 709 } 710 711 if (obj_holds_id) { 712 ret = drm_object_property_set_value(obj_holds_id, 713 prop_holds_id, 714 new_blob ? 715 new_blob->base.id : 0); 716 if (ret != 0) 717 goto err_created; 718 } 719 720 drm_property_blob_put(old_blob); 721 *replace = new_blob; 722 723 return 0; 724 725err_created: 726 drm_property_blob_put(new_blob); 727 return ret; 728} 729EXPORT_SYMBOL(drm_property_replace_global_blob); 730 731/** 732 * drm_property_replace_blob - replace a blob property 733 * @blob: a pointer to the member blob to be replaced 734 * @new_blob: the new blob to replace with 735 * 736 * Return: true if the blob was in fact replaced. 737 */ 738bool drm_property_replace_blob(struct drm_property_blob **blob, 739 struct drm_property_blob *new_blob) 740{ 741 struct drm_property_blob *old_blob = *blob; 742 743 if (old_blob == new_blob) 744 return false; 745 746 drm_property_blob_put(old_blob); 747 if (new_blob) 748 drm_property_blob_get(new_blob); 749 *blob = new_blob; 750 return true; 751} 752EXPORT_SYMBOL(drm_property_replace_blob); 753 754int drm_mode_getblob_ioctl(struct drm_device *dev, 755 void *data, struct drm_file *file_priv) 756{ 757 struct drm_mode_get_blob *out_resp = data; 758 struct drm_property_blob *blob; 759 int ret = 0; 760 761 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 762 return -EOPNOTSUPP; 763 764 blob = drm_property_lookup_blob(dev, out_resp->blob_id); 765 if (!blob) 766 return -ENOENT; 767 768 if (out_resp->length == blob->length) { 769 if (copy_to_user(u64_to_user_ptr(out_resp->data), 770 blob->data, 771 blob->length)) { 772 ret = -EFAULT; 773 goto unref; 774 } 775 } 776 out_resp->length = blob->length; 777unref: 778 drm_property_blob_put(blob); 779 780 return ret; 781} 782 783int drm_mode_createblob_ioctl(struct drm_device *dev, 784 void *data, struct drm_file *file_priv) 785{ 786 struct drm_mode_create_blob *out_resp = data; 787 struct drm_property_blob *blob; 788 int ret = 0; 789 790 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 791 return -EOPNOTSUPP; 792 793 blob = drm_property_create_blob(dev, out_resp->length, NULL); 794 if (IS_ERR(blob)) 795 return PTR_ERR(blob); 796 797 if (copy_from_user(blob->data, 798 u64_to_user_ptr(out_resp->data), 799 out_resp->length)) { 800 ret = -EFAULT; 801 goto out_blob; 802 } 803 804 /* Dropping the lock between create_blob and our access here is safe 805 * as only the same file_priv can remove the blob; at this point, it is 806 * not associated with any file_priv. */ 807 mutex_lock(&dev->mode_config.blob_lock); 808 out_resp->blob_id = blob->base.id; 809 list_add_tail(&blob->head_file, &file_priv->blobs); 810 mutex_unlock(&dev->mode_config.blob_lock); 811 812 return 0; 813 814out_blob: 815 drm_property_blob_put(blob); 816 return ret; 817} 818 819int drm_mode_destroyblob_ioctl(struct drm_device *dev, 820 void *data, struct drm_file *file_priv) 821{ 822 struct drm_mode_destroy_blob *out_resp = data; 823 struct drm_property_blob *blob = NULL, *bt; 824 bool found = false; 825 int ret = 0; 826 827 if (!drm_core_check_feature(dev, DRIVER_MODESET)) 828 return -EOPNOTSUPP; 829 830 blob = drm_property_lookup_blob(dev, out_resp->blob_id); 831 if (!blob) 832 return -ENOENT; 833 834 mutex_lock(&dev->mode_config.blob_lock); 835 /* Ensure the property was actually created by this user. */ 836 list_for_each_entry(bt, &file_priv->blobs, head_file) { 837 if (bt == blob) { 838 found = true; 839 break; 840 } 841 } 842 843 if (!found) { 844 ret = -EPERM; 845 goto err; 846 } 847 848 /* We must drop head_file here, because we may not be the last 849 * reference on the blob. */ 850 list_del_init(&blob->head_file); 851 mutex_unlock(&dev->mode_config.blob_lock); 852 853 /* One reference from lookup, and one from the filp. */ 854 drm_property_blob_put(blob); 855 drm_property_blob_put(blob); 856 857 return 0; 858 859err: 860 mutex_unlock(&dev->mode_config.blob_lock); 861 drm_property_blob_put(blob); 862 863 return ret; 864} 865 866/* Some properties could refer to dynamic refcnt'd objects, or things that 867 * need special locking to handle lifetime issues (ie. to ensure the prop 868 * value doesn't become invalid part way through the property update due to 869 * race). The value returned by reference via 'obj' should be passed back 870 * to drm_property_change_valid_put() after the property is set (and the 871 * object to which the property is attached has a chance to take its own 872 * reference). 873 */ 874bool drm_property_change_valid_get(struct drm_property *property, 875 uint64_t value, struct drm_mode_object **ref) 876{ 877 int i; 878 879 if (property->flags & DRM_MODE_PROP_IMMUTABLE) 880 return false; 881 882 *ref = NULL; 883 884 if (drm_property_type_is(property, DRM_MODE_PROP_RANGE)) { 885 if (value < property->values[0] || value > property->values[1]) 886 return false; 887 return true; 888 } else if (drm_property_type_is(property, DRM_MODE_PROP_SIGNED_RANGE)) { 889 int64_t svalue = U642I64(value); 890 891 if (svalue < U642I64(property->values[0]) || 892 svalue > U642I64(property->values[1])) 893 return false; 894 return true; 895 } else if (drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) { 896 uint64_t valid_mask = 0; 897 898 for (i = 0; i < property->num_values; i++) 899 valid_mask |= (1ULL << property->values[i]); 900 return !(value & ~valid_mask); 901 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) { 902 struct drm_property_blob *blob; 903 904 if (value == 0) 905 return true; 906 907 blob = drm_property_lookup_blob(property->dev, value); 908 if (blob) { 909 *ref = &blob->base; 910 return true; 911 } else { 912 return false; 913 } 914 } else if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 915 /* a zero value for an object property translates to null: */ 916 if (value == 0) 917 return true; 918 919 *ref = __drm_mode_object_find(property->dev, NULL, value, 920 property->values[0]); 921 return *ref != NULL; 922 } 923 924 for (i = 0; i < property->num_values; i++) 925 if (property->values[i] == value) 926 return true; 927 return false; 928} 929 930void drm_property_change_valid_put(struct drm_property *property, 931 struct drm_mode_object *ref) 932{ 933 if (!ref) 934 return; 935 936 if (drm_property_type_is(property, DRM_MODE_PROP_OBJECT)) { 937 drm_mode_object_put(ref); 938 } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) 939 drm_property_blob_put(obj_to_blob(ref)); 940}