aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/s390/crypto/z90main.c140
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 *);
385static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *); 385static ssize_t z90crypt_read(struct file *, char __user *, size_t, loff_t *);
386static ssize_t z90crypt_write(struct file *, const char __user *, 386static ssize_t z90crypt_write(struct file *, const char __user *,
387 size_t, loff_t *); 387 size_t, loff_t *);
388static int z90crypt_ioctl(struct inode *, struct file *, 388static long z90crypt_unlocked_ioctl(struct file *, unsigned int, unsigned long);
389 unsigned int, unsigned long); 389static long z90crypt_compat_ioctl(struct file *, unsigned int, unsigned long);
390 390
391static void z90crypt_reader_task(unsigned long); 391static void z90crypt_reader_task(unsigned long);
392static void z90crypt_schedule_reader_task(unsigned long); 392static void z90crypt_schedule_reader_task(unsigned long);
@@ -433,12 +433,15 @@ static atomic_t total_open;
433static atomic_t z90crypt_step; 433static atomic_t z90crypt_step;
434 434
435static struct file_operations z90crypt_fops = { 435static 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
477static int 480static long
478trans_modexpo32(unsigned int fd, unsigned int cmd, unsigned long arg, 481trans_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
521static int 523static long
522trans_modexpo_crt32(unsigned int fd, unsigned int cmd, unsigned long arg, 524trans_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
559static int compatible_ioctls[] = { 559static long
560 ICAZ90STATUS, Z90QUIESCE, Z90STAT_TOTALCOUNT, Z90STAT_PCICACOUNT, 560z90crypt_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
567static 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
578static 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
612static inline void z90_unregister_ioctl32s(void)
613{
614}
615
616static 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
738init_module_cleanup: 703init_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 */
1807static int 1768static long
1808z90crypt_ioctl(struct inode *inode, struct file *filp, 1769z90crypt_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;