aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/drm/drm_drawable.c35
-rw-r--r--drivers/char/drm/drm_drv.c12
2 files changed, 35 insertions, 12 deletions
diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
index 5580c5731eb8..ce7a027b0ad4 100644
--- a/drivers/char/drm/drm_drawable.c
+++ b/drivers/char/drm/drm_drawable.c
@@ -92,13 +92,13 @@ done:
92 bitfield[i] = 0; 92 bitfield[i] = 0;
93 } 93 }
94 94
95 draw.handle = i * 8 * sizeof(*bitfield) + j; 95 draw.handle = i * 8 * sizeof(*bitfield) + j + 1;
96 DRM_DEBUG("%d\n", draw.handle); 96 DRM_DEBUG("%d\n", draw.handle);
97 97
98 spin_lock_irqsave(&dev->drw_lock, irqflags); 98 spin_lock_irqsave(&dev->drw_lock, irqflags);
99 99
100 bitfield[i] |= 1 << j; 100 bitfield[i] |= 1 << j;
101 info[draw.handle] = NULL; 101 info[draw.handle - 1] = NULL;
102 102
103 if (bitfield != dev->drw_bitfield) { 103 if (bitfield != dev->drw_bitfield) {
104 memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length * 104 memcpy(bitfield, dev->drw_bitfield, dev->drw_bitfield_length *
@@ -132,7 +132,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
132{ 132{
133 DRM_DEVICE; 133 DRM_DEVICE;
134 drm_draw_t draw; 134 drm_draw_t draw;
135 unsigned int idx, shift; 135 unsigned int id, idx, shift;
136 unsigned long irqflags; 136 unsigned long irqflags;
137 u32 *bitfield = dev->drw_bitfield; 137 u32 *bitfield = dev->drw_bitfield;
138 unsigned int bitfield_length = dev->drw_bitfield_length; 138 unsigned int bitfield_length = dev->drw_bitfield_length;
@@ -142,10 +142,11 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
142 DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data, 142 DRM_COPY_FROM_USER_IOCTL(draw, (drm_draw_t __user *) data,
143 sizeof(draw)); 143 sizeof(draw));
144 144
145 idx = draw.handle / (8 * sizeof(*bitfield)); 145 id = draw.handle - 1;
146 shift = draw.handle % (8 * sizeof(*bitfield)); 146 idx = id / (8 * sizeof(*bitfield));
147 shift = id % (8 * sizeof(*bitfield));
147 148
148 if (idx >= bitfield_length || 149 if (idx < 0 || idx >= bitfield_length ||
149 !(bitfield[idx] & (1 << shift))) { 150 !(bitfield[idx] & (1 << shift))) {
150 DRM_DEBUG("No such drawable %d\n", draw.handle); 151 DRM_DEBUG("No such drawable %d\n", draw.handle);
151 return 0; 152 return 0;
@@ -157,6 +158,12 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
157 158
158 spin_unlock_irqrestore(&dev->drw_lock, irqflags); 159 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
159 160
161 if (info[id]) {
162 drm_free(info[id]->rects, info[id]->num_rects *
163 sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
164 drm_free(info[id], sizeof(**info), DRM_MEM_BUFS);
165 }
166
160 /* Can we shrink the arrays? */ 167 /* Can we shrink the arrays? */
161 if (idx == bitfield_length - 1) { 168 if (idx == bitfield_length - 1) {
162 while (idx >= 0 && !bitfield[idx]) 169 while (idx >= 0 && !bitfield[idx])
@@ -164,7 +171,7 @@ int drm_rmdraw(DRM_IOCTL_ARGS)
164 171
165 bitfield_length = idx + 1; 172 bitfield_length = idx + 1;
166 173
167 if (idx != draw.handle / (8 * sizeof(*bitfield))) 174 if (idx != id / (8 * sizeof(*bitfield)))
168 bitfield = drm_alloc(bitfield_length * 175 bitfield = drm_alloc(bitfield_length *
169 sizeof(*bitfield), DRM_MEM_BUFS); 176 sizeof(*bitfield), DRM_MEM_BUFS);
170 177
@@ -222,11 +229,12 @@ int drm_update_drawable_info(DRM_IOCTL_ARGS) {
222 DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data, 229 DRM_COPY_FROM_USER_IOCTL(update, (drm_update_draw_t __user *) data,
223 sizeof(update)); 230 sizeof(update));
224 231
225 id = update.handle; 232 id = update.handle - 1;
226 idx = id / (8 * sizeof(*bitfield)); 233 idx = id / (8 * sizeof(*bitfield));
227 shift = id % (8 * sizeof(*bitfield)); 234 shift = id % (8 * sizeof(*bitfield));
228 235
229 if (idx >= bitfield_length || !(bitfield[idx] & (1 << shift))) { 236 if (idx < 0 || idx >= bitfield_length ||
237 !(bitfield[idx] & (1 << shift))) {
230 DRM_ERROR("No such drawable %d\n", update.handle); 238 DRM_ERROR("No such drawable %d\n", update.handle);
231 return DRM_ERR(EINVAL); 239 return DRM_ERR(EINVAL);
232 } 240 }
@@ -304,10 +312,13 @@ error:
304 */ 312 */
305drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { 313drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) {
306 u32 *bitfield = dev->drw_bitfield; 314 u32 *bitfield = dev->drw_bitfield;
307 unsigned int idx = id / (8 * sizeof(*bitfield)); 315 unsigned int idx, shift;
308 unsigned int shift = id % (8 * sizeof(*bitfield)); 316
317 id--;
318 idx = id / (8 * sizeof(*bitfield));
319 shift = id % (8 * sizeof(*bitfield));
309 320
310 if (idx >= dev->drw_bitfield_length || 321 if (idx < 0 || idx >= dev->drw_bitfield_length ||
311 !(bitfield[idx] & (1 << shift))) { 322 !(bitfield[idx] & (1 << shift))) {
312 DRM_DEBUG("No such drawable %d\n", id); 323 DRM_DEBUG("No such drawable %d\n", id);
313 return NULL; 324 return NULL;
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 59de4a01515f..a70af0de4453 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -153,6 +153,18 @@ int drm_lastclose(drm_device_t * dev)
153 if (dev->irq_enabled) 153 if (dev->irq_enabled)
154 drm_irq_uninstall(dev); 154 drm_irq_uninstall(dev);
155 155
156 /* Free drawable information memory */
157 for (i = 0; i < dev->drw_bitfield_length / sizeof(*dev->drw_bitfield);
158 i++) {
159 drm_drawable_info_t *info = drm_get_drawable_info(dev, i);
160
161 if (info) {
162 drm_free(info->rects, info->num_rects *
163 sizeof(drm_clip_rect_t), DRM_MEM_BUFS);
164 drm_free(info, sizeof(*info), DRM_MEM_BUFS);
165 }
166 }
167
156 mutex_lock(&dev->struct_mutex); 168 mutex_lock(&dev->struct_mutex);
157 del_timer(&dev->timer); 169 del_timer(&dev->timer);
158 170