From: Stuart Abercrombie <sabercrombie@xxxxxxxxxxxx> In several places, including the interrupt handler, the i915 driver assumes it can deref. dev->primary->master->driver_priv if dev->primary->master is non-NULL. This wasn't true if drm_open_helper was midway through, so rearrange the initialization order. v2: Address this in drm_open_helper instead of the various access points -- basically Stephane's fix. Signed-off-by: Stuart Abercrombie <sabercrombie@xxxxxxxxxxxx> Signed-off-by: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> --- drivers/gpu/drm/drm_fops.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c index 7f2af9a..3df3032 100644 --- a/drivers/gpu/drm/drm_fops.c +++ b/drivers/gpu/drm/drm_fops.c @@ -260,9 +260,11 @@ static int drm_open_helper(struct inode *inode, struct file *filp, * any master object for render clients */ mutex_lock(&dev->struct_mutex); if (!priv->minor->master && !drm_is_render_client(priv)) { - /* create a new master */ - priv->minor->master = drm_master_create(priv->minor); - if (!priv->minor->master) { + /* create a new master but don't assign it yet + * to ensure master->driver_priv is set up first + */ + struct drm_master *master_ptr = drm_master_create(priv->minor); + if (!master_ptr) { mutex_unlock(&dev->struct_mutex); ret = -ENOMEM; goto out_close; @@ -270,7 +272,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, priv->is_master = 1; /* take another reference for the copy in the local file priv */ - priv->master = drm_master_get(priv->minor->master); + priv->master = drm_master_get(master_ptr); priv->authenticated = 1; @@ -280,7 +282,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp, if (ret) { mutex_lock(&dev->struct_mutex); /* drop both references if this fails */ - drm_master_put(&priv->minor->master); + drm_master_put(&master_ptr); drm_master_put(&priv->master); mutex_unlock(&dev->struct_mutex); goto out_close; @@ -291,12 +293,13 @@ static int drm_open_helper(struct inode *inode, struct file *filp, ret = dev->driver->master_set(dev, priv, true); if (ret) { /* drop both references if this fails */ - drm_master_put(&priv->minor->master); + drm_master_put(&master_ptr); drm_master_put(&priv->master); mutex_unlock(&dev->struct_mutex); goto out_close; } } + priv->minor->master = master_ptr; } else if (!drm_is_render_client(priv)) { /* get a reference to the master */ priv->master = drm_master_get(priv->minor->master); -- 1.9.0.rc1.175.g0b1dcb5 _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel