|
@@ -65,43 +65,27 @@ static drm_map_list_t *drm_find_matching_map(drm_device_t *dev,
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/*
|
|
|
- * Used to allocate 32-bit handles for mappings.
|
|
|
- */
|
|
|
-#define START_RANGE 0x10000000
|
|
|
-#define END_RANGE 0x40000000
|
|
|
-
|
|
|
-#ifdef _LP64
|
|
|
-static __inline__ unsigned int HandleID(unsigned long lhandle,
|
|
|
- drm_device_t *dev)
|
|
|
+int drm_map_handle(drm_device_t *dev, drm_hash_item_t *hash,
|
|
|
+ unsigned long user_token, int hashed_handle)
|
|
|
{
|
|
|
- static unsigned int map32_handle = START_RANGE;
|
|
|
- unsigned int hash;
|
|
|
-
|
|
|
- if (lhandle & 0xffffffff00000000) {
|
|
|
- hash = map32_handle;
|
|
|
- map32_handle += PAGE_SIZE;
|
|
|
- if (map32_handle > END_RANGE)
|
|
|
- map32_handle = START_RANGE;
|
|
|
- } else
|
|
|
- hash = lhandle;
|
|
|
-
|
|
|
- while (1) {
|
|
|
- drm_map_list_t *_entry;
|
|
|
- list_for_each_entry(_entry, &dev->maplist->head, head) {
|
|
|
- if (_entry->user_token == hash)
|
|
|
- break;
|
|
|
- }
|
|
|
- if (&_entry->head == &dev->maplist->head)
|
|
|
- return hash;
|
|
|
+ int use_hashed_handle;
|
|
|
+ #if (BITS_PER_LONG == 64)
|
|
|
+ use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
|
|
|
+#elif (BITS_PER_LONG == 32)
|
|
|
+ use_hashed_handle = hashed_handle;
|
|
|
+#else
|
|
|
+#error Unsupported long size. Neither 64 nor 32 bits.
|
|
|
+#endif
|
|
|
|
|
|
- hash += PAGE_SIZE;
|
|
|
- map32_handle += PAGE_SIZE;
|
|
|
+ if (use_hashed_handle) {
|
|
|
+ return drm_ht_just_insert_please(&dev->map_hash, hash,
|
|
|
+ user_token, 32 - PAGE_SHIFT - 3,
|
|
|
+ PAGE_SHIFT, DRM_MAP_HASH_OFFSET);
|
|
|
+ } else {
|
|
|
+ hash->key = user_token;
|
|
|
+ return drm_ht_insert_item(&dev->map_hash, hash);
|
|
|
}
|
|
|
}
|
|
|
-#else
|
|
|
-# define HandleID(x,dev) (unsigned int)(x)
|
|
|
-#endif
|
|
|
|
|
|
/**
|
|
|
* Ioctl to specify a range of memory that is available for mapping by a non-root process.
|
|
@@ -123,6 +107,8 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|
|
drm_map_t *map;
|
|
|
drm_map_list_t *list;
|
|
|
drm_dma_handle_t *dmah;
|
|
|
+ unsigned long user_token;
|
|
|
+ int ret;
|
|
|
|
|
|
map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
|
|
|
if (!map)
|
|
@@ -257,11 +243,20 @@ static int drm_addmap_core(drm_device_t * dev, unsigned int offset,
|
|
|
|
|
|
mutex_lock(&dev->struct_mutex);
|
|
|
list_add(&list->head, &dev->maplist->head);
|
|
|
+
|
|
|
/* Assign a 32-bit handle */
|
|
|
/* We do it here so that dev->struct_mutex protects the increment */
|
|
|
- list->user_token = HandleID(map->type == _DRM_SHM
|
|
|
- ? (unsigned long)map->handle
|
|
|
- : map->offset, dev);
|
|
|
+ user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
|
|
|
+ map->offset;
|
|
|
+ ret = drm_map_handle(dev, &list->hash, user_token, FALSE);
|
|
|
+ if (ret) {
|
|
|
+ drm_free(map, sizeof(*map), DRM_MEM_MAPS);
|
|
|
+ drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
|
|
+ mutex_unlock(&dev->struct_mutex);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ list->user_token = list->hash.key;
|
|
|
mutex_unlock(&dev->struct_mutex);
|
|
|
|
|
|
*maplist = list;
|
|
@@ -346,6 +341,7 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map)
|
|
|
|
|
|
if (r_list->map == map) {
|
|
|
list_del(list);
|
|
|
+ drm_ht_remove_key(&dev->map_hash, r_list->user_token);
|
|
|
drm_free(list, sizeof(*list), DRM_MEM_MAPS);
|
|
|
break;
|
|
|
}
|