Skip to content

Commit

Permalink
drm: fix issue with handle lookup for a 0 handle
Browse files Browse the repository at this point in the history
On 32-bit PPC a 0 handle is valid for AGP space, the 32/64 lookup
doesn't handle 0 correctly.

From: Ben Herrenschmidt <benh@kernel.crashing.org> and Paul Mackerras <paulus@samba.org>
Signed-off-by: Dave Airlie <airlied@linux.ie>
  • Loading branch information
Dave Airlie authored and Dave Airlie committed Sep 5, 2005
1 parent f505380 commit 89625eb
Showing 1 changed file with 32 additions and 32 deletions.
64 changes: 32 additions & 32 deletions drivers/char/drm/drm_bufs.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,16 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource)
}
EXPORT_SYMBOL(drm_get_resource_len);

static drm_local_map_t *drm_find_matching_map(drm_device_t *dev,
drm_local_map_t *map)
static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
drm_local_map_t *map)
{
struct list_head *list;

list_for_each(list, &dev->maplist->head) {
drm_map_list_t *entry = list_entry(list, drm_map_list_t, head);
if (entry->map && map->type == entry->map->type &&
entry->map->offset == map->offset) {
return entry->map;
return entry;
}
}

Expand Down Expand Up @@ -114,14 +114,13 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev
* type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
* applicable and if supported by the kernel.
*/
int drm_addmap(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
drm_map_flags_t flags, drm_local_map_t ** map_ptr)
int drm_addmap_core(drm_device_t * dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
drm_map_flags_t flags, drm_map_list_t **maplist)
{
drm_map_t *map;
drm_map_list_t *list;
drm_dma_handle_t *dmah;
drm_local_map_t *found_map;

map = drm_alloc( sizeof(*map), DRM_MEM_MAPS );
if ( !map )
Expand Down Expand Up @@ -166,17 +165,17 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
* needing to be aware of it. Therefore, we just return success
* when the server tries to create a duplicate map.
*/
found_map = drm_find_matching_map(dev, map);
if (found_map != NULL) {
if (found_map->size != map->size) {
list = drm_find_matching_map(dev, map);
if (list != NULL) {
if (list->map->size != map->size) {
DRM_DEBUG("Matching maps of type %d with "
"mismatched sizes, (%ld vs %ld)\n",
map->type, map->size, found_map->size);
found_map->size = map->size;
map->type, map->size, list->map->size);
list->map->size = map->size;
}

drm_free(map, sizeof(*map), DRM_MEM_MAPS);
*map_ptr = found_map;
*maplist = list;
return 0;
}

Expand Down Expand Up @@ -264,9 +263,22 @@ int drm_addmap(drm_device_t * dev, unsigned int offset,
: map->offset, dev);
up(&dev->struct_sem);

*map_ptr = map;
*maplist = list;
return 0;
}

int drm_addmap(drm_device_t *dev, unsigned int offset,
unsigned int size, drm_map_type_t type,
drm_map_flags_t flags, drm_local_map_t **map_ptr)
{
drm_map_list_t *list;
int rc;

rc = drm_addmap_core(dev, offset, size, type, flags, &list);
if (!rc)
*map_ptr = list->map;
return rc;
}
EXPORT_SYMBOL(drm_addmap);

int drm_addmap_ioctl(struct inode *inode, struct file *filp,
Expand All @@ -275,10 +287,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->head->dev;
drm_map_t map;
drm_map_t *map_ptr;
drm_map_list_t *maplist;
drm_map_t __user *argp = (void __user *)arg;
int err;
unsigned long handle = 0;

if (!(filp->f_mode & 3))
return -EACCES; /* Require read/write */
Expand All @@ -287,26 +298,15 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp,
return -EFAULT;
}

err = drm_addmap(dev, map.offset, map.size, map.type, map.flags,
&map_ptr);
err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags,
&maplist);

if (err) {
if (err)
return err;
}

{
drm_map_list_t *_entry;
list_for_each_entry(_entry, &dev->maplist->head, head) {
if (_entry->map == map_ptr)
handle = _entry->user_token;
}
if (!handle)
return -EFAULT;
}

if (copy_to_user(argp, map_ptr, sizeof(*map_ptr)))
if (copy_to_user(argp, maplist->map, sizeof(drm_map_t)))
return -EFAULT;
if (put_user(handle, &argp->handle))
if (put_user(maplist->user_token, &argp->handle))
return -EFAULT;
return 0;
}
Expand Down

0 comments on commit 89625eb

Please sign in to comment.