aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm
diff options
context:
space:
mode:
authorThomas Hellstrom <thomas@tungstengraphics.com>2006-08-07 08:22:10 -0400
committerDave Airlie <airlied@linux.ie>2006-09-21 15:32:31 -0400
commit8669cbc5e651bf4effa20e8c244a5a7d67da6fe9 (patch)
treea97ac359c8041bc39efc0f32cac26772a43a0736 /drivers/char/drm
parent3d45dbd611d1441d667b06acced9fbad3c8fcb1b (diff)
drm: move drm authentication to new generic hash table.
Fix drm_remove_magic potential memory leak / corruption. Move drm authentication token hashing to new generic hash table implementation. Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm')
-rw-r--r--drivers/char/drm/drmP.h8
-rw-r--r--drivers/char/drm/drm_auth.c62
-rw-r--r--drivers/char/drm/drm_drv.c10
-rw-r--r--drivers/char/drm/drm_fops.c6
-rw-r--r--drivers/char/drm/drm_hashtab.h2
5 files changed, 26 insertions, 62 deletions
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
index c93985bb91a2..fedaf013f848 100644
--- a/drivers/char/drm/drmP.h
+++ b/drivers/char/drm/drmP.h
@@ -105,7 +105,7 @@
105#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then 105#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then
106 also include looping detection. */ 106 also include looping detection. */
107 107
108#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */ 108#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */
109#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */ 109#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
110#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */ 110#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
111#define DRM_LOOPING_LIMIT 5000000 111#define DRM_LOOPING_LIMIT 5000000
@@ -277,7 +277,8 @@ typedef struct drm_devstate {
277} drm_devstate_t; 277} drm_devstate_t;
278 278
279typedef struct drm_magic_entry { 279typedef struct drm_magic_entry {
280 drm_magic_t magic; 280 drm_hash_item_t hash_item;
281 struct list_head head;
281 struct drm_file *priv; 282 struct drm_file *priv;
282 struct drm_magic_entry *next; 283 struct drm_magic_entry *next;
283} drm_magic_entry_t; 284} drm_magic_entry_t;
@@ -653,7 +654,8 @@ typedef struct drm_device {
653 /*@{ */ 654 /*@{ */
654 drm_file_t *file_first; /**< file list head */ 655 drm_file_t *file_first; /**< file list head */
655 drm_file_t *file_last; /**< file list tail */ 656 drm_file_t *file_last; /**< file list tail */
656 drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */ 657 drm_open_hash_t magiclist; /**< magic hash table */
658 struct list_head magicfree;
657 /*@} */ 659 /*@} */
658 660
659 /** \name Memory management */ 661 /** \name Memory management */
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
index 2a37586a7ee8..40cd262ca9e1 100644
--- a/drivers/char/drm/drm_auth.c
+++ b/drivers/char/drm/drm_auth.c
@@ -36,20 +36,6 @@
36#include "drmP.h" 36#include "drmP.h"
37 37
38/** 38/**
39 * Generate a hash key from a magic.
40 *
41 * \param magic magic.
42 * \return hash key.
43 *
44 * The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
45 * a power of 2.
46 */
47static int drm_hash_magic(drm_magic_t magic)
48{
49 return magic & (DRM_HASH_SIZE - 1);
50}
51
52/**
53 * Find the file with the given magic number. 39 * Find the file with the given magic number.
54 * 40 *
55 * \param dev DRM device. 41 * \param dev DRM device.
@@ -63,14 +49,12 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
63{ 49{
64 drm_file_t *retval = NULL; 50 drm_file_t *retval = NULL;
65 drm_magic_entry_t *pt; 51 drm_magic_entry_t *pt;
66 int hash = drm_hash_magic(magic); 52 drm_hash_item_t *hash;
67 53
68 mutex_lock(&dev->struct_mutex); 54 mutex_lock(&dev->struct_mutex);
69 for (pt = dev->magiclist[hash].head; pt; pt = pt->next) { 55 if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
70 if (pt->magic == magic) { 56 pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
71 retval = pt->priv; 57 retval = pt->priv;
72 break;
73 }
74 } 58 }
75 mutex_unlock(&dev->struct_mutex); 59 mutex_unlock(&dev->struct_mutex);
76 return retval; 60 return retval;
@@ -90,28 +74,20 @@ static drm_file_t *drm_find_file(drm_device_t * dev, drm_magic_t magic)
90static int drm_add_magic(drm_device_t * dev, drm_file_t * priv, 74static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
91 drm_magic_t magic) 75 drm_magic_t magic)
92{ 76{
93 int hash;
94 drm_magic_entry_t *entry; 77 drm_magic_entry_t *entry;
95 78
96 DRM_DEBUG("%d\n", magic); 79 DRM_DEBUG("%d\n", magic);
97 80
98 hash = drm_hash_magic(magic);
99 entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC); 81 entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
100 if (!entry) 82 if (!entry)
101 return -ENOMEM; 83 return -ENOMEM;
102 memset(entry, 0, sizeof(*entry)); 84 memset(entry, 0, sizeof(*entry));
103 entry->magic = magic;
104 entry->priv = priv; 85 entry->priv = priv;
105 entry->next = NULL;
106 86
87 entry->hash_item.key = (unsigned long)magic;
107 mutex_lock(&dev->struct_mutex); 88 mutex_lock(&dev->struct_mutex);
108 if (dev->magiclist[hash].tail) { 89 drm_ht_insert_item(&dev->magiclist, &entry->hash_item);
109 dev->magiclist[hash].tail->next = entry; 90 list_add_tail(&entry->head, &dev->magicfree);
110 dev->magiclist[hash].tail = entry;
111 } else {
112 dev->magiclist[hash].head = entry;
113 dev->magiclist[hash].tail = entry;
114 }
115 mutex_unlock(&dev->struct_mutex); 91 mutex_unlock(&dev->struct_mutex);
116 92
117 return 0; 93 return 0;
@@ -128,29 +104,19 @@ static int drm_add_magic(drm_device_t * dev, drm_file_t * priv,
128 */ 104 */
129static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic) 105static int drm_remove_magic(drm_device_t * dev, drm_magic_t magic)
130{ 106{
131 drm_magic_entry_t *prev = NULL;
132 drm_magic_entry_t *pt; 107 drm_magic_entry_t *pt;
133 int hash; 108 drm_hash_item_t *hash;
134 109
135 DRM_DEBUG("%d\n", magic); 110 DRM_DEBUG("%d\n", magic);
136 hash = drm_hash_magic(magic);
137 111
138 mutex_lock(&dev->struct_mutex); 112 mutex_lock(&dev->struct_mutex);
139 for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) { 113 if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
140 if (pt->magic == magic) { 114 mutex_unlock(&dev->struct_mutex);
141 if (dev->magiclist[hash].head == pt) { 115 return -EINVAL;
142 dev->magiclist[hash].head = pt->next;
143 }
144 if (dev->magiclist[hash].tail == pt) {
145 dev->magiclist[hash].tail = prev;
146 }
147 if (prev) {
148 prev->next = pt->next;
149 }
150 mutex_unlock(&dev->struct_mutex);
151 return 0;
152 }
153 } 116 }
117 pt = drm_hash_entry(hash, drm_magic_entry_t, hash_item);
118 drm_ht_remove_item(&dev->magiclist, hash);
119 list_del(&pt->head);
154 mutex_unlock(&dev->struct_mutex); 120 mutex_unlock(&dev->struct_mutex);
155 121
156 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); 122 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
index 3da72f7364f0..f9ecc8414b8a 100644
--- a/drivers/char/drm/drm_drv.c
+++ b/drivers/char/drm/drm_drv.c
@@ -155,12 +155,10 @@ int drm_lastclose(drm_device_t * dev)
155 del_timer(&dev->timer); 155 del_timer(&dev->timer);
156 156
157 /* Clear pid list */ 157 /* Clear pid list */
158 for (i = 0; i < DRM_HASH_SIZE; i++) { 158 list_for_each_entry_safe(pt, next, &dev->magicfree, head) {
159 for (pt = dev->magiclist[i].head; pt; pt = next) { 159 list_del(&pt->head);
160 next = pt->next; 160 drm_ht_remove_item(&dev->magiclist, &pt->hash_item);
161 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); 161 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
162 }
163 dev->magiclist[i].head = dev->magiclist[i].tail = NULL;
164 } 162 }
165 163
166 /* Clear AGP information */ 164 /* Clear AGP information */
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
index 51ccc82bf612..2bbf45d85c35 100644
--- a/drivers/char/drm/drm_fops.c
+++ b/drivers/char/drm/drm_fops.c
@@ -72,10 +72,8 @@ static int drm_setup(drm_device_t * dev)
72 for (i = 0; i < ARRAY_SIZE(dev->counts); i++) 72 for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
73 atomic_set(&dev->counts[i], 0); 73 atomic_set(&dev->counts[i], 0);
74 74
75 for (i = 0; i < DRM_HASH_SIZE; i++) { 75 drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER);
76 dev->magiclist[i].head = NULL; 76 INIT_LIST_HEAD(&dev->magicfree);
77 dev->magiclist[i].tail = NULL;
78 }
79 77
80 dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST); 78 dev->ctxlist = drm_alloc(sizeof(*dev->ctxlist), DRM_MEM_CTXLIST);
81 if (dev->ctxlist == NULL) 79 if (dev->ctxlist == NULL)
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
index 40afec05bff8..9e19ef1814ba 100644
--- a/drivers/char/drm/drm_hashtab.h
+++ b/drivers/char/drm/drm_hashtab.h
@@ -35,7 +35,7 @@
35#ifndef DRM_HASHTAB_H 35#ifndef DRM_HASHTAB_H
36#define DRM_HASHTAB_H 36#define DRM_HASHTAB_H
37 37
38#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member) 38#define drm_hash_entry(_ptr, _type, _member) list_entry(_ptr, _type, _member)
39 39
40typedef struct drm_hash_item{ 40typedef struct drm_hash_item{
41 struct hlist_node head; 41 struct hlist_node head;