diff options
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/drm/drm_drawable.c | 35 | ||||
-rw-r--r-- | drivers/char/drm/drm_drv.c | 12 |
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 | */ |
305 | drm_drawable_info_t *drm_get_drawable_info(drm_device_t *dev, drm_drawable_t id) { | 313 | drm_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 | ||