Commit f92f053b authored by Maarten Lankhorst's avatar Maarten Lankhorst Committed by Sean Paul

drm: Move property validation to a helper, v2.

Property lifetimes are equal to the device lifetime, so the separate
drm_property_find is not needed. The pointer can be retrieved from
the properties member, which saves us some locking and a extra lookup.
The lifetime for properties is until the device is destroyed, which
happens late in the device unload path.

kms_atomic is also testing for invalid properties which returns -ENOENT,
to be consistent return -ENOENT for valid properties that don't appear
on the object property list.

Changes since v1:
- Return -ENOENT for invalid properties to make kms_atomic pass.
- Change commit message slightly to take this into account.

Testcase: kms_atomic
Testcase: kms_properties
Fixes: 4e9951d9 ("drm/atomic: Reject properties not part of the object.")
Suggested-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: default avatarSean Paul <seanpaul@chromium.org>
Link: http://patchwork.freedesktop.org/patch/msgid/599c7fa8-b6fd-a42b-c619-a9e4a9c5c244@linux.intel.com
parent d25a4cbb
...@@ -1609,7 +1609,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -1609,7 +1609,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
struct drm_crtc_state *crtc_state; struct drm_crtc_state *crtc_state;
unsigned plane_mask; unsigned plane_mask;
int ret = 0; int ret = 0;
unsigned int i, j, k; unsigned int i, j;
/* disallow for drivers not supporting atomic: */ /* disallow for drivers not supporting atomic: */
if (!drm_core_check_feature(dev, DRIVER_ATOMIC)) if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
...@@ -1691,16 +1691,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev, ...@@ -1691,16 +1691,7 @@ int drm_mode_atomic_ioctl(struct drm_device *dev,
goto out; goto out;
} }
for (k = 0; k < obj->properties->count; k++) prop = drm_mode_obj_find_prop_id(obj, prop_id);
if (obj->properties->properties[k]->base.id == prop_id)
break;
if (k == obj->properties->count) {
ret = -EINVAL;
goto out;
}
prop = drm_property_find(dev, prop_id);
if (!prop) { if (!prop) {
drm_mode_object_unreference(obj); drm_mode_object_unreference(obj);
ret = -ENOENT; ret = -ENOENT;
......
...@@ -115,6 +115,8 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic, ...@@ -115,6 +115,8 @@ int drm_mode_object_get_properties(struct drm_mode_object *obj, bool atomic,
uint32_t __user *prop_ptr, uint32_t __user *prop_ptr,
uint64_t __user *prop_values, uint64_t __user *prop_values,
uint32_t *arg_count_props); uint32_t *arg_count_props);
struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
uint32_t prop_id);
/* IOCTL */ /* IOCTL */
......
...@@ -372,14 +372,25 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data, ...@@ -372,14 +372,25 @@ int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
return ret; return ret;
} }
struct drm_property *drm_mode_obj_find_prop_id(struct drm_mode_object *obj,
uint32_t prop_id)
{
int i;
for (i = 0; i < obj->properties->count; i++)
if (obj->properties->properties[i]->base.id == prop_id)
return obj->properties->properties[i];
return NULL;
}
int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
struct drm_mode_obj_set_property *arg = data; struct drm_mode_obj_set_property *arg = data;
struct drm_mode_object *arg_obj; struct drm_mode_object *arg_obj;
struct drm_mode_object *prop_obj;
struct drm_property *property; struct drm_property *property;
int i, ret = -EINVAL; int ret = -EINVAL;
struct drm_mode_object *ref; struct drm_mode_object *ref;
if (!drm_core_check_feature(dev, DRIVER_MODESET)) if (!drm_core_check_feature(dev, DRIVER_MODESET))
...@@ -392,23 +403,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data, ...@@ -392,23 +403,13 @@ int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
ret = -ENOENT; ret = -ENOENT;
goto out; goto out;
} }
if (!arg_obj->properties)
goto out_unref;
for (i = 0; i < arg_obj->properties->count; i++)
if (arg_obj->properties->properties[i]->base.id == arg->prop_id)
break;
if (i == arg_obj->properties->count) if (!arg_obj->properties)
goto out_unref; goto out_unref;
prop_obj = drm_mode_object_find(dev, arg->prop_id, property = drm_mode_obj_find_prop_id(arg_obj, arg->prop_id);
DRM_MODE_OBJECT_PROPERTY); if (!property)
if (!prop_obj) {
ret = -ENOENT;
goto out_unref; goto out_unref;
}
property = obj_to_property(prop_obj);
if (!drm_property_change_valid_get(property, arg->value, &ref)) if (!drm_property_change_valid_get(property, arg->value, &ref))
goto out_unref; goto out_unref;
......
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