Correct a recursion on non-recursive mutex in drm_addmap from radeon's

firstopen, by making drm_addmap require the drm device lock to be held.
    Also, make matching of kernel maps match linux by requiring shm matches
    to have the contains_lock flag set if the offset doesn't match.
main
Eric Anholt 2005-11-08 01:12:08 +00:00
parent 3fce085e13
commit 145b23b552
1 changed files with 6 additions and 5 deletions

View File

@ -127,17 +127,17 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
*/ */
if (type == _DRM_REGISTERS || type == _DRM_FRAME_BUFFER || if (type == _DRM_REGISTERS || type == _DRM_FRAME_BUFFER ||
type == _DRM_SHM) { type == _DRM_SHM) {
DRM_LOCK();
TAILQ_FOREACH(map, &dev->maplist, link) { TAILQ_FOREACH(map, &dev->maplist, link) {
if (map->type == type && if (map->type == type && (map->offset == offset ||
(map->offset == offset || map->type == _DRM_SHM)) { (map->type == _DRM_SHM &&
map->flags == _DRM_CONTAINS_LOCK))) {
map->size = size; map->size = size;
DRM_DEBUG("Found kernel map %d\n", type); DRM_DEBUG("Found kernel map %d\n", type);
goto done; goto done;
} }
} }
DRM_UNLOCK();
} }
DRM_UNLOCK();
/* Allocate a new map structure, fill it in, and do any type-specific /* Allocate a new map structure, fill it in, and do any type-specific
* initialization necessary. * initialization necessary.
@ -236,7 +236,6 @@ int drm_addmap(drm_device_t * dev, unsigned long offset, unsigned long size,
done: done:
/* Jumped to, with lock held, when a kernel map is found. */ /* Jumped to, with lock held, when a kernel map is found. */
DRM_UNLOCK();
DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", map->type, map->offset, DRM_DEBUG("Added map %d 0x%lx/0x%lx\n", map->type, map->offset,
map->size); map->size);
@ -261,8 +260,10 @@ int drm_addmap_ioctl(DRM_IOCTL_ARGS)
if (!DRM_SUSER(p) && request.type != _DRM_AGP) if (!DRM_SUSER(p) && request.type != _DRM_AGP)
return DRM_ERR(EACCES); return DRM_ERR(EACCES);
DRM_LOCK();
err = drm_addmap(dev, request.offset, request.size, request.type, err = drm_addmap(dev, request.offset, request.size, request.type,
request.flags, &map); request.flags, &map);
DRM_UNLOCK();
if (err != 0) if (err != 0)
return err; return err;