When a new render node is created, the number of elements
of id_list allocated in drm_mode_group_init function should
not be the sum of all CRTCs, encoders, and connectors that
the device has, but the one specified by the ioctl that
created the node.

Signed-off-by: Ilija Hadzic <ihadzic at research.bell-labs.com>
---
 drivers/gpu/drm/drm_crtc.c |   16 +++++++---------
 drivers/gpu/drm/drm_stub.c |    5 ++---
 include/drm/drm_crtc.h     |    2 +-
 3 files changed, 10 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index f081873..1e0ff2d 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -933,14 +933,8 @@ void drm_mode_config_init(struct drm_device *dev)
 }
 EXPORT_SYMBOL(drm_mode_config_init);

-int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
+int drm_mode_group_init(struct drm_mode_group *group, int total_objects)
 {
-       uint32_t total_objects = 0;
-
-       total_objects += dev->mode_config.num_crtc;
-       total_objects += dev->mode_config.num_connector;
-       total_objects += dev->mode_config.num_encoder;
-
        group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL);
        if (!group->id_list)
                return -ENOMEM;
@@ -958,9 +952,13 @@ int drm_mode_group_init_legacy_group(struct drm_device 
*dev,
        struct drm_crtc *crtc;
        struct drm_encoder *encoder;
        struct drm_connector *connector;
-       int ret;
+       int ret, total_objects;

-       if ((ret = drm_mode_group_init(dev, group)))
+       total_objects = dev->mode_config.num_crtc;
+       total_objects += dev->mode_config.num_connector;
+       total_objects += dev->mode_config.num_encoder;
+       ret = drm_mode_group_init(group, total_objects);
+       if (ret)
                return ret;

        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c
index aa4b34f..e316a69 100644
--- a/drivers/gpu/drm/drm_stub.c
+++ b/drivers/gpu/drm/drm_stub.c
@@ -578,13 +578,12 @@ int drm_render_node_create_ioctl(struct drm_device *dev, 
void *data,
        ret = drm_create_render_node(dev, &new_minor);
        if (ret)
                return ret;
-
-       ret = drm_mode_group_init(dev, &new_minor->mode_group);
+       total_ids = args->num_crtc + args->num_encoder + args->num_connector;
+       ret = drm_mode_group_init(&new_minor->mode_group, total_ids);
        if (ret)
                goto out_del;

        ids_ptr = (uint32_t __user *)(unsigned long)args->id_list_ptr;
-       total_ids = args->num_crtc + args->num_encoder + args->num_connector;
        for (i = 0; i < total_ids; i++) {
                if (get_user(new_minor->mode_group.id_list[i], &ids_ptr[i])) {
                        ret = -EFAULT;
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index fc87b31..2110a82 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -849,7 +849,7 @@ extern char *drm_get_dvi_i_select_name(int val);
 extern char *drm_get_tv_subconnector_name(int val);
 extern char *drm_get_tv_select_name(int val);
 extern void drm_fb_release(struct drm_file *file_priv);
-extern int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group 
*group);
+extern int drm_mode_group_init(struct drm_mode_group *group, int 
total_objects);
 extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct 
drm_mode_group *group);
 extern struct edid *drm_get_edid(struct drm_connector *connector,
                                 struct i2c_adapter *adapter);
-- 
1.7.8.5

Reply via email to