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