diff options
author | Dave Airlie <airlied@starflyer.(none)> | 2005-09-05 07:23:23 -0400 |
---|---|---|
committer | Dave Airlie <airlied@linux.ie> | 2005-09-05 07:23:23 -0400 |
commit | 89625eb186b9b0b9454d44126f8b1bcc72ad93b7 (patch) | |
tree | 0e5bf395d8c53fcfaf0790b417666a8dabae8a8e /drivers/char | |
parent | f505380ba7b98ec97bf25300c2a58aeae903530b (diff) |
drm: fix issue with handle lookup for a 0 handle
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>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/drm/drm_bufs.c | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index e0743ebbe4bd..8eff0736a94d 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -48,8 +48,8 @@ unsigned long drm_get_resource_len(drm_device_t *dev, unsigned int resource) | |||
48 | } | 48 | } |
49 | EXPORT_SYMBOL(drm_get_resource_len); | 49 | EXPORT_SYMBOL(drm_get_resource_len); |
50 | 50 | ||
51 | static drm_local_map_t *drm_find_matching_map(drm_device_t *dev, | 51 | static drm_map_list_t *drm_find_matching_map(drm_device_t *dev, |
52 | drm_local_map_t *map) | 52 | drm_local_map_t *map) |
53 | { | 53 | { |
54 | struct list_head *list; | 54 | struct list_head *list; |
55 | 55 | ||
@@ -57,7 +57,7 @@ static drm_local_map_t *drm_find_matching_map(drm_device_t *dev, | |||
57 | drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); | 57 | drm_map_list_t *entry = list_entry(list, drm_map_list_t, head); |
58 | if (entry->map && map->type == entry->map->type && | 58 | if (entry->map && map->type == entry->map->type && |
59 | entry->map->offset == map->offset) { | 59 | entry->map->offset == map->offset) { |
60 | return entry->map; | 60 | return entry; |
61 | } | 61 | } |
62 | } | 62 | } |
63 | 63 | ||
@@ -114,14 +114,13 @@ static __inline__ unsigned int HandleID(unsigned long lhandle, drm_device_t *dev | |||
114 | * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where | 114 | * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where |
115 | * applicable and if supported by the kernel. | 115 | * applicable and if supported by the kernel. |
116 | */ | 116 | */ |
117 | int drm_addmap(drm_device_t * dev, unsigned int offset, | 117 | int drm_addmap_core(drm_device_t * dev, unsigned int offset, |
118 | unsigned int size, drm_map_type_t type, | 118 | unsigned int size, drm_map_type_t type, |
119 | drm_map_flags_t flags, drm_local_map_t ** map_ptr) | 119 | drm_map_flags_t flags, drm_map_list_t **maplist) |
120 | { | 120 | { |
121 | drm_map_t *map; | 121 | drm_map_t *map; |
122 | drm_map_list_t *list; | 122 | drm_map_list_t *list; |
123 | drm_dma_handle_t *dmah; | 123 | drm_dma_handle_t *dmah; |
124 | drm_local_map_t *found_map; | ||
125 | 124 | ||
126 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); | 125 | map = drm_alloc( sizeof(*map), DRM_MEM_MAPS ); |
127 | if ( !map ) | 126 | if ( !map ) |
@@ -166,17 +165,17 @@ int drm_addmap(drm_device_t * dev, unsigned int offset, | |||
166 | * needing to be aware of it. Therefore, we just return success | 165 | * needing to be aware of it. Therefore, we just return success |
167 | * when the server tries to create a duplicate map. | 166 | * when the server tries to create a duplicate map. |
168 | */ | 167 | */ |
169 | found_map = drm_find_matching_map(dev, map); | 168 | list = drm_find_matching_map(dev, map); |
170 | if (found_map != NULL) { | 169 | if (list != NULL) { |
171 | if (found_map->size != map->size) { | 170 | if (list->map->size != map->size) { |
172 | DRM_DEBUG("Matching maps of type %d with " | 171 | DRM_DEBUG("Matching maps of type %d with " |
173 | "mismatched sizes, (%ld vs %ld)\n", | 172 | "mismatched sizes, (%ld vs %ld)\n", |
174 | map->type, map->size, found_map->size); | 173 | map->type, map->size, list->map->size); |
175 | found_map->size = map->size; | 174 | list->map->size = map->size; |
176 | } | 175 | } |
177 | 176 | ||
178 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); | 177 | drm_free(map, sizeof(*map), DRM_MEM_MAPS); |
179 | *map_ptr = found_map; | 178 | *maplist = list; |
180 | return 0; | 179 | return 0; |
181 | } | 180 | } |
182 | 181 | ||
@@ -264,9 +263,22 @@ int drm_addmap(drm_device_t * dev, unsigned int offset, | |||
264 | : map->offset, dev); | 263 | : map->offset, dev); |
265 | up(&dev->struct_sem); | 264 | up(&dev->struct_sem); |
266 | 265 | ||
267 | *map_ptr = map; | 266 | *maplist = list; |
268 | return 0; | 267 | return 0; |
269 | } | 268 | } |
269 | |||
270 | int drm_addmap(drm_device_t *dev, unsigned int offset, | ||
271 | unsigned int size, drm_map_type_t type, | ||
272 | drm_map_flags_t flags, drm_local_map_t **map_ptr) | ||
273 | { | ||
274 | drm_map_list_t *list; | ||
275 | int rc; | ||
276 | |||
277 | rc = drm_addmap_core(dev, offset, size, type, flags, &list); | ||
278 | if (!rc) | ||
279 | *map_ptr = list->map; | ||
280 | return rc; | ||
281 | } | ||
270 | EXPORT_SYMBOL(drm_addmap); | 282 | EXPORT_SYMBOL(drm_addmap); |
271 | 283 | ||
272 | int drm_addmap_ioctl(struct inode *inode, struct file *filp, | 284 | int drm_addmap_ioctl(struct inode *inode, struct file *filp, |
@@ -275,10 +287,9 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, | |||
275 | drm_file_t *priv = filp->private_data; | 287 | drm_file_t *priv = filp->private_data; |
276 | drm_device_t *dev = priv->head->dev; | 288 | drm_device_t *dev = priv->head->dev; |
277 | drm_map_t map; | 289 | drm_map_t map; |
278 | drm_map_t *map_ptr; | 290 | drm_map_list_t *maplist; |
279 | drm_map_t __user *argp = (void __user *)arg; | 291 | drm_map_t __user *argp = (void __user *)arg; |
280 | int err; | 292 | int err; |
281 | unsigned long handle = 0; | ||
282 | 293 | ||
283 | if (!(filp->f_mode & 3)) | 294 | if (!(filp->f_mode & 3)) |
284 | return -EACCES; /* Require read/write */ | 295 | return -EACCES; /* Require read/write */ |
@@ -287,26 +298,15 @@ int drm_addmap_ioctl(struct inode *inode, struct file *filp, | |||
287 | return -EFAULT; | 298 | return -EFAULT; |
288 | } | 299 | } |
289 | 300 | ||
290 | err = drm_addmap(dev, map.offset, map.size, map.type, map.flags, | 301 | err = drm_addmap_core(dev, map.offset, map.size, map.type, map.flags, |
291 | &map_ptr); | 302 | &maplist); |
292 | 303 | ||
293 | if (err) { | 304 | if (err) |
294 | return err; | 305 | return err; |
295 | } | ||
296 | |||
297 | { | ||
298 | drm_map_list_t *_entry; | ||
299 | list_for_each_entry(_entry, &dev->maplist->head, head) { | ||
300 | if (_entry->map == map_ptr) | ||
301 | handle = _entry->user_token; | ||
302 | } | ||
303 | if (!handle) | ||
304 | return -EFAULT; | ||
305 | } | ||
306 | 306 | ||
307 | if (copy_to_user(argp, map_ptr, sizeof(*map_ptr))) | 307 | if (copy_to_user(argp, maplist->map, sizeof(drm_map_t))) |
308 | return -EFAULT; | 308 | return -EFAULT; |
309 | if (put_user(handle, &argp->handle)) | 309 | if (put_user(maplist->user_token, &argp->handle)) |
310 | return -EFAULT; | 310 | return -EFAULT; |
311 | return 0; | 311 | return 0; |
312 | } | 312 | } |