diff options
Diffstat (limited to 'drivers/gpu/drm/drm_crtc.c')
| -rw-r--r-- | drivers/gpu/drm/drm_crtc.c | 63 | 
1 files changed, 31 insertions, 32 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index ef1b22144d3..f2d667b8bee 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c @@ -470,10 +470,8 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)  {  	struct drm_device *dev = crtc->dev; -	if (crtc->gamma_store) { -		kfree(crtc->gamma_store); -		crtc->gamma_store = NULL; -	} +	kfree(crtc->gamma_store); +	crtc->gamma_store = NULL;  	drm_mode_object_put(dev, &crtc->base);  	list_del(&crtc->head); @@ -555,16 +553,17 @@ int drm_connector_init(struct drm_device *dev,  	INIT_LIST_HEAD(&connector->probed_modes);  	INIT_LIST_HEAD(&connector->modes);  	connector->edid_blob_ptr = NULL; +	connector->status = connector_status_unknown;  	list_add_tail(&connector->head, &dev->mode_config.connector_list);  	dev->mode_config.num_connector++;  	if (connector_type != DRM_MODE_CONNECTOR_VIRTUAL) -		drm_connector_attach_property(connector, +		drm_object_attach_property(&connector->base,  					      dev->mode_config.edid_property,  					      0); -	drm_connector_attach_property(connector, +	drm_object_attach_property(&connector->base,  				      dev->mode_config.dpms_property, 0);   out: @@ -2280,13 +2279,21 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)  	for (i = 0; i < num_planes; i++) {  		unsigned int width = r->width / (i != 0 ? hsub : 1); +		unsigned int height = r->height / (i != 0 ? vsub : 1); +		unsigned int cpp = drm_format_plane_cpp(r->pixel_format, i);  		if (!r->handles[i]) {  			DRM_DEBUG_KMS("no buffer object handle for plane %d\n", i);  			return -EINVAL;  		} -		if (r->pitches[i] < drm_format_plane_cpp(r->pixel_format, i) * width) { +		if ((uint64_t) width * cpp > UINT_MAX) +			return -ERANGE; + +		if ((uint64_t) height * r->pitches[i] + r->offsets[i] > UINT_MAX) +			return -ERANGE; + +		if (r->pitches[i] < width * cpp) {  			DRM_DEBUG_KMS("bad pitch %u for plane %d\n", r->pitches[i], i);  			return -EINVAL;  		} @@ -2323,6 +2330,11 @@ int drm_mode_addfb2(struct drm_device *dev,  	if (!drm_core_check_feature(dev, DRIVER_MODESET))  		return -EINVAL; +	if (r->flags & ~DRM_MODE_FB_INTERLACED) { +		DRM_DEBUG_KMS("bad framebuffer flags 0x%08x\n", r->flags); +		return -EINVAL; +	} +  	if ((config->min_width > r->width) || (r->width > config->max_width)) {  		DRM_DEBUG_KMS("bad framebuffer width %d, should be >= %d && <= %d\n",  			  r->width, config->min_width, config->max_width); @@ -2916,27 +2928,6 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)  }  EXPORT_SYMBOL(drm_property_destroy); -void drm_connector_attach_property(struct drm_connector *connector, -			       struct drm_property *property, uint64_t init_val) -{ -	drm_object_attach_property(&connector->base, property, init_val); -} -EXPORT_SYMBOL(drm_connector_attach_property); - -int drm_connector_property_set_value(struct drm_connector *connector, -				  struct drm_property *property, uint64_t value) -{ -	return drm_object_property_set_value(&connector->base, property, value); -} -EXPORT_SYMBOL(drm_connector_property_set_value); - -int drm_connector_property_get_value(struct drm_connector *connector, -				  struct drm_property *property, uint64_t *val) -{ -	return drm_object_property_get_value(&connector->base, property, val); -} -EXPORT_SYMBOL(drm_connector_property_get_value); -  void drm_object_attach_property(struct drm_mode_object *obj,  				struct drm_property *property,  				uint64_t init_val) @@ -3173,15 +3164,17 @@ int drm_mode_connector_update_edid_property(struct drm_connector *connector,  	/* Delete edid, when there is none. */  	if (!edid) {  		connector->edid_blob_ptr = NULL; -		ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, 0); +		ret = drm_object_property_set_value(&connector->base, dev->mode_config.edid_property, 0);  		return ret;  	}  	size = EDID_LENGTH * (1 + edid->extensions);  	connector->edid_blob_ptr = drm_property_create_blob(connector->dev,  							    size, edid); +	if (!connector->edid_blob_ptr) +		return -EINVAL; -	ret = drm_connector_property_set_value(connector, +	ret = drm_object_property_set_value(&connector->base,  					       dev->mode_config.edid_property,  					       connector->edid_blob_ptr->base.id); @@ -3204,6 +3197,9 @@ static bool drm_property_change_is_valid(struct drm_property *property,  		for (i = 0; i < property->num_values; i++)  			valid_mask |= (1ULL << property->values[i]);  		return !(value & ~valid_mask); +	} else if (property->flags & DRM_MODE_PROP_BLOB) { +		/* Only the driver knows */ +		return true;  	} else {  		int i;  		for (i = 0; i < property->num_values; i++) @@ -3245,7 +3241,7 @@ static int drm_mode_connector_set_obj_prop(struct drm_mode_object *obj,  	/* store the property value if successful */  	if (!ret) -		drm_connector_property_set_value(connector, property, value); +		drm_object_property_set_value(&connector->base, property, value);  	return ret;  } @@ -3656,9 +3652,12 @@ void drm_mode_config_reset(struct drm_device *dev)  		if (encoder->funcs->reset)  			encoder->funcs->reset(encoder); -	list_for_each_entry(connector, &dev->mode_config.connector_list, head) +	list_for_each_entry(connector, &dev->mode_config.connector_list, head) { +		connector->status = connector_status_unknown; +  		if (connector->funcs->reset)  			connector->funcs->reset(connector); +	}  }  EXPORT_SYMBOL(drm_mode_config_reset);  |