aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_bufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_bufs.c')
-rw-r--r--drivers/gpu/drm/drm_bufs.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/drivers/gpu/drm/drm_bufs.c b/drivers/gpu/drm/drm_bufs.c
index bde64b84166e..dc3ce3e0a0a4 100644
--- a/drivers/gpu/drm/drm_bufs.c
+++ b/drivers/gpu/drm/drm_bufs.c
@@ -54,9 +54,9 @@ static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
54{ 54{
55 struct drm_map_list *entry; 55 struct drm_map_list *entry;
56 list_for_each_entry(entry, &dev->maplist, head) { 56 list_for_each_entry(entry, &dev->maplist, head) {
57 if (entry->map && map->type == entry->map->type && 57 if (entry->map && (entry->master == dev->primary->master) && (map->type == entry->map->type) &&
58 ((entry->map->offset == map->offset) || 58 ((entry->map->offset == map->offset) ||
59 (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) { 59 ((map->type == _DRM_SHM) && (map->flags&_DRM_CONTAINS_LOCK)))) {
60 return entry; 60 return entry;
61 } 61 }
62 } 62 }
@@ -210,12 +210,12 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
210 map->offset = (unsigned long)map->handle; 210 map->offset = (unsigned long)map->handle;
211 if (map->flags & _DRM_CONTAINS_LOCK) { 211 if (map->flags & _DRM_CONTAINS_LOCK) {
212 /* Prevent a 2nd X Server from creating a 2nd lock */ 212 /* Prevent a 2nd X Server from creating a 2nd lock */
213 if (dev->lock.hw_lock != NULL) { 213 if (dev->primary->master->lock.hw_lock != NULL) {
214 vfree(map->handle); 214 vfree(map->handle);
215 drm_free(map, sizeof(*map), DRM_MEM_MAPS); 215 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
216 return -EBUSY; 216 return -EBUSY;
217 } 217 }
218 dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */ 218 dev->sigdata.lock = dev->primary->master->lock.hw_lock = map->handle; /* Pointer to lock */
219 } 219 }
220 break; 220 break;
221 case _DRM_AGP: { 221 case _DRM_AGP: {
@@ -319,6 +319,7 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
319 list->user_token = list->hash.key << PAGE_SHIFT; 319 list->user_token = list->hash.key << PAGE_SHIFT;
320 mutex_unlock(&dev->struct_mutex); 320 mutex_unlock(&dev->struct_mutex);
321 321
322 list->master = dev->primary->master;
322 *maplist = list; 323 *maplist = list;
323 return 0; 324 return 0;
324 } 325 }
@@ -345,7 +346,7 @@ int drm_addmap_ioctl(struct drm_device *dev, void *data,
345 struct drm_map_list *maplist; 346 struct drm_map_list *maplist;
346 int err; 347 int err;
347 348
348 if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP)) 349 if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP || map->type == _DRM_SHM))
349 return -EPERM; 350 return -EPERM;
350 351
351 err = drm_addmap_core(dev, map->offset, map->size, map->type, 352 err = drm_addmap_core(dev, map->offset, map->size, map->type,
@@ -380,10 +381,12 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
380 struct drm_map_list *r_list = NULL, *list_t; 381 struct drm_map_list *r_list = NULL, *list_t;
381 drm_dma_handle_t dmah; 382 drm_dma_handle_t dmah;
382 int found = 0; 383 int found = 0;
384 struct drm_master *master;
383 385
384 /* Find the list entry for the map and remove it */ 386 /* Find the list entry for the map and remove it */
385 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) { 387 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
386 if (r_list->map == map) { 388 if (r_list->map == map) {
389 master = r_list->master;
387 list_del(&r_list->head); 390 list_del(&r_list->head);
388 drm_ht_remove_key(&dev->map_hash, 391 drm_ht_remove_key(&dev->map_hash,
389 r_list->user_token >> PAGE_SHIFT); 392 r_list->user_token >> PAGE_SHIFT);
@@ -409,6 +412,13 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
409 break; 412 break;
410 case _DRM_SHM: 413 case _DRM_SHM:
411 vfree(map->handle); 414 vfree(map->handle);
415 if (master) {
416 if (dev->sigdata.lock == master->lock.hw_lock)
417 dev->sigdata.lock = NULL;
418 master->lock.hw_lock = NULL; /* SHM removed */
419 master->lock.file_priv = NULL;
420 wake_up_interruptible(&master->lock.lock_queue);
421 }
412 break; 422 break;
413 case _DRM_AGP: 423 case _DRM_AGP:
414 case _DRM_SCATTER_GATHER: 424 case _DRM_SCATTER_GATHER: