diff options
| -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; |
