Commit 6bfc56aa authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Dave Airlie

drm: Handle drm_object_get() failures

Check drm_mode_object_get() return value everywhere.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarAlex Deucher <alexander.deucher@amd.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 93bbf6db
...@@ -293,9 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb, ...@@ -293,9 +293,8 @@ int drm_framebuffer_init(struct drm_device *dev, struct drm_framebuffer *fb,
int ret; int ret;
ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB); ret = drm_mode_object_get(dev, &fb->base, DRM_MODE_OBJECT_FB);
if (ret) { if (ret)
return ret; return ret;
}
fb->dev = dev; fb->dev = dev;
fb->funcs = funcs; fb->funcs = funcs;
...@@ -365,19 +364,31 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup); ...@@ -365,19 +364,31 @@ EXPORT_SYMBOL(drm_framebuffer_cleanup);
* Caller must hold mode config lock. * Caller must hold mode config lock.
* *
* Inits a new object created as base part of an driver crtc object. * Inits a new object created as base part of an driver crtc object.
*
* RETURNS:
* Zero on success, error code on failure.
*/ */
void drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs) const struct drm_crtc_funcs *funcs)
{ {
int ret;
crtc->dev = dev; crtc->dev = dev;
crtc->funcs = funcs; crtc->funcs = funcs;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
if (ret)
goto out;
list_add_tail(&crtc->head, &dev->mode_config.crtc_list); list_add_tail(&crtc->head, &dev->mode_config.crtc_list);
dev->mode_config.num_crtc++; dev->mode_config.num_crtc++;
out:
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return ret;
} }
EXPORT_SYMBOL(drm_crtc_init); EXPORT_SYMBOL(drm_crtc_init);
...@@ -453,17 +464,25 @@ EXPORT_SYMBOL(drm_mode_remove); ...@@ -453,17 +464,25 @@ EXPORT_SYMBOL(drm_mode_remove);
* *
* Initialises a preallocated connector. Connectors should be * Initialises a preallocated connector. Connectors should be
* subclassed as part of driver connector objects. * subclassed as part of driver connector objects.
*
* RETURNS:
* Zero on success, error code on failure.
*/ */
void drm_connector_init(struct drm_device *dev, int drm_connector_init(struct drm_device *dev,
struct drm_connector *connector, struct drm_connector *connector,
const struct drm_connector_funcs *funcs, const struct drm_connector_funcs *funcs,
int connector_type) int connector_type)
{ {
int ret;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
ret = drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
if (ret)
goto out;
connector->dev = dev; connector->dev = dev;
connector->funcs = funcs; connector->funcs = funcs;
drm_mode_object_get(dev, &connector->base, DRM_MODE_OBJECT_CONNECTOR);
connector->connector_type = connector_type; connector->connector_type = connector_type;
connector->connector_type_id = connector->connector_type_id =
++drm_connector_enum_list[connector_type].count; /* TODO */ ++drm_connector_enum_list[connector_type].count; /* TODO */
...@@ -483,7 +502,10 @@ void drm_connector_init(struct drm_device *dev, ...@@ -483,7 +502,10 @@ void drm_connector_init(struct drm_device *dev,
drm_connector_attach_property(connector, drm_connector_attach_property(connector,
dev->mode_config.dpms_property, 0); dev->mode_config.dpms_property, 0);
out:
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return ret;
} }
EXPORT_SYMBOL(drm_connector_init); EXPORT_SYMBOL(drm_connector_init);
...@@ -518,23 +540,30 @@ void drm_connector_cleanup(struct drm_connector *connector) ...@@ -518,23 +540,30 @@ void drm_connector_cleanup(struct drm_connector *connector)
} }
EXPORT_SYMBOL(drm_connector_cleanup); EXPORT_SYMBOL(drm_connector_cleanup);
void drm_encoder_init(struct drm_device *dev, int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder, struct drm_encoder *encoder,
const struct drm_encoder_funcs *funcs, const struct drm_encoder_funcs *funcs,
int encoder_type) int encoder_type)
{ {
int ret;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
encoder->dev = dev; ret = drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER);
if (ret)
goto out;
drm_mode_object_get(dev, &encoder->base, DRM_MODE_OBJECT_ENCODER); encoder->dev = dev;
encoder->encoder_type = encoder_type; encoder->encoder_type = encoder_type;
encoder->funcs = funcs; encoder->funcs = funcs;
list_add_tail(&encoder->head, &dev->mode_config.encoder_list); list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
dev->mode_config.num_encoder++; dev->mode_config.num_encoder++;
out:
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return ret;
} }
EXPORT_SYMBOL(drm_encoder_init); EXPORT_SYMBOL(drm_encoder_init);
...@@ -555,18 +584,23 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane, ...@@ -555,18 +584,23 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
const uint32_t *formats, uint32_t format_count, const uint32_t *formats, uint32_t format_count,
bool priv) bool priv)
{ {
int ret;
mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->mode_config.mutex);
ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
if (ret)
goto out;
plane->dev = dev; plane->dev = dev;
drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
plane->funcs = funcs; plane->funcs = funcs;
plane->format_types = kmalloc(sizeof(uint32_t) * format_count, plane->format_types = kmalloc(sizeof(uint32_t) * format_count,
GFP_KERNEL); GFP_KERNEL);
if (!plane->format_types) { if (!plane->format_types) {
DRM_DEBUG_KMS("out of memory when allocating plane\n"); DRM_DEBUG_KMS("out of memory when allocating plane\n");
drm_mode_object_put(dev, &plane->base); drm_mode_object_put(dev, &plane->base);
mutex_unlock(&dev->mode_config.mutex); ret = -ENOMEM;
return -ENOMEM; goto out;
} }
memcpy(plane->format_types, formats, format_count * sizeof(uint32_t)); 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,9 +618,10 @@ int drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
INIT_LIST_HEAD(&plane->head); INIT_LIST_HEAD(&plane->head);
} }
out:
mutex_unlock(&dev->mode_config.mutex); mutex_unlock(&dev->mode_config.mutex);
return 0; return ret;
} }
EXPORT_SYMBOL(drm_plane_init); EXPORT_SYMBOL(drm_plane_init);
...@@ -626,7 +661,11 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev) ...@@ -626,7 +661,11 @@ struct drm_display_mode *drm_mode_create(struct drm_device *dev)
if (!nmode) if (!nmode)
return NULL; return NULL;
drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE); if (drm_mode_object_get(dev, &nmode->base, DRM_MODE_OBJECT_MODE)) {
kfree(nmode);
return NULL;
}
return nmode; return nmode;
} }
EXPORT_SYMBOL(drm_mode_create); EXPORT_SYMBOL(drm_mode_create);
...@@ -2597,6 +2636,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, ...@@ -2597,6 +2636,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
const char *name, int num_values) const char *name, int num_values)
{ {
struct drm_property *property = NULL; struct drm_property *property = NULL;
int ret;
property = kzalloc(sizeof(struct drm_property), GFP_KERNEL); property = kzalloc(sizeof(struct drm_property), GFP_KERNEL);
if (!property) if (!property)
...@@ -2608,7 +2648,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, ...@@ -2608,7 +2648,10 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
goto fail; goto fail;
} }
drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY); ret = drm_mode_object_get(dev, &property->base, DRM_MODE_OBJECT_PROPERTY);
if (ret)
goto fail;
property->flags = flags; property->flags = flags;
property->num_values = num_values; property->num_values = num_values;
INIT_LIST_HEAD(&property->enum_blob_list); INIT_LIST_HEAD(&property->enum_blob_list);
...@@ -2621,6 +2664,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, ...@@ -2621,6 +2664,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags,
list_add_tail(&property->head, &dev->mode_config.property_list); list_add_tail(&property->head, &dev->mode_config.property_list);
return property; return property;
fail: fail:
kfree(property->values);
kfree(property); kfree(property);
return NULL; return NULL;
} }
...@@ -2884,6 +2928,7 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev ...@@ -2884,6 +2928,7 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev
void *data) void *data)
{ {
struct drm_property_blob *blob; struct drm_property_blob *blob;
int ret;
if (!length || !data) if (!length || !data)
return NULL; return NULL;
...@@ -2892,13 +2937,17 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev ...@@ -2892,13 +2937,17 @@ static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev
if (!blob) if (!blob)
return NULL; return NULL;
ret = drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
if (ret) {
kfree(blob);
return NULL;
}
blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob)); blob->data = (void *)((char *)blob + sizeof(struct drm_property_blob));
blob->length = length; blob->length = length;
memcpy(blob->data, data, length); memcpy(blob->data, data, length);
drm_mode_object_get(dev, &blob->base, DRM_MODE_OBJECT_BLOB);
list_add_tail(&blob->head, &dev->mode_config.property_blob_list); list_add_tail(&blob->head, &dev->mode_config.property_blob_list);
return blob; return blob;
} }
......
...@@ -352,6 +352,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, ...@@ -352,6 +352,8 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
return true; return true;
adjusted_mode = drm_mode_duplicate(dev, mode); adjusted_mode = drm_mode_duplicate(dev, mode);
if (!adjusted_mode)
return false;
saved_hwmode = crtc->hwmode; saved_hwmode = crtc->hwmode;
saved_mode = crtc->mode; saved_mode = crtc->mode;
......
...@@ -815,22 +815,22 @@ struct drm_prop_enum_list { ...@@ -815,22 +815,22 @@ struct drm_prop_enum_list {
char *name; char *name;
}; };
extern void drm_crtc_init(struct drm_device *dev, extern int drm_crtc_init(struct drm_device *dev,
struct drm_crtc *crtc, struct drm_crtc *crtc,
const struct drm_crtc_funcs *funcs); const struct drm_crtc_funcs *funcs);
extern void drm_crtc_cleanup(struct drm_crtc *crtc); extern void drm_crtc_cleanup(struct drm_crtc *crtc);
extern void drm_connector_init(struct drm_device *dev, extern int drm_connector_init(struct drm_device *dev,
struct drm_connector *connector, struct drm_connector *connector,
const struct drm_connector_funcs *funcs, const struct drm_connector_funcs *funcs,
int connector_type); int connector_type);
extern void drm_connector_cleanup(struct drm_connector *connector); extern void drm_connector_cleanup(struct drm_connector *connector);
extern void drm_encoder_init(struct drm_device *dev, extern int drm_encoder_init(struct drm_device *dev,
struct drm_encoder *encoder, struct drm_encoder *encoder,
const struct drm_encoder_funcs *funcs, const struct drm_encoder_funcs *funcs,
int encoder_type); int encoder_type);
extern int drm_plane_init(struct drm_device *dev, extern int drm_plane_init(struct drm_device *dev,
struct drm_plane *plane, struct drm_plane *plane,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment