aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/drm_context.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char/drm/drm_context.c')
-rw-r--r--drivers/char/drm/drm_context.c151
1 files changed, 53 insertions, 98 deletions
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
index 4037a3602f1..17fe69e7bfc 100644
--- a/drivers/char/drm/drm_context.c
+++ b/drivers/char/drm/drm_context.c
@@ -139,21 +139,16 @@ void drm_ctxbitmap_cleanup(struct drm_device * dev)
139 * Gets the map from drm_device::ctx_idr with the handle specified and 139 * Gets the map from drm_device::ctx_idr with the handle specified and
140 * returns its handle. 140 * returns its handle.
141 */ 141 */
142int drm_getsareactx(struct inode *inode, struct drm_file *file_priv, 142int drm_getsareactx(struct drm_device *dev, void *data,
143 unsigned int cmd, unsigned long arg) 143 struct drm_file *file_priv)
144{ 144{
145 struct drm_device *dev = file_priv->head->dev; 145 struct drm_ctx_priv_map *request = data;
146 struct drm_ctx_priv_map __user *argp = (void __user *)arg;
147 struct drm_ctx_priv_map request;
148 struct drm_map *map; 146 struct drm_map *map;
149 struct drm_map_list *_entry; 147 struct drm_map_list *_entry;
150 148
151 if (copy_from_user(&request, argp, sizeof(request)))
152 return -EFAULT;
153
154 mutex_lock(&dev->struct_mutex); 149 mutex_lock(&dev->struct_mutex);
155 150
156 map = idr_find(&dev->ctx_idr, request.ctx_id); 151 map = idr_find(&dev->ctx_idr, request->ctx_id);
157 if (!map) { 152 if (!map) {
158 mutex_unlock(&dev->struct_mutex); 153 mutex_unlock(&dev->struct_mutex);
159 return -EINVAL; 154 return -EINVAL;
@@ -161,19 +156,17 @@ int drm_getsareactx(struct inode *inode, struct drm_file *file_priv,
161 156
162 mutex_unlock(&dev->struct_mutex); 157 mutex_unlock(&dev->struct_mutex);
163 158
164 request.handle = NULL; 159 request->handle = NULL;
165 list_for_each_entry(_entry, &dev->maplist, head) { 160 list_for_each_entry(_entry, &dev->maplist, head) {
166 if (_entry->map == map) { 161 if (_entry->map == map) {
167 request.handle = 162 request->handle =
168 (void *)(unsigned long)_entry->user_token; 163 (void *)(unsigned long)_entry->user_token;
169 break; 164 break;
170 } 165 }
171 } 166 }
172 if (request.handle == NULL) 167 if (request->handle == NULL)
173 return -EINVAL; 168 return -EINVAL;
174 169
175 if (copy_to_user(argp, &request, sizeof(request)))
176 return -EFAULT;
177 return 0; 170 return 0;
178} 171}
179 172
@@ -189,23 +182,17 @@ int drm_getsareactx(struct inode *inode, struct drm_file *file_priv,
189 * Searches the mapping specified in \p arg and update the entry in 182 * Searches the mapping specified in \p arg and update the entry in
190 * drm_device::ctx_idr with it. 183 * drm_device::ctx_idr with it.
191 */ 184 */
192int drm_setsareactx(struct inode *inode, struct drm_file *file_priv, 185int drm_setsareactx(struct drm_device *dev, void *data,
193 unsigned int cmd, unsigned long arg) 186 struct drm_file *file_priv)
194{ 187{
195 struct drm_device *dev = file_priv->head->dev; 188 struct drm_ctx_priv_map *request = data;
196 struct drm_ctx_priv_map request;
197 struct drm_map *map = NULL; 189 struct drm_map *map = NULL;
198 struct drm_map_list *r_list = NULL; 190 struct drm_map_list *r_list = NULL;
199 191
200 if (copy_from_user(&request,
201 (struct drm_ctx_priv_map __user *) arg,
202 sizeof(request)))
203 return -EFAULT;
204
205 mutex_lock(&dev->struct_mutex); 192 mutex_lock(&dev->struct_mutex);
206 list_for_each_entry(r_list, &dev->maplist, head) { 193 list_for_each_entry(r_list, &dev->maplist, head) {
207 if (r_list->map 194 if (r_list->map
208 && r_list->user_token == (unsigned long)request.handle) 195 && r_list->user_token == (unsigned long) request->handle)
209 goto found; 196 goto found;
210 } 197 }
211 bad: 198 bad:
@@ -217,10 +204,11 @@ int drm_setsareactx(struct inode *inode, struct drm_file *file_priv,
217 if (!map) 204 if (!map)
218 goto bad; 205 goto bad;
219 206
220 if (IS_ERR(idr_replace(&dev->ctx_idr, map, request.ctx_id))) 207 if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
221 goto bad; 208 goto bad;
222 209
223 mutex_unlock(&dev->struct_mutex); 210 mutex_unlock(&dev->struct_mutex);
211
224 return 0; 212 return 0;
225} 213}
226 214
@@ -295,29 +283,23 @@ static int drm_context_switch_complete(struct drm_device * dev, int new)
295 * \param arg user argument pointing to a drm_ctx_res structure. 283 * \param arg user argument pointing to a drm_ctx_res structure.
296 * \return zero on success or a negative number on failure. 284 * \return zero on success or a negative number on failure.
297 */ 285 */
298int drm_resctx(struct inode *inode, struct drm_file *file_priv, 286int drm_resctx(struct drm_device *dev, void *data,
299 unsigned int cmd, unsigned long arg) 287 struct drm_file *file_priv)
300{ 288{
301 struct drm_ctx_res res; 289 struct drm_ctx_res *res = data;
302 struct drm_ctx_res __user *argp = (void __user *)arg;
303 struct drm_ctx ctx; 290 struct drm_ctx ctx;
304 int i; 291 int i;
305 292
306 if (copy_from_user(&res, argp, sizeof(res))) 293 if (res->count >= DRM_RESERVED_CONTEXTS) {
307 return -EFAULT;
308
309 if (res.count >= DRM_RESERVED_CONTEXTS) {
310 memset(&ctx, 0, sizeof(ctx)); 294 memset(&ctx, 0, sizeof(ctx));
311 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { 295 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
312 ctx.handle = i; 296 ctx.handle = i;
313 if (copy_to_user(&res.contexts[i], &ctx, sizeof(ctx))) 297 if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
314 return -EFAULT; 298 return -EFAULT;
315 } 299 }
316 } 300 }
317 res.count = DRM_RESERVED_CONTEXTS; 301 res->count = DRM_RESERVED_CONTEXTS;
318 302
319 if (copy_to_user(argp, &res, sizeof(res)))
320 return -EFAULT;
321 return 0; 303 return 0;
322} 304}
323 305
@@ -332,32 +314,27 @@ int drm_resctx(struct inode *inode, struct drm_file *file_priv,
332 * 314 *
333 * Get a new handle for the context and copy to userspace. 315 * Get a new handle for the context and copy to userspace.
334 */ 316 */
335int drm_addctx(struct inode *inode, struct drm_file *file_priv, 317int drm_addctx(struct drm_device *dev, void *data,
336 unsigned int cmd, unsigned long arg) 318 struct drm_file *file_priv)
337{ 319{
338 struct drm_device *dev = file_priv->head->dev;
339 struct drm_ctx_list *ctx_entry; 320 struct drm_ctx_list *ctx_entry;
340 struct drm_ctx __user *argp = (void __user *)arg; 321 struct drm_ctx *ctx = data;
341 struct drm_ctx ctx;
342
343 if (copy_from_user(&ctx, argp, sizeof(ctx)))
344 return -EFAULT;
345 322
346 ctx.handle = drm_ctxbitmap_next(dev); 323 ctx->handle = drm_ctxbitmap_next(dev);
347 if (ctx.handle == DRM_KERNEL_CONTEXT) { 324 if (ctx->handle == DRM_KERNEL_CONTEXT) {
348 /* Skip kernel's context and get a new one. */ 325 /* Skip kernel's context and get a new one. */
349 ctx.handle = drm_ctxbitmap_next(dev); 326 ctx->handle = drm_ctxbitmap_next(dev);
350 } 327 }
351 DRM_DEBUG("%d\n", ctx.handle); 328 DRM_DEBUG("%d\n", ctx->handle);
352 if (ctx.handle == -1) { 329 if (ctx->handle == -1) {
353 DRM_DEBUG("Not enough free contexts.\n"); 330 DRM_DEBUG("Not enough free contexts.\n");
354 /* Should this return -EBUSY instead? */ 331 /* Should this return -EBUSY instead? */
355 return -ENOMEM; 332 return -ENOMEM;
356 } 333 }
357 334
358 if (ctx.handle != DRM_KERNEL_CONTEXT) { 335 if (ctx->handle != DRM_KERNEL_CONTEXT) {
359 if (dev->driver->context_ctor) 336 if (dev->driver->context_ctor)
360 if (!dev->driver->context_ctor(dev, ctx.handle)) { 337 if (!dev->driver->context_ctor(dev, ctx->handle)) {
361 DRM_DEBUG("Running out of ctxs or memory.\n"); 338 DRM_DEBUG("Running out of ctxs or memory.\n");
362 return -ENOMEM; 339 return -ENOMEM;
363 } 340 }
@@ -370,7 +347,7 @@ int drm_addctx(struct inode *inode, struct drm_file *file_priv,
370 } 347 }
371 348
372 INIT_LIST_HEAD(&ctx_entry->head); 349 INIT_LIST_HEAD(&ctx_entry->head);
373 ctx_entry->handle = ctx.handle; 350 ctx_entry->handle = ctx->handle;
374 ctx_entry->tag = file_priv; 351 ctx_entry->tag = file_priv;
375 352
376 mutex_lock(&dev->ctxlist_mutex); 353 mutex_lock(&dev->ctxlist_mutex);
@@ -378,13 +355,10 @@ int drm_addctx(struct inode *inode, struct drm_file *file_priv,
378 ++dev->ctx_count; 355 ++dev->ctx_count;
379 mutex_unlock(&dev->ctxlist_mutex); 356 mutex_unlock(&dev->ctxlist_mutex);
380 357
381 if (copy_to_user(argp, &ctx, sizeof(ctx)))
382 return -EFAULT;
383 return 0; 358 return 0;
384} 359}
385 360
386int drm_modctx(struct inode *inode, struct drm_file *file_priv, 361int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
387 unsigned int cmd, unsigned long arg)
388{ 362{
389 /* This does nothing */ 363 /* This does nothing */
390 return 0; 364 return 0;
@@ -399,20 +373,13 @@ int drm_modctx(struct inode *inode, struct drm_file *file_priv,
399 * \param arg user argument pointing to a drm_ctx structure. 373 * \param arg user argument pointing to a drm_ctx structure.
400 * \return zero on success or a negative number on failure. 374 * \return zero on success or a negative number on failure.
401 */ 375 */
402int drm_getctx(struct inode *inode, struct drm_file *file_priv, 376int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
403 unsigned int cmd, unsigned long arg)
404{ 377{
405 struct drm_ctx __user *argp = (void __user *)arg; 378 struct drm_ctx *ctx = data;
406 struct drm_ctx ctx;
407
408 if (copy_from_user(&ctx, argp, sizeof(ctx)))
409 return -EFAULT;
410 379
411 /* This is 0, because we don't handle any context flags */ 380 /* This is 0, because we don't handle any context flags */
412 ctx.flags = 0; 381 ctx->flags = 0;
413 382
414 if (copy_to_user(argp, &ctx, sizeof(ctx)))
415 return -EFAULT;
416 return 0; 383 return 0;
417} 384}
418 385
@@ -427,17 +394,13 @@ int drm_getctx(struct inode *inode, struct drm_file *file_priv,
427 * 394 *
428 * Calls context_switch(). 395 * Calls context_switch().
429 */ 396 */
430int drm_switchctx(struct inode *inode, struct drm_file *file_priv, 397int drm_switchctx(struct drm_device *dev, void *data,
431 unsigned int cmd, unsigned long arg) 398 struct drm_file *file_priv)
432{ 399{
433 struct drm_device *dev = file_priv->head->dev; 400 struct drm_ctx *ctx = data;
434 struct drm_ctx ctx;
435 401
436 if (copy_from_user(&ctx, (struct drm_ctx __user *) arg, sizeof(ctx))) 402 DRM_DEBUG("%d\n", ctx->handle);
437 return -EFAULT; 403 return drm_context_switch(dev, dev->last_context, ctx->handle);
438
439 DRM_DEBUG("%d\n", ctx.handle);
440 return drm_context_switch(dev, dev->last_context, ctx.handle);
441} 404}
442 405
443/** 406/**
@@ -451,17 +414,13 @@ int drm_switchctx(struct inode *inode, struct drm_file *file_priv,
451 * 414 *
452 * Calls context_switch_complete(). 415 * Calls context_switch_complete().
453 */ 416 */
454int drm_newctx(struct inode *inode, struct drm_file *file_priv, 417int drm_newctx(struct drm_device *dev, void *data,
455 unsigned int cmd, unsigned long arg) 418 struct drm_file *file_priv)
456{ 419{
457 struct drm_device *dev = file_priv->head->dev; 420 struct drm_ctx *ctx = data;
458 struct drm_ctx ctx;
459 421
460 if (copy_from_user(&ctx, (struct drm_ctx __user *) arg, sizeof(ctx))) 422 DRM_DEBUG("%d\n", ctx->handle);
461 return -EFAULT; 423 drm_context_switch_complete(dev, ctx->handle);
462
463 DRM_DEBUG("%d\n", ctx.handle);
464 drm_context_switch_complete(dev, ctx.handle);
465 424
466 return 0; 425 return 0;
467} 426}
@@ -477,23 +436,19 @@ int drm_newctx(struct inode *inode, struct drm_file *file_priv,
477 * 436 *
478 * If not the special kernel context, calls ctxbitmap_free() to free the specified context. 437 * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
479 */ 438 */
480int drm_rmctx(struct inode *inode, struct drm_file *file_priv, 439int drm_rmctx(struct drm_device *dev, void *data,
481 unsigned int cmd, unsigned long arg) 440 struct drm_file *file_priv)
482{ 441{
483 struct drm_device *dev = file_priv->head->dev; 442 struct drm_ctx *ctx = data;
484 struct drm_ctx ctx;
485
486 if (copy_from_user(&ctx, (struct drm_ctx __user *) arg, sizeof(ctx)))
487 return -EFAULT;
488 443
489 DRM_DEBUG("%d\n", ctx.handle); 444 DRM_DEBUG("%d\n", ctx->handle);
490 if (ctx.handle == DRM_KERNEL_CONTEXT + 1) { 445 if (ctx->handle == DRM_KERNEL_CONTEXT + 1) {
491 file_priv->remove_auth_on_close = 1; 446 file_priv->remove_auth_on_close = 1;
492 } 447 }
493 if (ctx.handle != DRM_KERNEL_CONTEXT) { 448 if (ctx->handle != DRM_KERNEL_CONTEXT) {
494 if (dev->driver->context_dtor) 449 if (dev->driver->context_dtor)
495 dev->driver->context_dtor(dev, ctx.handle); 450 dev->driver->context_dtor(dev, ctx->handle);
496 drm_ctxbitmap_free(dev, ctx.handle); 451 drm_ctxbitmap_free(dev, ctx->handle);
497 } 452 }
498 453
499 mutex_lock(&dev->ctxlist_mutex); 454 mutex_lock(&dev->ctxlist_mutex);
@@ -501,7 +456,7 @@ int drm_rmctx(struct inode *inode, struct drm_file *file_priv,
501 struct drm_ctx_list *pos, *n; 456 struct drm_ctx_list *pos, *n;
502 457
503 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) { 458 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
504 if (pos->handle == ctx.handle) { 459 if (pos->handle == ctx->handle) {
505 list_del(&pos->head); 460 list_del(&pos->head);
506 drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST); 461 drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
507 --dev->ctx_count; 462 --dev->ctx_count;