aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/zcrypt_api.c
diff options
context:
space:
mode:
authorHolger Dengler <hd@linux.vnet.ibm.com>2012-09-10 15:34:26 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-09-26 09:45:17 -0400
commitdabecb2933f7ae901c88cb10c71ab38ca7dfc38f (patch)
tree04d0094b077eddcf47c3c692dfc0eeda2de727d6 /drivers/s390/crypto/zcrypt_api.c
parent745e967a49b26725cc9f30105ff67c8fee8926d6 (diff)
s390/zcryt: Handle AP configuration changes
Detect external AP bus configuration changes and request an AP device rescan. Signed-off-by: Holger Dengler <hd@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_api.c')
-rw-r--r--drivers/s390/crypto/zcrypt_api.c114
1 files changed, 106 insertions, 8 deletions
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index f1f026e0b189..31cfaa556072 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -38,7 +38,10 @@
38#include <linux/atomic.h> 38#include <linux/atomic.h>
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
40#include <linux/hw_random.h> 40#include <linux/hw_random.h>
41#include <linux/debugfs.h>
42#include <asm/debug.h>
41 43
44#include "zcrypt_debug.h"
42#include "zcrypt_api.h" 45#include "zcrypt_api.h"
43 46
44/* 47/*
@@ -53,6 +56,10 @@ static DEFINE_SPINLOCK(zcrypt_device_lock);
53static LIST_HEAD(zcrypt_device_list); 56static LIST_HEAD(zcrypt_device_list);
54static int zcrypt_device_count = 0; 57static int zcrypt_device_count = 0;
55static atomic_t zcrypt_open_count = ATOMIC_INIT(0); 58static atomic_t zcrypt_open_count = ATOMIC_INIT(0);
59static atomic_t zcrypt_rescan_count = ATOMIC_INIT(0);
60
61atomic_t zcrypt_rescan_req = ATOMIC_INIT(0);
62EXPORT_SYMBOL(zcrypt_rescan_req);
56 63
57static int zcrypt_rng_device_add(void); 64static int zcrypt_rng_device_add(void);
58static void zcrypt_rng_device_remove(void); 65static void zcrypt_rng_device_remove(void);
@@ -60,6 +67,10 @@ static void zcrypt_rng_device_remove(void);
60static DEFINE_SPINLOCK(zcrypt_ops_list_lock); 67static DEFINE_SPINLOCK(zcrypt_ops_list_lock);
61static LIST_HEAD(zcrypt_ops_list); 68static LIST_HEAD(zcrypt_ops_list);
62 69
70static debug_info_t *zcrypt_dbf_common;
71static debug_info_t *zcrypt_dbf_devices;
72static struct dentry *debugfs_root;
73
63/* 74/*
64 * Device attributes common for all crypto devices. 75 * Device attributes common for all crypto devices.
65 */ 76 */
@@ -89,6 +100,8 @@ static ssize_t zcrypt_online_store(struct device *dev,
89 if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1) 100 if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
90 return -EINVAL; 101 return -EINVAL;
91 zdev->online = online; 102 zdev->online = online;
103 ZCRYPT_DBF_DEV(DBF_INFO, zdev, "dev%04xo%dman", zdev->ap_dev->qid,
104 zdev->online);
92 if (!online) 105 if (!online)
93 ap_flush_queue(zdev->ap_dev); 106 ap_flush_queue(zdev->ap_dev);
94 return count; 107 return count;
@@ -107,6 +120,24 @@ static struct attribute_group zcrypt_device_attr_group = {
107}; 120};
108 121
109/** 122/**
123 * Process a rescan of the transport layer.
124 *
125 * Returns 1, if the rescan has been processed, otherwise 0.
126 */
127static inline int zcrypt_process_rescan(void)
128{
129 if (atomic_read(&zcrypt_rescan_req)) {
130 atomic_set(&zcrypt_rescan_req, 0);
131 atomic_inc(&zcrypt_rescan_count);
132 ap_bus_force_rescan();
133 ZCRYPT_DBF_COMMON(DBF_INFO, "rescan%07d",
134 atomic_inc_return(&zcrypt_rescan_count));
135 return 1;
136 }
137 return 0;
138}
139
140/**
110 * __zcrypt_increase_preference(): Increase preference of a crypto device. 141 * __zcrypt_increase_preference(): Increase preference of a crypto device.
111 * @zdev: Pointer the crypto device 142 * @zdev: Pointer the crypto device
112 * 143 *
@@ -194,6 +225,7 @@ struct zcrypt_device *zcrypt_device_alloc(size_t max_response_size)
194 zdev->reply.length = max_response_size; 225 zdev->reply.length = max_response_size;
195 spin_lock_init(&zdev->lock); 226 spin_lock_init(&zdev->lock);
196 INIT_LIST_HEAD(&zdev->list); 227 INIT_LIST_HEAD(&zdev->list);
228 zdev->dbf_area = zcrypt_dbf_devices;
197 return zdev; 229 return zdev;
198 230
199out_free: 231out_free:
@@ -229,6 +261,8 @@ int zcrypt_device_register(struct zcrypt_device *zdev)
229 kref_init(&zdev->refcount); 261 kref_init(&zdev->refcount);
230 spin_lock_bh(&zcrypt_device_lock); 262 spin_lock_bh(&zcrypt_device_lock);
231 zdev->online = 1; /* New devices are online by default. */ 263 zdev->online = 1; /* New devices are online by default. */
264 ZCRYPT_DBF_DEV(DBF_INFO, zdev, "dev%04xo%dreg", zdev->ap_dev->qid,
265 zdev->online);
232 list_add_tail(&zdev->list, &zcrypt_device_list); 266 list_add_tail(&zdev->list, &zcrypt_device_list);
233 __zcrypt_increase_preference(zdev); 267 __zcrypt_increase_preference(zdev);
234 zcrypt_device_count++; 268 zcrypt_device_count++;
@@ -707,6 +741,11 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
707 do { 741 do {
708 rc = zcrypt_rsa_modexpo(&mex); 742 rc = zcrypt_rsa_modexpo(&mex);
709 } while (rc == -EAGAIN); 743 } while (rc == -EAGAIN);
744 /* on failure: retry once again after a requested rescan */
745 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
746 do {
747 rc = zcrypt_rsa_modexpo(&mex);
748 } while (rc == -EAGAIN);
710 if (rc) 749 if (rc)
711 return rc; 750 return rc;
712 return put_user(mex.outputdatalength, &umex->outputdatalength); 751 return put_user(mex.outputdatalength, &umex->outputdatalength);
@@ -719,6 +758,11 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
719 do { 758 do {
720 rc = zcrypt_rsa_crt(&crt); 759 rc = zcrypt_rsa_crt(&crt);
721 } while (rc == -EAGAIN); 760 } while (rc == -EAGAIN);
761 /* on failure: retry once again after a requested rescan */
762 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
763 do {
764 rc = zcrypt_rsa_crt(&crt);
765 } while (rc == -EAGAIN);
722 if (rc) 766 if (rc)
723 return rc; 767 return rc;
724 return put_user(crt.outputdatalength, &ucrt->outputdatalength); 768 return put_user(crt.outputdatalength, &ucrt->outputdatalength);
@@ -731,6 +775,11 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
731 do { 775 do {
732 rc = zcrypt_send_cprb(&xcRB); 776 rc = zcrypt_send_cprb(&xcRB);
733 } while (rc == -EAGAIN); 777 } while (rc == -EAGAIN);
778 /* on failure: retry once again after a requested rescan */
779 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
780 do {
781 rc = zcrypt_send_cprb(&xcRB);
782 } while (rc == -EAGAIN);
734 if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB))) 783 if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB)))
735 return -EFAULT; 784 return -EFAULT;
736 return rc; 785 return rc;
@@ -837,10 +886,15 @@ static long trans_modexpo32(struct file *filp, unsigned int cmd,
837 do { 886 do {
838 rc = zcrypt_rsa_modexpo(&mex64); 887 rc = zcrypt_rsa_modexpo(&mex64);
839 } while (rc == -EAGAIN); 888 } while (rc == -EAGAIN);
840 if (!rc) 889 /* on failure: retry once again after a requested rescan */
841 rc = put_user(mex64.outputdatalength, 890 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
842 &umex32->outputdatalength); 891 do {
843 return rc; 892 rc = zcrypt_rsa_modexpo(&mex64);
893 } while (rc == -EAGAIN);
894 if (rc)
895 return rc;
896 return put_user(mex64.outputdatalength,
897 &umex32->outputdatalength);
844} 898}
845 899
846struct compat_ica_rsa_modexpo_crt { 900struct compat_ica_rsa_modexpo_crt {
@@ -877,10 +931,15 @@ static long trans_modexpo_crt32(struct file *filp, unsigned int cmd,
877 do { 931 do {
878 rc = zcrypt_rsa_crt(&crt64); 932 rc = zcrypt_rsa_crt(&crt64);
879 } while (rc == -EAGAIN); 933 } while (rc == -EAGAIN);
880 if (!rc) 934 /* on failure: retry once again after a requested rescan */
881 rc = put_user(crt64.outputdatalength, 935 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
882 &ucrt32->outputdatalength); 936 do {
883 return rc; 937 rc = zcrypt_rsa_crt(&crt64);
938 } while (rc == -EAGAIN);
939 if (rc)
940 return rc;
941 return put_user(crt64.outputdatalength,
942 &ucrt32->outputdatalength);
884} 943}
885 944
886struct compat_ica_xcRB { 945struct compat_ica_xcRB {
@@ -936,6 +995,11 @@ static long trans_xcRB32(struct file *filp, unsigned int cmd,
936 do { 995 do {
937 rc = zcrypt_send_cprb(&xcRB64); 996 rc = zcrypt_send_cprb(&xcRB64);
938 } while (rc == -EAGAIN); 997 } while (rc == -EAGAIN);
998 /* on failure: retry once again after a requested rescan */
999 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
1000 do {
1001 rc = zcrypt_send_cprb(&xcRB64);
1002 } while (rc == -EAGAIN);
939 xcRB32.reply_control_blk_length = xcRB64.reply_control_blk_length; 1003 xcRB32.reply_control_blk_length = xcRB64.reply_control_blk_length;
940 xcRB32.reply_data_length = xcRB64.reply_data_length; 1004 xcRB32.reply_data_length = xcRB64.reply_data_length;
941 xcRB32.status = xcRB64.status; 1005 xcRB32.status = xcRB64.status;
@@ -1193,6 +1257,9 @@ static int zcrypt_rng_data_read(struct hwrng *rng, u32 *data)
1193 */ 1257 */
1194 if (zcrypt_rng_buffer_index == 0) { 1258 if (zcrypt_rng_buffer_index == 0) {
1195 rc = zcrypt_rng((char *) zcrypt_rng_buffer); 1259 rc = zcrypt_rng((char *) zcrypt_rng_buffer);
1260 /* on failure: retry once again after a requested rescan */
1261 if ((rc == -ENODEV) && (zcrypt_process_rescan()))
1262 rc = zcrypt_rng((char *) zcrypt_rng_buffer);
1196 if (rc < 0) 1263 if (rc < 0)
1197 return -EIO; 1264 return -EIO;
1198 zcrypt_rng_buffer_index = rc / sizeof *data; 1265 zcrypt_rng_buffer_index = rc / sizeof *data;
@@ -1245,6 +1312,30 @@ static void zcrypt_rng_device_remove(void)
1245 mutex_unlock(&zcrypt_rng_mutex); 1312 mutex_unlock(&zcrypt_rng_mutex);
1246} 1313}
1247 1314
1315int __init zcrypt_debug_init(void)
1316{
1317 debugfs_root = debugfs_create_dir("zcrypt", NULL);
1318
1319 zcrypt_dbf_common = debug_register("zcrypt_common", 1, 1, 16);
1320 debug_register_view(zcrypt_dbf_common, &debug_hex_ascii_view);
1321 debug_set_level(zcrypt_dbf_common, DBF_ERR);
1322
1323 zcrypt_dbf_devices = debug_register("zcrypt_devices", 1, 1, 16);
1324 debug_register_view(zcrypt_dbf_devices, &debug_hex_ascii_view);
1325 debug_set_level(zcrypt_dbf_devices, DBF_ERR);
1326
1327 return 0;
1328}
1329
1330void zcrypt_debug_exit(void)
1331{
1332 debugfs_remove(debugfs_root);
1333 if (zcrypt_dbf_common)
1334 debug_unregister(zcrypt_dbf_common);
1335 if (zcrypt_dbf_devices)
1336 debug_unregister(zcrypt_dbf_devices);
1337}
1338
1248/** 1339/**
1249 * zcrypt_api_init(): Module initialization. 1340 * zcrypt_api_init(): Module initialization.
1250 * 1341 *
@@ -1254,6 +1345,12 @@ int __init zcrypt_api_init(void)
1254{ 1345{
1255 int rc; 1346 int rc;
1256 1347
1348 rc = zcrypt_debug_init();
1349 if (rc)
1350 goto out;
1351
1352 atomic_set(&zcrypt_rescan_req, 0);
1353
1257 /* Register the request sprayer. */ 1354 /* Register the request sprayer. */
1258 rc = misc_register(&zcrypt_misc_device); 1355 rc = misc_register(&zcrypt_misc_device);
1259 if (rc < 0) 1356 if (rc < 0)
@@ -1283,6 +1380,7 @@ void zcrypt_api_exit(void)
1283{ 1380{
1284 remove_proc_entry("driver/z90crypt", NULL); 1381 remove_proc_entry("driver/z90crypt", NULL);
1285 misc_deregister(&zcrypt_misc_device); 1382 misc_deregister(&zcrypt_misc_device);
1383 zcrypt_debug_exit();
1286} 1384}
1287 1385
1288module_init(zcrypt_api_init); 1386module_init(zcrypt_api_init);