diff options
author | Oded Gabbay <oded.gabbay@amd.com> | 2014-12-29 07:20:05 -0500 |
---|---|---|
committer | Oded Gabbay <oded.gabbay@amd.com> | 2015-01-06 12:44:36 -0500 |
commit | 76baee6c733bfef30fcf86cbd121e336b839e408 (patch) | |
tree | 1ba6313aa81b5c69ed5591e0cb8598c2fd69434b /drivers/gpu | |
parent | b81c55db1053805866a242cd0bfbfb0c60c499b3 (diff) |
drm/amdkfd: rewrite kfd_ioctl() according to drm_ioctl()
This patch changes kfd_ioctl() to be very similar to drm_ioctl().
The patch defines an array of amdkfd_ioctls, which maps IOCTL definition to the
ioctl function.
The kfd_ioctl() uses that mapping to call the appropriate ioctl function,
through a function pointer.
This patch also declares a new typedef for the ioctl function pointer.
v2: Renamed KFD_COMMAND_(START|END) to AMDKFD_...
Signed-off-by: Oded Gabbay <oded.gabbay@amd.com>
Acked-by: Christian König <christian.koenig@amd.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | 116 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 18 |
2 files changed, 86 insertions, 48 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 6fbde9e411e0..fcfdf23e1913 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
@@ -482,21 +482,79 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ | ||
486 | [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | ||
487 | |||
488 | /** Ioctl table */ | ||
489 | static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { | ||
490 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, | ||
491 | kfd_ioctl_get_version, 0), | ||
492 | |||
493 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, | ||
494 | kfd_ioctl_create_queue, 0), | ||
495 | |||
496 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, | ||
497 | kfd_ioctl_destroy_queue, 0), | ||
498 | |||
499 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, | ||
500 | kfd_ioctl_set_memory_policy, 0), | ||
501 | |||
502 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, | ||
503 | kfd_ioctl_get_clock_counters, 0), | ||
504 | |||
505 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, | ||
506 | kfd_ioctl_get_process_apertures, 0), | ||
507 | |||
508 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, | ||
509 | kfd_ioctl_update_queue, 0), | ||
510 | }; | ||
511 | |||
512 | #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) | ||
513 | |||
485 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 514 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
486 | { | 515 | { |
487 | struct kfd_process *process; | 516 | struct kfd_process *process; |
517 | amdkfd_ioctl_t *func; | ||
518 | const struct amdkfd_ioctl_desc *ioctl = NULL; | ||
519 | unsigned int nr = _IOC_NR(cmd); | ||
488 | char stack_kdata[128]; | 520 | char stack_kdata[128]; |
489 | char *kdata = NULL; | 521 | char *kdata = NULL; |
490 | unsigned int usize, asize; | 522 | unsigned int usize, asize; |
491 | int retcode = -EINVAL; | 523 | int retcode = -EINVAL; |
492 | 524 | ||
493 | dev_dbg(kfd_device, | 525 | if (nr >= AMDKFD_CORE_IOCTL_COUNT) |
494 | "ioctl cmd 0x%x (#%d), arg 0x%lx\n", | 526 | goto err_i1; |
495 | cmd, _IOC_NR(cmd), arg); | 527 | |
528 | if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { | ||
529 | u32 amdkfd_size; | ||
530 | |||
531 | ioctl = &amdkfd_ioctls[nr]; | ||
532 | |||
533 | amdkfd_size = _IOC_SIZE(ioctl->cmd); | ||
534 | usize = asize = _IOC_SIZE(cmd); | ||
535 | if (amdkfd_size > asize) | ||
536 | asize = amdkfd_size; | ||
537 | |||
538 | cmd = ioctl->cmd; | ||
539 | } else | ||
540 | goto err_i1; | ||
541 | |||
542 | dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg); | ||
496 | 543 | ||
497 | process = kfd_get_process(current); | 544 | process = kfd_get_process(current); |
498 | if (IS_ERR(process)) | 545 | if (IS_ERR(process)) { |
499 | return PTR_ERR(process); | 546 | dev_dbg(kfd_device, "no process\n"); |
547 | goto err_i1; | ||
548 | } | ||
549 | |||
550 | /* Do not trust userspace, use our own definition */ | ||
551 | func = ioctl->func; | ||
552 | |||
553 | if (unlikely(!func)) { | ||
554 | dev_dbg(kfd_device, "no function\n"); | ||
555 | retcode = -EINVAL; | ||
556 | goto err_i1; | ||
557 | } | ||
500 | 558 | ||
501 | if (cmd & (IOC_IN | IOC_OUT)) { | 559 | if (cmd & (IOC_IN | IOC_OUT)) { |
502 | if (asize <= sizeof(stack_kdata)) { | 560 | if (asize <= sizeof(stack_kdata)) { |
@@ -521,55 +579,17 @@ static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | |||
521 | memset(kdata, 0, usize); | 579 | memset(kdata, 0, usize); |
522 | } | 580 | } |
523 | 581 | ||
524 | 582 | retcode = func(filep, process, kdata); | |
525 | switch (cmd) { | ||
526 | case AMDKFD_IOC_GET_VERSION: | ||
527 | retcode = kfd_ioctl_get_version(filep, process, kdata); | ||
528 | break; | ||
529 | |||
530 | case AMDKFD_IOC_CREATE_QUEUE: | ||
531 | retcode = kfd_ioctl_create_queue(filep, process, | ||
532 | kdata); | ||
533 | break; | ||
534 | |||
535 | case AMDKFD_IOC_DESTROY_QUEUE: | ||
536 | retcode = kfd_ioctl_destroy_queue(filep, process, | ||
537 | kdata); | ||
538 | break; | ||
539 | |||
540 | case AMDKFD_IOC_SET_MEMORY_POLICY: | ||
541 | retcode = kfd_ioctl_set_memory_policy(filep, process, | ||
542 | kdata); | ||
543 | break; | ||
544 | |||
545 | case AMDKFD_IOC_GET_CLOCK_COUNTERS: | ||
546 | retcode = kfd_ioctl_get_clock_counters(filep, process, | ||
547 | kdata); | ||
548 | break; | ||
549 | |||
550 | case AMDKFD_IOC_GET_PROCESS_APERTURES: | ||
551 | retcode = kfd_ioctl_get_process_apertures(filep, process, | ||
552 | kdata); | ||
553 | break; | ||
554 | |||
555 | case AMDKFD_IOC_UPDATE_QUEUE: | ||
556 | retcode = kfd_ioctl_update_queue(filep, process, | ||
557 | kdata); | ||
558 | break; | ||
559 | |||
560 | default: | ||
561 | dev_dbg(kfd_device, | ||
562 | "unknown ioctl cmd 0x%x, arg 0x%lx)\n", | ||
563 | cmd, arg); | ||
564 | retcode = -EINVAL; | ||
565 | break; | ||
566 | } | ||
567 | 583 | ||
568 | if (cmd & IOC_OUT) | 584 | if (cmd & IOC_OUT) |
569 | if (copy_to_user((void __user *)arg, kdata, usize) != 0) | 585 | if (copy_to_user((void __user *)arg, kdata, usize) != 0) |
570 | retcode = -EFAULT; | 586 | retcode = -EFAULT; |
571 | 587 | ||
572 | err_i1: | 588 | err_i1: |
589 | if (!ioctl) | ||
590 | dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", | ||
591 | task_pid_nr(current), cmd, nr); | ||
592 | |||
573 | if (kdata != stack_kdata) | 593 | if (kdata != stack_kdata) |
574 | kfree(kdata); | 594 | kfree(kdata); |
575 | 595 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f9fb81e3bb09..a5edb29507e3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -463,6 +463,24 @@ struct kfd_process { | |||
463 | bool is_32bit_user_mode; | 463 | bool is_32bit_user_mode; |
464 | }; | 464 | }; |
465 | 465 | ||
466 | /** | ||
467 | * Ioctl function type. | ||
468 | * | ||
469 | * \param filep pointer to file structure. | ||
470 | * \param p amdkfd process pointer. | ||
471 | * \param data pointer to arg that was copied from user. | ||
472 | */ | ||
473 | typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, | ||
474 | void *data); | ||
475 | |||
476 | struct amdkfd_ioctl_desc { | ||
477 | unsigned int cmd; | ||
478 | int flags; | ||
479 | amdkfd_ioctl_t *func; | ||
480 | unsigned int cmd_drv; | ||
481 | const char *name; | ||
482 | }; | ||
483 | |||
466 | void kfd_process_create_wq(void); | 484 | void kfd_process_create_wq(void); |
467 | void kfd_process_destroy_wq(void); | 485 | void kfd_process_destroy_wq(void); |
468 | struct kfd_process *kfd_create_process(const struct task_struct *); | 486 | struct kfd_process *kfd_create_process(const struct task_struct *); |