diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/s390/crypto/zcrypt_api.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 164 |
1 files changed, 78 insertions, 86 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 65b6a96afe6b..304caf549973 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c | |||
@@ -33,8 +33,10 @@ | |||
33 | #include <linux/miscdevice.h> | 33 | #include <linux/miscdevice.h> |
34 | #include <linux/fs.h> | 34 | #include <linux/fs.h> |
35 | #include <linux/proc_fs.h> | 35 | #include <linux/proc_fs.h> |
36 | #include <linux/seq_file.h> | ||
36 | #include <linux/compat.h> | 37 | #include <linux/compat.h> |
37 | #include <linux/smp_lock.h> | 38 | #include <linux/smp_lock.h> |
39 | #include <linux/slab.h> | ||
38 | #include <asm/atomic.h> | 40 | #include <asm/atomic.h> |
39 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
40 | #include <linux/hw_random.h> | 42 | #include <linux/hw_random.h> |
@@ -299,9 +301,7 @@ static ssize_t zcrypt_write(struct file *filp, const char __user *buf, | |||
299 | */ | 301 | */ |
300 | static int zcrypt_open(struct inode *inode, struct file *filp) | 302 | static int zcrypt_open(struct inode *inode, struct file *filp) |
301 | { | 303 | { |
302 | lock_kernel(); | ||
303 | atomic_inc(&zcrypt_open_count); | 304 | atomic_inc(&zcrypt_open_count); |
304 | unlock_kernel(); | ||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
@@ -395,10 +395,12 @@ static long zcrypt_rsa_crt(struct ica_rsa_modexpo_crt *crt) | |||
395 | * u_mult_inv > 128 bytes. | 395 | * u_mult_inv > 128 bytes. |
396 | */ | 396 | */ |
397 | if (copied == 0) { | 397 | if (copied == 0) { |
398 | int len; | 398 | unsigned int len; |
399 | spin_unlock_bh(&zcrypt_device_lock); | 399 | spin_unlock_bh(&zcrypt_device_lock); |
400 | /* len is max 256 / 2 - 120 = 8 */ | 400 | /* len is max 256 / 2 - 120 = 8 */ |
401 | len = crt->inputdatalength / 2 - 120; | 401 | len = crt->inputdatalength / 2 - 120; |
402 | if (len > sizeof(z1)) | ||
403 | return -EFAULT; | ||
402 | z1 = z2 = z3 = 0; | 404 | z1 = z2 = z3 = 0; |
403 | if (copy_from_user(&z1, crt->np_prime, len) || | 405 | if (copy_from_user(&z1, crt->np_prime, len) || |
404 | copy_from_user(&z2, crt->bp_key, len) || | 406 | copy_from_user(&z2, crt->bp_key, len) || |
@@ -912,122 +914,105 @@ static struct miscdevice zcrypt_misc_device = { | |||
912 | */ | 914 | */ |
913 | static struct proc_dir_entry *zcrypt_entry; | 915 | static struct proc_dir_entry *zcrypt_entry; |
914 | 916 | ||
915 | static int sprintcl(unsigned char *outaddr, unsigned char *addr, | 917 | static void sprintcl(struct seq_file *m, unsigned char *addr, unsigned int len) |
916 | unsigned int len) | ||
917 | { | 918 | { |
918 | int hl, i; | 919 | int i; |
919 | 920 | ||
920 | hl = 0; | ||
921 | for (i = 0; i < len; i++) | 921 | for (i = 0; i < len; i++) |
922 | hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]); | 922 | seq_printf(m, "%01x", (unsigned int) addr[i]); |
923 | hl += sprintf(outaddr+hl, " "); | 923 | seq_putc(m, ' '); |
924 | return hl; | ||
925 | } | 924 | } |
926 | 925 | ||
927 | static int sprintrw(unsigned char *outaddr, unsigned char *addr, | 926 | static void sprintrw(struct seq_file *m, unsigned char *addr, unsigned int len) |
928 | unsigned int len) | ||
929 | { | 927 | { |
930 | int hl, inl, c, cx; | 928 | int inl, c, cx; |
931 | 929 | ||
932 | hl = sprintf(outaddr, " "); | 930 | seq_printf(m, " "); |
933 | inl = 0; | 931 | inl = 0; |
934 | for (c = 0; c < (len / 16); c++) { | 932 | for (c = 0; c < (len / 16); c++) { |
935 | hl += sprintcl(outaddr+hl, addr+inl, 16); | 933 | sprintcl(m, addr+inl, 16); |
936 | inl += 16; | 934 | inl += 16; |
937 | } | 935 | } |
938 | cx = len%16; | 936 | cx = len%16; |
939 | if (cx) { | 937 | if (cx) { |
940 | hl += sprintcl(outaddr+hl, addr+inl, cx); | 938 | sprintcl(m, addr+inl, cx); |
941 | inl += cx; | 939 | inl += cx; |
942 | } | 940 | } |
943 | hl += sprintf(outaddr+hl, "\n"); | 941 | seq_putc(m, '\n'); |
944 | return hl; | ||
945 | } | 942 | } |
946 | 943 | ||
947 | static int sprinthx(unsigned char *title, unsigned char *outaddr, | 944 | static void sprinthx(unsigned char *title, struct seq_file *m, |
948 | unsigned char *addr, unsigned int len) | 945 | unsigned char *addr, unsigned int len) |
949 | { | 946 | { |
950 | int hl, inl, r, rx; | 947 | int inl, r, rx; |
951 | 948 | ||
952 | hl = sprintf(outaddr, "\n%s\n", title); | 949 | seq_printf(m, "\n%s\n", title); |
953 | inl = 0; | 950 | inl = 0; |
954 | for (r = 0; r < (len / 64); r++) { | 951 | for (r = 0; r < (len / 64); r++) { |
955 | hl += sprintrw(outaddr+hl, addr+inl, 64); | 952 | sprintrw(m, addr+inl, 64); |
956 | inl += 64; | 953 | inl += 64; |
957 | } | 954 | } |
958 | rx = len % 64; | 955 | rx = len % 64; |
959 | if (rx) { | 956 | if (rx) { |
960 | hl += sprintrw(outaddr+hl, addr+inl, rx); | 957 | sprintrw(m, addr+inl, rx); |
961 | inl += rx; | 958 | inl += rx; |
962 | } | 959 | } |
963 | hl += sprintf(outaddr+hl, "\n"); | 960 | seq_putc(m, '\n'); |
964 | return hl; | ||
965 | } | 961 | } |
966 | 962 | ||
967 | static int sprinthx4(unsigned char *title, unsigned char *outaddr, | 963 | static void sprinthx4(unsigned char *title, struct seq_file *m, |
968 | unsigned int *array, unsigned int len) | 964 | unsigned int *array, unsigned int len) |
969 | { | 965 | { |
970 | int hl, r; | 966 | int r; |
971 | 967 | ||
972 | hl = sprintf(outaddr, "\n%s\n", title); | 968 | seq_printf(m, "\n%s\n", title); |
973 | for (r = 0; r < len; r++) { | 969 | for (r = 0; r < len; r++) { |
974 | if ((r % 8) == 0) | 970 | if ((r % 8) == 0) |
975 | hl += sprintf(outaddr+hl, " "); | 971 | seq_printf(m, " "); |
976 | hl += sprintf(outaddr+hl, "%08X ", array[r]); | 972 | seq_printf(m, "%08X ", array[r]); |
977 | if ((r % 8) == 7) | 973 | if ((r % 8) == 7) |
978 | hl += sprintf(outaddr+hl, "\n"); | 974 | seq_putc(m, '\n'); |
979 | } | 975 | } |
980 | hl += sprintf(outaddr+hl, "\n"); | 976 | seq_putc(m, '\n'); |
981 | return hl; | ||
982 | } | 977 | } |
983 | 978 | ||
984 | static int zcrypt_status_read(char *resp_buff, char **start, off_t offset, | 979 | static int zcrypt_proc_show(struct seq_file *m, void *v) |
985 | int count, int *eof, void *data) | ||
986 | { | 980 | { |
987 | unsigned char *workarea; | 981 | char workarea[sizeof(int) * AP_DEVICES]; |
988 | int len; | 982 | |
989 | 983 | seq_printf(m, "\nzcrypt version: %d.%d.%d\n", | |
990 | len = 0; | 984 | ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT); |
991 | 985 | seq_printf(m, "Cryptographic domain: %d\n", ap_domain_index); | |
992 | /* resp_buff is a page. Use the right half for a work area */ | 986 | seq_printf(m, "Total device count: %d\n", zcrypt_device_count); |
993 | workarea = resp_buff + 2000; | 987 | seq_printf(m, "PCICA count: %d\n", zcrypt_count_type(ZCRYPT_PCICA)); |
994 | len += sprintf(resp_buff + len, "\nzcrypt version: %d.%d.%d\n", | 988 | seq_printf(m, "PCICC count: %d\n", zcrypt_count_type(ZCRYPT_PCICC)); |
995 | ZCRYPT_VERSION, ZCRYPT_RELEASE, ZCRYPT_VARIANT); | 989 | seq_printf(m, "PCIXCC MCL2 count: %d\n", |
996 | len += sprintf(resp_buff + len, "Cryptographic domain: %d\n", | 990 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL2)); |
997 | ap_domain_index); | 991 | seq_printf(m, "PCIXCC MCL3 count: %d\n", |
998 | len += sprintf(resp_buff + len, "Total device count: %d\n", | 992 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL3)); |
999 | zcrypt_device_count); | 993 | seq_printf(m, "CEX2C count: %d\n", zcrypt_count_type(ZCRYPT_CEX2C)); |
1000 | len += sprintf(resp_buff + len, "PCICA count: %d\n", | 994 | seq_printf(m, "CEX2A count: %d\n", zcrypt_count_type(ZCRYPT_CEX2A)); |
1001 | zcrypt_count_type(ZCRYPT_PCICA)); | 995 | seq_printf(m, "CEX3C count: %d\n", zcrypt_count_type(ZCRYPT_CEX3C)); |
1002 | len += sprintf(resp_buff + len, "PCICC count: %d\n", | 996 | seq_printf(m, "CEX3A count: %d\n", zcrypt_count_type(ZCRYPT_CEX3A)); |
1003 | zcrypt_count_type(ZCRYPT_PCICC)); | 997 | seq_printf(m, "requestq count: %d\n", zcrypt_requestq_count()); |
1004 | len += sprintf(resp_buff + len, "PCIXCC MCL2 count: %d\n", | 998 | seq_printf(m, "pendingq count: %d\n", zcrypt_pendingq_count()); |
1005 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL2)); | 999 | seq_printf(m, "Total open handles: %d\n\n", |
1006 | len += sprintf(resp_buff + len, "PCIXCC MCL3 count: %d\n", | 1000 | atomic_read(&zcrypt_open_count)); |
1007 | zcrypt_count_type(ZCRYPT_PCIXCC_MCL3)); | ||
1008 | len += sprintf(resp_buff + len, "CEX2C count: %d\n", | ||
1009 | zcrypt_count_type(ZCRYPT_CEX2C)); | ||
1010 | len += sprintf(resp_buff + len, "CEX2A count: %d\n", | ||
1011 | zcrypt_count_type(ZCRYPT_CEX2A)); | ||
1012 | len += sprintf(resp_buff + len, "requestq count: %d\n", | ||
1013 | zcrypt_requestq_count()); | ||
1014 | len += sprintf(resp_buff + len, "pendingq count: %d\n", | ||
1015 | zcrypt_pendingq_count()); | ||
1016 | len += sprintf(resp_buff + len, "Total open handles: %d\n\n", | ||
1017 | atomic_read(&zcrypt_open_count)); | ||
1018 | zcrypt_status_mask(workarea); | 1001 | zcrypt_status_mask(workarea); |
1019 | len += sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " | 1002 | sprinthx("Online devices: 1=PCICA 2=PCICC 3=PCIXCC(MCL2) " |
1020 | "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A", | 1003 | "4=PCIXCC(MCL3) 5=CEX2C 6=CEX2A 7=CEX3C 8=CEX3A", |
1021 | resp_buff+len, workarea, AP_DEVICES); | 1004 | m, workarea, AP_DEVICES); |
1022 | zcrypt_qdepth_mask(workarea); | 1005 | zcrypt_qdepth_mask(workarea); |
1023 | len += sprinthx("Waiting work element counts", | 1006 | sprinthx("Waiting work element counts", m, workarea, AP_DEVICES); |
1024 | resp_buff+len, workarea, AP_DEVICES); | ||
1025 | zcrypt_perdev_reqcnt((int *) workarea); | 1007 | zcrypt_perdev_reqcnt((int *) workarea); |
1026 | len += sprinthx4("Per-device successfully completed request counts", | 1008 | sprinthx4("Per-device successfully completed request counts", |
1027 | resp_buff+len,(unsigned int *) workarea, AP_DEVICES); | 1009 | m, (unsigned int *) workarea, AP_DEVICES); |
1028 | *eof = 1; | 1010 | return 0; |
1029 | memset((void *) workarea, 0x00, AP_DEVICES * sizeof(unsigned int)); | 1011 | } |
1030 | return len; | 1012 | |
1013 | static int zcrypt_proc_open(struct inode *inode, struct file *file) | ||
1014 | { | ||
1015 | return single_open(file, zcrypt_proc_show, NULL); | ||
1031 | } | 1016 | } |
1032 | 1017 | ||
1033 | static void zcrypt_disable_card(int index) | 1018 | static void zcrypt_disable_card(int index) |
@@ -1057,11 +1042,11 @@ static void zcrypt_enable_card(int index) | |||
1057 | spin_unlock_bh(&zcrypt_device_lock); | 1042 | spin_unlock_bh(&zcrypt_device_lock); |
1058 | } | 1043 | } |
1059 | 1044 | ||
1060 | static int zcrypt_status_write(struct file *file, const char __user *buffer, | 1045 | static ssize_t zcrypt_proc_write(struct file *file, const char __user *buffer, |
1061 | unsigned long count, void *data) | 1046 | size_t count, loff_t *pos) |
1062 | { | 1047 | { |
1063 | unsigned char *lbuf, *ptr; | 1048 | unsigned char *lbuf, *ptr; |
1064 | unsigned long local_count; | 1049 | size_t local_count; |
1065 | int j; | 1050 | int j; |
1066 | 1051 | ||
1067 | if (count <= 0) | 1052 | if (count <= 0) |
@@ -1095,8 +1080,9 @@ static int zcrypt_status_write(struct file *file, const char __user *buffer, | |||
1095 | * '0' for no device, '1' for PCICA, '2' for PCICC, | 1080 | * '0' for no device, '1' for PCICA, '2' for PCICC, |
1096 | * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3, | 1081 | * '3' for PCIXCC_MCL2, '4' for PCIXCC_MCL3, |
1097 | * '5' for CEX2C and '6' for CEX2A' | 1082 | * '5' for CEX2C and '6' for CEX2A' |
1083 | * '7' for CEX3C and '8' for CEX3A | ||
1098 | */ | 1084 | */ |
1099 | if (*ptr >= '0' && *ptr <= '6') | 1085 | if (*ptr >= '0' && *ptr <= '8') |
1100 | j++; | 1086 | j++; |
1101 | else if (*ptr == 'd' || *ptr == 'D') | 1087 | else if (*ptr == 'd' || *ptr == 'D') |
1102 | zcrypt_disable_card(j++); | 1088 | zcrypt_disable_card(j++); |
@@ -1110,6 +1096,15 @@ out: | |||
1110 | return count; | 1096 | return count; |
1111 | } | 1097 | } |
1112 | 1098 | ||
1099 | static const struct file_operations zcrypt_proc_fops = { | ||
1100 | .owner = THIS_MODULE, | ||
1101 | .open = zcrypt_proc_open, | ||
1102 | .read = seq_read, | ||
1103 | .llseek = seq_lseek, | ||
1104 | .release = single_release, | ||
1105 | .write = zcrypt_proc_write, | ||
1106 | }; | ||
1107 | |||
1113 | static int zcrypt_rng_device_count; | 1108 | static int zcrypt_rng_device_count; |
1114 | static u32 *zcrypt_rng_buffer; | 1109 | static u32 *zcrypt_rng_buffer; |
1115 | static int zcrypt_rng_buffer_index; | 1110 | static int zcrypt_rng_buffer_index; |
@@ -1192,14 +1187,11 @@ int __init zcrypt_api_init(void) | |||
1192 | goto out; | 1187 | goto out; |
1193 | 1188 | ||
1194 | /* Set up the proc file system */ | 1189 | /* Set up the proc file system */ |
1195 | zcrypt_entry = create_proc_entry("driver/z90crypt", 0644, NULL); | 1190 | zcrypt_entry = proc_create("driver/z90crypt", 0644, NULL, &zcrypt_proc_fops); |
1196 | if (!zcrypt_entry) { | 1191 | if (!zcrypt_entry) { |
1197 | rc = -ENOMEM; | 1192 | rc = -ENOMEM; |
1198 | goto out_misc; | 1193 | goto out_misc; |
1199 | } | 1194 | } |
1200 | zcrypt_entry->data = NULL; | ||
1201 | zcrypt_entry->read_proc = zcrypt_status_read; | ||
1202 | zcrypt_entry->write_proc = zcrypt_status_write; | ||
1203 | 1195 | ||
1204 | return 0; | 1196 | return 0; |
1205 | 1197 | ||