diff options
Diffstat (limited to 'drivers/s390/crypto/zcrypt_pcixcc.c')
-rw-r--r-- | drivers/s390/crypto/zcrypt_pcixcc.c | 41 |
1 files changed, 35 insertions, 6 deletions
diff --git a/drivers/s390/crypto/zcrypt_pcixcc.c b/drivers/s390/crypto/zcrypt_pcixcc.c index 5677b40e4ac0..510fab4577d4 100644 --- a/drivers/s390/crypto/zcrypt_pcixcc.c +++ b/drivers/s390/crypto/zcrypt_pcixcc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/err.h> | 31 | #include <linux/err.h> |
32 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/slab.h> | ||
33 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
34 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
35 | 36 | ||
@@ -43,10 +44,13 @@ | |||
43 | #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */ | 44 | #define PCIXCC_MIN_MOD_SIZE 16 /* 128 bits */ |
44 | #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ | 45 | #define PCIXCC_MIN_MOD_SIZE_OLD 64 /* 512 bits */ |
45 | #define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */ | 46 | #define PCIXCC_MAX_MOD_SIZE 256 /* 2048 bits */ |
47 | #define CEX3C_MIN_MOD_SIZE PCIXCC_MIN_MOD_SIZE | ||
48 | #define CEX3C_MAX_MOD_SIZE PCIXCC_MAX_MOD_SIZE | ||
46 | 49 | ||
47 | #define PCIXCC_MCL2_SPEED_RATING 7870 /* FIXME: needs finetuning */ | 50 | #define PCIXCC_MCL2_SPEED_RATING 7870 |
48 | #define PCIXCC_MCL3_SPEED_RATING 7870 | 51 | #define PCIXCC_MCL3_SPEED_RATING 7870 |
49 | #define CEX2C_SPEED_RATING 8540 | 52 | #define CEX2C_SPEED_RATING 7000 |
53 | #define CEX3C_SPEED_RATING 6500 /* FIXME: needs finetuning */ | ||
50 | 54 | ||
51 | #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */ | 55 | #define PCIXCC_MAX_ICA_MESSAGE_SIZE 0x77c /* max size type6 v2 crt message */ |
52 | #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ | 56 | #define PCIXCC_MAX_ICA_RESPONSE_SIZE 0x77c /* max size type86 v2 reply */ |
@@ -72,7 +76,7 @@ struct response_type { | |||
72 | static struct ap_device_id zcrypt_pcixcc_ids[] = { | 76 | static struct ap_device_id zcrypt_pcixcc_ids[] = { |
73 | { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) }, | 77 | { AP_DEVICE(AP_DEVICE_TYPE_PCIXCC) }, |
74 | { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) }, | 78 | { AP_DEVICE(AP_DEVICE_TYPE_CEX2C) }, |
75 | { AP_DEVICE(AP_DEVICE_TYPE_CEX2C2) }, | 79 | { AP_DEVICE(AP_DEVICE_TYPE_CEX3C) }, |
76 | { /* end of list */ }, | 80 | { /* end of list */ }, |
77 | }; | 81 | }; |
78 | 82 | ||
@@ -326,6 +330,11 @@ static int XCRB_msg_to_type6CPRB_msgX(struct zcrypt_device *zdev, | |||
326 | function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; | 330 | function_code = ((unsigned char *)&msg->cprbx) + msg->cprbx.cprb_len; |
327 | memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); | 331 | memcpy(msg->hdr.function_code, function_code, sizeof(msg->hdr.function_code)); |
328 | 332 | ||
333 | if (memcmp(function_code, "US", 2) == 0) | ||
334 | ap_msg->special = 1; | ||
335 | else | ||
336 | ap_msg->special = 0; | ||
337 | |||
329 | /* copy data block */ | 338 | /* copy data block */ |
330 | if (xcRB->request_data_length && | 339 | if (xcRB->request_data_length && |
331 | copy_from_user(req_data, xcRB->request_data_address, | 340 | copy_from_user(req_data, xcRB->request_data_address, |
@@ -462,6 +471,8 @@ static int convert_type86_ica(struct zcrypt_device *zdev, | |||
462 | } | 471 | } |
463 | if (service_rc == 12 && service_rs == 769) | 472 | if (service_rc == 12 && service_rs == 769) |
464 | return -EINVAL; | 473 | return -EINVAL; |
474 | if (service_rc == 8 && service_rs == 72) | ||
475 | return -EINVAL; | ||
465 | zdev->online = 0; | 476 | zdev->online = 0; |
466 | return -EAGAIN; /* repeat the request on a different device. */ | 477 | return -EAGAIN; /* repeat the request on a different device. */ |
467 | } | 478 | } |
@@ -688,6 +699,7 @@ static long zcrypt_pcixcc_modexpo(struct zcrypt_device *zdev, | |||
688 | }; | 699 | }; |
689 | int rc; | 700 | int rc; |
690 | 701 | ||
702 | ap_init_message(&ap_msg); | ||
691 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 703 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
692 | if (!ap_msg.message) | 704 | if (!ap_msg.message) |
693 | return -ENOMEM; | 705 | return -ENOMEM; |
@@ -727,6 +739,7 @@ static long zcrypt_pcixcc_modexpo_crt(struct zcrypt_device *zdev, | |||
727 | }; | 739 | }; |
728 | int rc; | 740 | int rc; |
729 | 741 | ||
742 | ap_init_message(&ap_msg); | ||
730 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 743 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
731 | if (!ap_msg.message) | 744 | if (!ap_msg.message) |
732 | return -ENOMEM; | 745 | return -ENOMEM; |
@@ -766,6 +779,7 @@ static long zcrypt_pcixcc_send_cprb(struct zcrypt_device *zdev, | |||
766 | }; | 779 | }; |
767 | int rc; | 780 | int rc; |
768 | 781 | ||
782 | ap_init_message(&ap_msg); | ||
769 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); | 783 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); |
770 | if (!ap_msg.message) | 784 | if (!ap_msg.message) |
771 | return -ENOMEM; | 785 | return -ENOMEM; |
@@ -805,6 +819,7 @@ static long zcrypt_pcixcc_rng(struct zcrypt_device *zdev, | |||
805 | }; | 819 | }; |
806 | int rc; | 820 | int rc; |
807 | 821 | ||
822 | ap_init_message(&ap_msg); | ||
808 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); | 823 | ap_msg.message = kmalloc(PCIXCC_MAX_XCRB_MESSAGE_SIZE, GFP_KERNEL); |
809 | if (!ap_msg.message) | 824 | if (!ap_msg.message) |
810 | return -ENOMEM; | 825 | return -ENOMEM; |
@@ -972,6 +987,7 @@ static int zcrypt_pcixcc_rng_supported(struct ap_device *ap_dev) | |||
972 | } __attribute__((packed)) *reply; | 987 | } __attribute__((packed)) *reply; |
973 | int rc, i; | 988 | int rc, i; |
974 | 989 | ||
990 | ap_init_message(&ap_msg); | ||
975 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); | 991 | ap_msg.message = (void *) get_zeroed_page(GFP_KERNEL); |
976 | if (!ap_msg.message) | 992 | if (!ap_msg.message) |
977 | return -ENOMEM; | 993 | return -ENOMEM; |
@@ -1016,14 +1032,15 @@ out_free: | |||
1016 | static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) | 1032 | static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) |
1017 | { | 1033 | { |
1018 | struct zcrypt_device *zdev; | 1034 | struct zcrypt_device *zdev; |
1019 | int rc; | 1035 | int rc = 0; |
1020 | 1036 | ||
1021 | zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE); | 1037 | zdev = zcrypt_device_alloc(PCIXCC_MAX_RESPONSE_SIZE); |
1022 | if (!zdev) | 1038 | if (!zdev) |
1023 | return -ENOMEM; | 1039 | return -ENOMEM; |
1024 | zdev->ap_dev = ap_dev; | 1040 | zdev->ap_dev = ap_dev; |
1025 | zdev->online = 1; | 1041 | zdev->online = 1; |
1026 | if (ap_dev->device_type == AP_DEVICE_TYPE_PCIXCC) { | 1042 | switch (ap_dev->device_type) { |
1043 | case AP_DEVICE_TYPE_PCIXCC: | ||
1027 | rc = zcrypt_pcixcc_mcl(ap_dev); | 1044 | rc = zcrypt_pcixcc_mcl(ap_dev); |
1028 | if (rc < 0) { | 1045 | if (rc < 0) { |
1029 | zcrypt_device_free(zdev); | 1046 | zcrypt_device_free(zdev); |
@@ -1041,13 +1058,25 @@ static int zcrypt_pcixcc_probe(struct ap_device *ap_dev) | |||
1041 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; | 1058 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; |
1042 | zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; | 1059 | zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; |
1043 | } | 1060 | } |
1044 | } else { | 1061 | break; |
1062 | case AP_DEVICE_TYPE_CEX2C: | ||
1045 | zdev->user_space_type = ZCRYPT_CEX2C; | 1063 | zdev->user_space_type = ZCRYPT_CEX2C; |
1046 | zdev->type_string = "CEX2C"; | 1064 | zdev->type_string = "CEX2C"; |
1047 | zdev->speed_rating = CEX2C_SPEED_RATING; | 1065 | zdev->speed_rating = CEX2C_SPEED_RATING; |
1048 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; | 1066 | zdev->min_mod_size = PCIXCC_MIN_MOD_SIZE; |
1049 | zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; | 1067 | zdev->max_mod_size = PCIXCC_MAX_MOD_SIZE; |
1068 | break; | ||
1069 | case AP_DEVICE_TYPE_CEX3C: | ||
1070 | zdev->user_space_type = ZCRYPT_CEX3C; | ||
1071 | zdev->type_string = "CEX3C"; | ||
1072 | zdev->speed_rating = CEX3C_SPEED_RATING; | ||
1073 | zdev->min_mod_size = CEX3C_MIN_MOD_SIZE; | ||
1074 | zdev->max_mod_size = CEX3C_MAX_MOD_SIZE; | ||
1075 | break; | ||
1076 | default: | ||
1077 | goto out_free; | ||
1050 | } | 1078 | } |
1079 | |||
1051 | rc = zcrypt_pcixcc_rng_supported(ap_dev); | 1080 | rc = zcrypt_pcixcc_rng_supported(ap_dev); |
1052 | if (rc < 0) { | 1081 | if (rc < 0) { |
1053 | zcrypt_device_free(zdev); | 1082 | zcrypt_device_free(zdev); |