diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2012-03-13 06:35:48 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2012-03-15 05:52:30 -0400 |
commit | 6bfc56aa89f963becbafbaeb105b6a84e0eb0db7 (patch) | |
tree | 46798969a078d0e14e34ebaa13d2b24d0a53e58d | |
parent | 93bbf6dbdadbb47ef5a19aecf45669c01ee8830d (diff) |
drm: Handle drm_object_get() failures
Check drm_mode_object_get() return value everywhere.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 95 | ||||
-rw-r--r-- | drivers/gpu/drm/drm_crtc_helper.c | 2 | ||||
-rw-r--r-- | include/drm/drm_crtc.h | 22 |
3 files changed, 85 insertions, 34 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index e36bd43aaa14..f5b098e50bb1 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -293,9 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, | |||
293 | int ret; | 293 | int ret; |
294 | 294 | ||
295 | ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); | 295 | ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); |
296 | if (ret) { | 296 | if (ret) |
297 | return ret; | 297 | return ret; |
298 | } | ||
299 | 298 | ||
300 | fb->dev = dev; | 299 | fb->dev = dev; |
301 | fb->funcs = funcs; | 300 | fb->funcs = funcs; |
@@ -365,19 +364,31 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); | |||
365 | * Caller must hold mode config lock. | 364 | * Caller must hold mode config lock. |
366 | * | 365 | * |
367 | * Inits a new object created as base part of an driver crtc object. | 366 | * Inits a new object created as base part of an driver crtc object. |
367 | * | ||
368 | * RETURNS: | ||
369 | * Zero on success, error code on failure. | ||
368 | */ | 370 | */ |
369 | void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, | 371 | int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, |
370 | const struct drm_crtc_funcs *funcs) | 372 | const struct drm_crtc_funcs *funcs) |
371 | { | 373 | { |
374 | int ret; | ||
375 | |||
372 | crtc->dev = dev; | 376 | crtc->dev = dev; |
373 | crtc->funcs = funcs; | 377 | crtc->funcs = funcs; |
374 | 378 | ||
375 | mutex_lock(&dev->mode_config.mutex); | 379 | mutex_lock(&dev->mode_config.mutex); |
376 | drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); | 380 | |
381 | ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC); | ||
382 | if (ret) | ||
383 | goto out; | ||
377 | 384 | ||
378 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); | 385 | list_add_tail(&crtc->head, &dev->mode_config.crtc_list); |
379 | dev->mode_config.num_crtc++; | 386 | dev->mode_config.num_crtc++; |
387 | |||
388 | out: | ||
380 | mutex_unlock(&dev->mode_config.mutex); | 389 | mutex_unlock(&dev->mode_config.mutex); |
390 | |||
391 | return ret; | ||
381 | } | 392 | } |
382 | EXPORT_SYMBOL(drm_crtc_init); | 393 | EXPORT_SYMBOL(drm_crtc_init); |
383 | 394 | ||
@@ -453,17 +464,25 @@ EXPORT_SYMBOL(drm_mode_remove); | |||
453 | * | 464 | * |
454 | * Initialises a preallocated connector. Connectors should be | 465 | * Initialises a preallocated connector. Connectors should be |
455 | * subclassed as part of driver connector objects. | 466 | * subclassed as part of driver connector objects. |
467 | * | ||
468 | * RETURNS: | ||
469 | * Zero on success, error code on failure. | ||
456 | */ | 470 | */ |
457 | void drm_connector_init(struct drm_device *dev, | 471 | int drm_connector_init(struct drm_device *dev, |
458 | struct drm_connector *connector, | 472 | struct drm_connector *connector, |
459 | const struct drm_connector_funcs *funcs, | 473 | const struct drm_connector_funcs *funcs, |
460 | int connector_type) | 474 | int connector_type) |
461 | { | 475 | { |
476 | int ret; | ||
477 | |||
462 | mutex_lock(&dev->mode_config.mutex); | 478 | mutex_lock(&dev->mode_config.mutex); |
463 | 479 | ||
480 | ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); | ||
481 | if (ret) | ||
482 | goto out; | ||
483 | |||
464 | connector->dev = dev; | 484 | connector->dev = dev; |
465 | connector->funcs = funcs; | 485 | connector->funcs = funcs; |
466 | drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR); | ||
467 | connector->connector_type = connector_type; | 486 | connector->connector_type = connector_type; |
468 | connector->connector_type_id = | 487 | connector->connector_type_id = |
469 | ++drm_connector_enum_list[connector_type].count; /* TODO */ | 488 | ++drm_connector_enum_list[connector_type].count; /* TODO */ |
@@ -483,7 +502,10 @@ void drm_connector_init(struct drm_device *dev, | |||
483 | drm_connector_attach_property(connector, | 502 | drm_connector_attach_property(connector, |
484 | dev->mode_config.dpms_property, 0); | 503 | dev->mode_config.dpms_property, 0); |
485 | 504 | ||
505 | out: | ||
486 | mutex_unlock(&dev->mode_config.mutex); | 506 | mutex_unlock(&dev->mode_config.mutex); |
507 | |||
508 | return ret; | ||
487 | } | 509 | } |
488 | EXPORT_SYMBOL(drm_connector_init); | 510 | EXPORT_SYMBOL(drm_connector_init); |
489 | 511 | ||
@@ -518,23 +540,30 @@ void drm_connector_cleanup(struct drm_connector *connector) | |||
518 | } | 540 | } |
519 | EXPORT_SYMBOL(drm_connector_cleanup); | 541 | EXPORT_SYMBOL(drm_connector_cleanup); |
520 | 542 | ||
521 | void drm_encoder_init(struct drm_device *dev, | 543 | int drm_encoder_init(struct drm_device *dev, |
522 | struct drm_encoder *encoder, | 544 | struct drm_encoder *encoder, |
523 | const struct drm_encoder_funcs *funcs, | 545 | const struct drm_encoder_funcs *funcs, |
524 | int encoder_type) | 546 | int encoder_type) |
525 | { | 547 | { |
548 | int ret; | ||
549 | |||
526 | mutex_lock(&dev->mode_config.mutex); | 550 | mutex_lock(&dev->mode_config.mutex); |
527 | 551 | ||
528 | encoder->dev = dev; | 552 | ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); |
553 | if (ret) | ||
554 | goto out; | ||
529 | 555 | ||
530 | drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); | 556 | encoder->dev = dev; |
531 | encoder->encoder_type = encoder_type; | 557 | encoder->encoder_type = encoder_type; |
532 | encoder->funcs = funcs; | 558 | encoder->funcs = funcs; |
533 | 559 | ||
534 | list_add_tail(&encoder->head, &dev->mode_config.encoder_list); | 560 | list_add_tail(&encoder->head, &dev->mode_config.encoder_list); |
535 | dev->mode_config.num_encoder++; | 561 | dev->mode_config.num_encoder++; |
536 | 562 | ||
563 | out: | ||
537 | mutex_unlock(&dev->mode_config.mutex); | 564 | mutex_unlock(&dev->mode_config.mutex); |
565 | |||
566 | return ret; | ||
538 | } | 567 | } |
539 | EXPORT_SYMBOL(drm_encoder_init); | 568 | EXPORT_SYMBOL(drm_encoder_init); |
540 | 569 | ||
@@ -555,18 +584,23 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
555 | const uint32_t *formats, uint32_t format_count, | 584 | const uint32_t *formats, uint32_t format_count, |
556 | bool priv) | 585 | bool priv) |
557 | { | 586 | { |
587 | int ret; | ||
588 | |||
558 | mutex_lock(&dev->mode_config.mutex); | 589 | mutex_lock(&dev->mode_config.mutex); |
559 | 590 | ||
591 | ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); | ||
592 | if (ret) | ||
593 | goto out; | ||
594 | |||
560 | plane->dev = dev; | 595 | plane->dev = dev; |
561 | drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE); | ||
562 | plane->funcs = funcs; | 596 | plane->funcs = funcs; |
563 | plane->format_types = kmalloc(sizeof(uint32_t) * format_count, | 597 | plane->format_types = kmalloc(sizeof(uint32_t) * format_count, |
564 | GFP_KERNEL); | 598 | GFP_KERNEL); |
565 | if (!plane->format_types) { | 599 | if (!plane->format_types) { |
566 | DRM_DEBUG_KMS("out of memory when allocating plane\n"); | 600 | DRM_DEBUG_KMS("out of memory when allocating plane\n"); |
567 | drm_mode_object_put(dev, &plane->base); | 601 | drm_mode_object_put(dev, &plane->base); |
568 | mutex_unlock(&dev->mode_config.mutex); | 602 | ret = -ENOMEM; |
569 | return -ENOMEM; | 603 | goto out; |
570 | } | 604 | } |
571 | 605 | ||
572 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); | 606 | memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); |
@@ -584,9 +618,10 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, | |||
584 | INIT_LIST_HEAD(&plane->head); | 618 | INIT_LIST_HEAD(&plane->head); |
585 | } | 619 | } |
586 | 620 | ||
621 | out: | ||
587 | mutex_unlock(&dev->mode_config.mutex); | 622 | mutex_unlock(&dev->mode_config.mutex); |
588 | 623 | ||
589 | return 0; | 624 | return ret; |
590 | } | 625 | } |
591 | EXPORT_SYMBOL(drm_plane_init); | 626 | EXPORT_SYMBOL(drm_plane_init); |
592 | 627 | ||
@@ -626,7 +661,11 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev) | |||
626 | if (!nmode) | 661 | if (!nmode) |
627 | return NULL; | 662 | return NULL; |
628 | 663 | ||
629 | drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE); | 664 | if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) { |
665 | kfree(nmode); | ||
666 | return NULL; | ||
667 | } | ||
668 | |||
630 | return nmode; | 669 | return nmode; |
631 | } | 670 | } |
632 | EXPORT_SYMBOL(drm_mode_create); | 671 | EXPORT_SYMBOL(drm_mode_create); |
@@ -2597,6 +2636,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, | |||
2597 | const char *name, int num_values) | 2636 | const char *name, int num_values) |
2598 | { | 2637 | { |
2599 | struct drm_property *property = NULL; | 2638 | struct drm_property *property = NULL; |
2639 | int ret; | ||
2600 | 2640 | ||
2601 | property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); | 2641 | property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); |
2602 | if (!property) | 2642 | if (!property) |
@@ -2608,7 +2648,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, | |||
2608 | goto fail; | 2648 | goto fail; |
2609 | } | 2649 | } |
2610 | 2650 | ||
2611 | drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); | 2651 | ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); |
2652 | if (ret) | ||
2653 | goto fail; | ||
2654 | |||
2612 | property->flags = flags; | 2655 | property->flags = flags; |
2613 | property->num_values = num_values; | 2656 | property->num_values = num_values; |
2614 | INIT_LIST_HEAD(&property->enum_blob_list); | 2657 | INIT_LIST_HEAD(&property->enum_blob_list); |
@@ -2621,6 +2664,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, | |||
2621 | list_add_tail(&property->head, &dev->mode_config.property_list); | 2664 | list_add_tail(&property->head, &dev->mode_config.property_list); |
2622 | return property; | 2665 | return property; |
2623 | fail: | 2666 | fail: |
2667 | kfree(property->values); | ||
2624 | kfree(property); | 2668 | kfree(property); |
2625 | return NULL; | 2669 | return NULL; |
2626 | } | 2670 | } |
@@ -2884,6 +2928,7 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev | |||
2884 | void *data) | 2928 | void *data) |
2885 | { | 2929 | { |
2886 | struct drm_property_blob *blob; | 2930 | struct drm_property_blob *blob; |
2931 | int ret; | ||
2887 | 2932 | ||
2888 | if (!length || !data) | 2933 | if (!length || !data) |
2889 | return NULL; | 2934 | return NULL; |
@@ -2892,13 +2937,17 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev | |||
2892 | if (!blob) | 2937 | if (!blob) |
2893 | return NULL; | 2938 | return NULL; |
2894 | 2939 | ||
2940 | ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); | ||
2941 | if (ret) { | ||
2942 | kfree(blob); | ||
2943 | return NULL; | ||
2944 | } | ||
2945 | |||
2895 | blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); | 2946 | blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); |
2896 | blob->length = length; | 2947 | blob->length = length; |
2897 | 2948 | ||
2898 | memcpy(blob->data, data, length); | 2949 | memcpy(blob->data, data, length); |
2899 | 2950 | ||
2900 | drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB); | ||
2901 | |||
2902 | list_add_tail(&blob->head, &dev->mode_config.property_blob_list); | 2951 | list_add_tail(&blob->head, &dev->mode_config.property_blob_list); |
2903 | return blob; | 2952 | return blob; |
2904 | } | 2953 | } |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index d761d1241152..d9d66846c610 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -352,6 +352,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, | |||
352 | return true; | 352 | return true; |
353 | 353 | ||
354 | adjusted_mode = drm_mode_duplicate(dev, mode); | 354 | adjusted_mode = drm_mode_duplicate(dev, mode); |
355 | if (!adjusted_mode) | ||
356 | return false; | ||
355 | 357 | ||
356 | saved_hwmode = crtc->hwmode; | 358 | saved_hwmode = crtc->hwmode; |
357 | saved_mode = crtc->mode; | 359 | saved_mode = crtc->mode; |
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index fe7ebc6b8c93..00f4007a6d04 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h | |||
@@ -815,22 +815,22 @@ struct drm_prop_enum_list { | |||
815 | char *name; | 815 | char *name; |
816 | }; | 816 | }; |
817 | 817 | ||
818 | extern void drm_crtc_init(struct drm_device *dev, | 818 | extern int drm_crtc_init(struct drm_device *dev, |
819 | struct drm_crtc *crtc, | 819 | struct drm_crtc *crtc, |
820 | const struct drm_crtc_funcs *funcs); | 820 | const struct drm_crtc_funcs *funcs); |
821 | extern void drm_crtc_cleanup(struct drm_crtc *crtc); | 821 | extern void drm_crtc_cleanup(struct drm_crtc *crtc); |
822 | 822 | ||
823 | extern void drm_connector_init(struct drm_device *dev, | 823 | extern int drm_connector_init(struct drm_device *dev, |
824 | struct drm_connector *connector, | 824 | struct drm_connector *connector, |
825 | const struct drm_connector_funcs *funcs, | 825 | const struct drm_connector_funcs *funcs, |
826 | int connector_type); | 826 | int connector_type); |
827 | 827 | ||
828 | extern void drm_connector_cleanup(struct drm_connector *connector); | 828 | extern void drm_connector_cleanup(struct drm_connector *connector); |
829 | 829 | ||
830 | extern void drm_encoder_init(struct drm_device *dev, | 830 | extern int drm_encoder_init(struct drm_device *dev, |
831 | struct drm_encoder *encoder, | 831 | struct drm_encoder *encoder, |
832 | const struct drm_encoder_funcs *funcs, | 832 | const struct drm_encoder_funcs *funcs, |
833 | int encoder_type); | 833 | int encoder_type); |
834 | 834 | ||
835 | extern int drm_plane_init(struct drm_device *dev, | 835 | extern int drm_plane_init(struct drm_device *dev, |
836 | struct drm_plane *plane, | 836 | struct drm_plane *plane, |