diff options
Diffstat (limited to 'drivers/s390/crypto/z90main.c')
-rw-r--r-- | drivers/s390/crypto/z90main.c | 140 |
1 files changed, 50 insertions, 90 deletions
diff --git a/drivers/s390/crypto/z90main.c b/drivers/s390/crypto/z90main.c index a98c00c02559..9ec29bb41b28 100644 --- a/drivers/s390/crypto/z90main.c +++ b/drivers/s390/crypto/z90main.c | |||
@@ -385,8 +385,8 @@ static int z90crypt_release(struct inode *, struct file *); | |||
385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); | 385 | static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); |
386 | static ssize_t z90crypt_write(struct file *, const char __user *, | 386 | static ssize_t z90crypt_write(struct file *, const char __user *, |
387 | size_t, loff_t *); | 387 | size_t, loff_t *); |
388 | static int z90crypt_ioctl(struct inode *, struct file *, | 388 | static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long); |
389 | unsigned int, unsigned long); | 389 | static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long); |
390 | 390 | ||
391 | static void z90crypt_reader_task(unsigned long); | 391 | static void z90crypt_reader_task(unsigned long); |
392 | static void z90crypt_schedule_reader_task(unsigned long); | 392 | static void z90crypt_schedule_reader_task(unsigned long); |
@@ -433,12 +433,15 @@ static atomic_t total_open; | |||
433 | static atomic_t z90crypt_step; | 433 | static atomic_t z90crypt_step; |
434 | 434 | ||
435 | static struct file_operations z90crypt_fops = { | 435 | static struct file_operations z90crypt_fops = { |
436 | .owner = THIS_MODULE, | 436 | .owner = THIS_MODULE, |
437 | .read = z90crypt_read, | 437 | .read = z90crypt_read, |
438 | .write = z90crypt_write, | 438 | .write = z90crypt_write, |
439 | .ioctl = z90crypt_ioctl, | 439 | .unlocked_ioctl = z90crypt_unlocked_ioctl, |
440 | .open = z90crypt_open, | 440 | #ifdef CONFIG_COMPAT |
441 | .release = z90crypt_release | 441 | .compat_ioctl = z90crypt_compat_ioctl, |
442 | #endif | ||
443 | .open = z90crypt_open, | ||
444 | .release = z90crypt_release | ||
442 | }; | 445 | }; |
443 | 446 | ||
444 | #ifndef Z90CRYPT_USE_HOTPLUG | 447 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -474,14 +477,13 @@ struct ica_rsa_modexpo_32 { // For 32-bit callers | |||
474 | compat_uptr_t n_modulus; | 477 | compat_uptr_t n_modulus; |
475 | }; | 478 | }; |
476 | 479 | ||
477 | static int | 480 | static long |
478 | trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | 481 | trans_modexpo32(struct file *filp, unsigned int cmd, unsigned long arg) |
479 | struct file *file) | ||
480 | { | 482 | { |
481 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); | 483 | struct ica_rsa_modexpo_32 __user *mex32u = compat_ptr(arg); |
482 | struct ica_rsa_modexpo_32 mex32k; | 484 | struct ica_rsa_modexpo_32 mex32k; |
483 | struct ica_rsa_modexpo __user *mex64; | 485 | struct ica_rsa_modexpo __user *mex64; |
484 | int ret = 0; | 486 | long ret = 0; |
485 | unsigned int i; | 487 | unsigned int i; |
486 | 488 | ||
487 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) | 489 | if (!access_ok(VERIFY_WRITE, mex32u, sizeof(struct ica_rsa_modexpo_32))) |
@@ -498,7 +500,7 @@ trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
498 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || | 500 | __put_user(compat_ptr(mex32k.b_key), &mex64->b_key) || |
499 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) | 501 | __put_user(compat_ptr(mex32k.n_modulus), &mex64->n_modulus)) |
500 | return -EFAULT; | 502 | return -EFAULT; |
501 | ret = sys_ioctl(fd, cmd, (unsigned long)mex64); | 503 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)mex64); |
502 | if (!ret) | 504 | if (!ret) |
503 | if (__get_user(i, &mex64->outputdatalength) || | 505 | if (__get_user(i, &mex64->outputdatalength) || |
504 | __put_user(i, &mex32u->outputdatalength)) | 506 | __put_user(i, &mex32u->outputdatalength)) |
@@ -518,14 +520,13 @@ struct ica_rsa_modexpo_crt_32 { // For 32-bit callers | |||
518 | compat_uptr_t u_mult_inv; | 520 | compat_uptr_t u_mult_inv; |
519 | }; | 521 | }; |
520 | 522 | ||
521 | static int | 523 | static long |
522 | trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | 524 | trans_modexpo_crt32(struct file *filp, unsigned int cmd, unsigned long arg) |
523 | struct file *file) | ||
524 | { | 525 | { |
525 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); | 526 | struct ica_rsa_modexpo_crt_32 __user *crt32u = compat_ptr(arg); |
526 | struct ica_rsa_modexpo_crt_32 crt32k; | 527 | struct ica_rsa_modexpo_crt_32 crt32k; |
527 | struct ica_rsa_modexpo_crt __user *crt64; | 528 | struct ica_rsa_modexpo_crt __user *crt64; |
528 | int ret = 0; | 529 | long ret = 0; |
529 | unsigned int i; | 530 | unsigned int i; |
530 | 531 | ||
531 | if (!access_ok(VERIFY_WRITE, crt32u, | 532 | if (!access_ok(VERIFY_WRITE, crt32u, |
@@ -546,9 +547,8 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
546 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || | 547 | __put_user(compat_ptr(crt32k.np_prime), &crt64->np_prime) || |
547 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || | 548 | __put_user(compat_ptr(crt32k.nq_prime), &crt64->nq_prime) || |
548 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) | 549 | __put_user(compat_ptr(crt32k.u_mult_inv), &crt64->u_mult_inv)) |
549 | ret = -EFAULT; | 550 | return -EFAULT; |
550 | if (!ret) | 551 | ret = z90crypt_unlocked_ioctl(filp, cmd, (unsigned long)crt64); |
551 | ret = sys_ioctl(fd, cmd, (unsigned long)crt64); | ||
552 | if (!ret) | 552 | if (!ret) |
553 | if (__get_user(i, &crt64->outputdatalength) || | 553 | if (__get_user(i, &crt64->outputdatalength) || |
554 | __put_user(i, &crt32u->outputdatalength)) | 554 | __put_user(i, &crt32u->outputdatalength)) |
@@ -556,66 +556,34 @@ trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, | |||
556 | return ret; | 556 | return ret; |
557 | } | 557 | } |
558 | 558 | ||
559 | static int compatible_ioctls[] = { | 559 | static long |
560 | ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT, | 560 | z90crypt_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
561 | Z90STAT_PCICCCOUNT, Z90STAT_PCIXCCCOUNT, Z90STAT_PCIXCCMCL2COUNT, | ||
562 | Z90STAT_PCIXCCMCL3COUNT, Z90STAT_CEX2CCOUNT, Z90STAT_REQUESTQ_COUNT, | ||
563 | Z90STAT_PENDINGQ_COUNT, Z90STAT_TOTALOPEN_COUNT, Z90STAT_DOMAIN_INDEX, | ||
564 | Z90STAT_STATUS_MASK, Z90STAT_QDEPTH_MASK, Z90STAT_PERDEV_REQCNT, | ||
565 | }; | ||
566 | |||
567 | static void z90_unregister_ioctl32s(void) | ||
568 | { | ||
569 | int i; | ||
570 | |||
571 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
572 | unregister_ioctl32_conversion(ICARSACRT); | ||
573 | |||
574 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) | ||
575 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
576 | } | ||
577 | |||
578 | static int z90_register_ioctl32s(void) | ||
579 | { | ||
580 | int result, i; | ||
581 | |||
582 | result = register_ioctl32_conversion(ICARSAMODEXPO, trans_modexpo32); | ||
583 | if (result == -EBUSY) { | ||
584 | unregister_ioctl32_conversion(ICARSAMODEXPO); | ||
585 | result = register_ioctl32_conversion(ICARSAMODEXPO, | ||
586 | trans_modexpo32); | ||
587 | } | ||
588 | if (result) | ||
589 | return result; | ||
590 | result = register_ioctl32_conversion(ICARSACRT, trans_modexpo_crt32); | ||
591 | if (result == -EBUSY) { | ||
592 | unregister_ioctl32_conversion(ICARSACRT); | ||
593 | result = register_ioctl32_conversion(ICARSACRT, | ||
594 | trans_modexpo_crt32); | ||
595 | } | ||
596 | if (result) | ||
597 | return result; | ||
598 | |||
599 | for(i = 0; i < ARRAY_SIZE(compatible_ioctls); i++) { | ||
600 | result = register_ioctl32_conversion(compatible_ioctls[i], 0); | ||
601 | if (result == -EBUSY) { | ||
602 | unregister_ioctl32_conversion(compatible_ioctls[i]); | ||
603 | result = register_ioctl32_conversion( | ||
604 | compatible_ioctls[i], 0); | ||
605 | } | ||
606 | if (result) | ||
607 | return result; | ||
608 | } | ||
609 | return 0; | ||
610 | } | ||
611 | #else // !CONFIG_COMPAT | ||
612 | static inline void z90_unregister_ioctl32s(void) | ||
613 | { | ||
614 | } | ||
615 | |||
616 | static inline int z90_register_ioctl32s(void) | ||
617 | { | 561 | { |
618 | return 0; | 562 | switch (cmd) { |
563 | case ICAZ90STATUS: | ||
564 | case Z90QUIESCE: | ||
565 | case Z90STAT_TOTALCOUNT: | ||
566 | case Z90STAT_PCICACOUNT: | ||
567 | case Z90STAT_PCICCCOUNT: | ||
568 | case Z90STAT_PCIXCCCOUNT: | ||
569 | case Z90STAT_PCIXCCMCL2COUNT: | ||
570 | case Z90STAT_PCIXCCMCL3COUNT: | ||
571 | case Z90STAT_CEX2CCOUNT: | ||
572 | case Z90STAT_REQUESTQ_COUNT: | ||
573 | case Z90STAT_PENDINGQ_COUNT: | ||
574 | case Z90STAT_TOTALOPEN_COUNT: | ||
575 | case Z90STAT_DOMAIN_INDEX: | ||
576 | case Z90STAT_STATUS_MASK: | ||
577 | case Z90STAT_QDEPTH_MASK: | ||
578 | case Z90STAT_PERDEV_REQCNT: | ||
579 | return z90crypt_unlocked_ioctl(filp, cmd, arg); | ||
580 | case ICARSAMODEXPO: | ||
581 | return trans_modexpo32(filp, cmd, arg); | ||
582 | case ICARSACRT: | ||
583 | return trans_modexpo_crt32(filp, cmd, arg); | ||
584 | default: | ||
585 | return -ENOIOCTLCMD; | ||
586 | } | ||
619 | } | 587 | } |
620 | #endif | 588 | #endif |
621 | 589 | ||
@@ -730,14 +698,9 @@ z90crypt_init_module(void) | |||
730 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); | 698 | reader_timer.expires = jiffies + (READERTIME * HZ / 1000); |
731 | add_timer(&reader_timer); | 699 | add_timer(&reader_timer); |
732 | 700 | ||
733 | if ((result = z90_register_ioctl32s())) | ||
734 | goto init_module_cleanup; | ||
735 | |||
736 | return 0; // success | 701 | return 0; // success |
737 | 702 | ||
738 | init_module_cleanup: | 703 | init_module_cleanup: |
739 | z90_unregister_ioctl32s(); | ||
740 | |||
741 | #ifndef Z90CRYPT_USE_HOTPLUG | 704 | #ifndef Z90CRYPT_USE_HOTPLUG |
742 | if ((nresult = misc_deregister(&z90crypt_misc_device))) | 705 | if ((nresult = misc_deregister(&z90crypt_misc_device))) |
743 | PRINTK("misc_deregister failed with %d.\n", nresult); | 706 | PRINTK("misc_deregister failed with %d.\n", nresult); |
@@ -763,8 +726,6 @@ z90crypt_cleanup_module(void) | |||
763 | 726 | ||
764 | PDEBUG("PID %d\n", PID()); | 727 | PDEBUG("PID %d\n", PID()); |
765 | 728 | ||
766 | z90_unregister_ioctl32s(); | ||
767 | |||
768 | remove_proc_entry("driver/z90crypt", 0); | 729 | remove_proc_entry("driver/z90crypt", 0); |
769 | 730 | ||
770 | #ifndef Z90CRYPT_USE_HOTPLUG | 731 | #ifndef Z90CRYPT_USE_HOTPLUG |
@@ -800,7 +761,7 @@ z90crypt_cleanup_module(void) | |||
800 | * z90crypt_release | 761 | * z90crypt_release |
801 | * z90crypt_read | 762 | * z90crypt_read |
802 | * z90crypt_write | 763 | * z90crypt_write |
803 | * z90crypt_ioctl | 764 | * z90crypt_unlocked_ioctl |
804 | * z90crypt_status | 765 | * z90crypt_status |
805 | * z90crypt_status_write | 766 | * z90crypt_status_write |
806 | * disable_card | 767 | * disable_card |
@@ -1804,9 +1765,8 @@ z90crypt_rsa(struct priv_data *private_data_p, pid_t pid, | |||
1804 | * This function is a little long, but it's really just one large switch | 1765 | * This function is a little long, but it's really just one large switch |
1805 | * statement. | 1766 | * statement. |
1806 | */ | 1767 | */ |
1807 | static int | 1768 | static long |
1808 | z90crypt_ioctl(struct inode *inode, struct file *filp, | 1769 | z90crypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
1809 | unsigned int cmd, unsigned long arg) | ||
1810 | { | 1770 | { |
1811 | struct priv_data *private_data_p = filp->private_data; | 1771 | struct priv_data *private_data_p = filp->private_data; |
1812 | unsigned char *status; | 1772 | unsigned char *status; |