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