aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/zcrypt_api.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/s390/crypto/zcrypt_api.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c164
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 */
300static int zcrypt_open(struct inode *inode, struct file *filp) 302static 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 */
913static struct proc_dir_entry *zcrypt_entry; 915static struct proc_dir_entry *zcrypt_entry;
914 916
915static int sprintcl(unsigned char *outaddr, unsigned char *addr, 917static 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
927static int sprintrw(unsigned char *outaddr, unsigned char *addr, 926static 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
947static int sprinthx(unsigned char *title, unsigned char *outaddr, 944static 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
967static int sprinthx4(unsigned char *title, unsigned char *outaddr, 963static 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
984static int zcrypt_status_read(char *resp_buff, char **start, off_t offset, 979static 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
1013static int zcrypt_proc_open(struct inode *inode, struct file *file)
1014{
1015 return single_open(file, zcrypt_proc_show, NULL);
1031} 1016}
1032 1017
1033static void zcrypt_disable_card(int index) 1018static 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
1060static int zcrypt_status_write(struct file *file, const char __user *buffer, 1045static 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
1099static 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
1113static int zcrypt_rng_device_count; 1108static int zcrypt_rng_device_count;
1114static u32 *zcrypt_rng_buffer; 1109static u32 *zcrypt_rng_buffer;
1115static int zcrypt_rng_buffer_index; 1110static 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