]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/3.6.7/drm-set-dev_mapping-before-calling-drm_open_helper.patch
Linux 3.6.7
[thirdparty/kernel/stable-queue.git] / releases / 3.6.7 / drm-set-dev_mapping-before-calling-drm_open_helper.patch
CommitLineData
f660c16b
GKH
1From fdb40a08ef7bc970899c3a1f471165f9c22763a1 Mon Sep 17 00:00:00 2001
2From: Ilija Hadzic <ilijahadzic@gmail.com>
3Date: Mon, 29 Oct 2012 17:35:01 +0000
4Subject: drm: set dev_mapping before calling drm_open_helper
5
6From: Ilija Hadzic <ilijahadzic@gmail.com>
7
8commit fdb40a08ef7bc970899c3a1f471165f9c22763a1 upstream.
9
10Some drivers (specifically vmwgfx) look at dev_mapping
11in their open hook, so we have to set dev->dev_mapping
12earlier in the process.
13
14Reference:
15http://lists.freedesktop.org/archives/dri-devel/2012-October/029420.html
16
17Signed-off-by: Ilija Hadzic <ihadzic@research.bell-labs.com>
18Reported-by: Thomas Hellstrom <thellstrom@vmware.com>
19Reviewed-by: Thomas Hellstrom <thellstrom@vmware.com>
20Signed-off-by: Dave Airlie <airlied@redhat.com>
21Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22
23---
24 drivers/gpu/drm/drm_fops.c | 47 ++++++++++++++++++++++++++++-----------------
25 1 file changed, 30 insertions(+), 17 deletions(-)
26
27--- a/drivers/gpu/drm/drm_fops.c
28+++ b/drivers/gpu/drm/drm_fops.c
29@@ -121,6 +121,8 @@ int drm_open(struct inode *inode, struct
30 int minor_id = iminor(inode);
31 struct drm_minor *minor;
32 int retcode = 0;
33+ int need_setup = 0;
34+ struct address_space *old_mapping;
35
36 minor = idr_find(&drm_minors_idr, minor_id);
37 if (!minor)
38@@ -132,26 +134,37 @@ int drm_open(struct inode *inode, struct
39 if (drm_device_is_unplugged(dev))
40 return -ENODEV;
41
42+ if (!dev->open_count++)
43+ need_setup = 1;
44+ mutex_lock(&dev->struct_mutex);
45+ old_mapping = dev->dev_mapping;
46+ if (old_mapping == NULL)
47+ dev->dev_mapping = &inode->i_data;
48+ /* ihold ensures nobody can remove inode with our i_data */
49+ ihold(container_of(dev->dev_mapping, struct inode, i_data));
50+ inode->i_mapping = dev->dev_mapping;
51+ filp->f_mapping = dev->dev_mapping;
52+ mutex_unlock(&dev->struct_mutex);
53+
54 retcode = drm_open_helper(inode, filp, dev);
55- if (!retcode) {
56- atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
57- if (!dev->open_count++) {
58- retcode = drm_setup(dev);
59- if (retcode)
60- dev->open_count--;
61- }
62- }
63- if (!retcode) {
64- mutex_lock(&dev->struct_mutex);
65- if (dev->dev_mapping == NULL)
66- dev->dev_mapping = &inode->i_data;
67- /* ihold ensures nobody can remove inode with our i_data */
68- ihold(container_of(dev->dev_mapping, struct inode, i_data));
69- inode->i_mapping = dev->dev_mapping;
70- filp->f_mapping = dev->dev_mapping;
71- mutex_unlock(&dev->struct_mutex);
72+ if (retcode)
73+ goto err_undo;
74+ atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
75+ if (need_setup) {
76+ retcode = drm_setup(dev);
77+ if (retcode)
78+ goto err_undo;
79 }
80+ return 0;
81
82+err_undo:
83+ mutex_lock(&dev->struct_mutex);
84+ filp->f_mapping = old_mapping;
85+ inode->i_mapping = old_mapping;
86+ iput(container_of(dev->dev_mapping, struct inode, i_data));
87+ dev->dev_mapping = old_mapping;
88+ mutex_unlock(&dev->struct_mutex);
89+ dev->open_count--;
90 return retcode;
91 }
92 EXPORT_SYMBOL(drm_open);