diff options
Diffstat (limited to 'drivers/gpu/drm/drm_bufs.c')
-rw-r--r-- | drivers/gpu/drm/drm_bufs.c | 20 |
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: |