1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright IBM Corp. 2001, 2012 4 * Author(s): Robert Burroughs 5 * Eric Rossman (edrossma@us.ibm.com) 6 * Cornelia Huck <cornelia.huck@de.ibm.com> 7 * 8 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) 9 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com> 10 * Ralph Wuerthner <rwuerthn@de.ibm.com> 11 * MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com> 12 */ 13 14 #include <linux/export.h> 15 #include <linux/module.h> 16 #include <linux/init.h> 17 #include <linux/interrupt.h> 18 #include <linux/miscdevice.h> 19 #include <linux/fs.h> 20 #include <linux/proc_fs.h> 21 #include <linux/seq_file.h> 22 #include <linux/compat.h> 23 #include <linux/slab.h> 24 #include <linux/atomic.h> 25 #include <linux/uaccess.h> 26 #include <linux/hw_random.h> 27 #include <linux/debugfs.h> 28 #include <asm/debug.h> 29 30 #include "zcrypt_debug.h" 31 #include "zcrypt_api.h" 32 33 #include "zcrypt_msgtype6.h" 34 #include "zcrypt_msgtype50.h" 35 36 /* 37 * Device attributes common for all crypto queue devices. 38 */ 39 40 static ssize_t online_show(struct device *dev, 41 struct device_attribute *attr, 42 char *buf) 43 { 44 struct zcrypt_queue *zq = dev_get_drvdata(dev); 45 struct ap_queue *aq = to_ap_queue(dev); 46 int online = aq->config && !aq->chkstop && zq->online ? 1 : 0; 47 48 return sysfs_emit(buf, "%d\n", online); 49 } 50 51 static ssize_t online_store(struct device *dev, 52 struct device_attribute *attr, 53 const char *buf, size_t count) 54 { 55 struct zcrypt_queue *zq = dev_get_drvdata(dev); 56 struct ap_queue *aq = to_ap_queue(dev); 57 struct zcrypt_card *zc = zq->zcard; 58 int online; 59 60 if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1) 61 return -EINVAL; 62 63 if (online && (!aq->config || !aq->card->config || 64 aq->chkstop || aq->card->chkstop)) 65 return -ENODEV; 66 if (online && !zc->online) 67 return -EINVAL; 68 zq->online = online; 69 70 ZCRYPT_DBF_INFO("%s queue=%02x.%04x online=%d\n", 71 __func__, AP_QID_CARD(zq->queue->qid), 72 AP_QID_QUEUE(zq->queue->qid), online); 73 74 ap_send_online_uevent(&aq->ap_dev, online); 75 76 if (!online) 77 ap_flush_queue(zq->queue); 78 return count; 79 } 80 81 static DEVICE_ATTR_RW(online); 82 83 static ssize_t load_show(struct device *dev, 84 struct device_attribute *attr, 85 char *buf) 86 { 87 struct zcrypt_queue *zq = dev_get_drvdata(dev); 88 89 return sysfs_emit(buf, "%d\n", atomic_read(&zq->load)); 90 } 91 92 static DEVICE_ATTR_RO(load); 93 94 static struct attribute *zcrypt_queue_attrs[] = { 95 &dev_attr_online.attr, 96 &dev_attr_load.attr, 97 NULL, 98 }; 99 100 static const struct attribute_group zcrypt_queue_attr_group = { 101 .attrs = zcrypt_queue_attrs, 102 }; 103 104 bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online) 105 { 106 if (!!zq->online != !!online) { 107 zq->online = online; 108 if (!online) 109 ap_flush_queue(zq->queue); 110 return true; 111 } 112 return false; 113 } 114 115 struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size) 116 { 117 struct zcrypt_queue *zq; 118 119 zq = kzalloc(sizeof(*zq), GFP_KERNEL); 120 if (!zq) 121 return NULL; 122 zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL); 123 if (!zq->reply.msg) 124 goto out_free; 125 zq->reply.bufsize = reply_buf_size; 126 INIT_LIST_HEAD(&zq->list); 127 kref_init(&zq->refcount); 128 return zq; 129 130 out_free: 131 kfree(zq); 132 return NULL; 133 } 134 EXPORT_SYMBOL(zcrypt_queue_alloc); 135 136 void zcrypt_queue_free(struct zcrypt_queue *zq) 137 { 138 kfree(zq->reply.msg); 139 kfree(zq); 140 } 141 EXPORT_SYMBOL(zcrypt_queue_free); 142 143 static void zcrypt_queue_release(struct kref *kref) 144 { 145 struct zcrypt_queue *zq = 146 container_of(kref, struct zcrypt_queue, refcount); 147 zcrypt_queue_free(zq); 148 } 149 150 void zcrypt_queue_get(struct zcrypt_queue *zq) 151 { 152 kref_get(&zq->refcount); 153 } 154 EXPORT_SYMBOL(zcrypt_queue_get); 155 156 int zcrypt_queue_put(struct zcrypt_queue *zq) 157 { 158 return kref_put(&zq->refcount, zcrypt_queue_release); 159 } 160 EXPORT_SYMBOL(zcrypt_queue_put); 161 162 /** 163 * zcrypt_queue_register() - Register a crypto queue device. 164 * @zq: Pointer to a crypto queue device 165 * 166 * Register a crypto queue device. Returns 0 if successful. 167 */ 168 int zcrypt_queue_register(struct zcrypt_queue *zq) 169 { 170 struct zcrypt_card *zc; 171 int rc; 172 173 spin_lock(&zcrypt_list_lock); 174 zc = dev_get_drvdata(&zq->queue->card->ap_dev.device); 175 zcrypt_card_get(zc); 176 zq->zcard = zc; 177 zq->online = 1; /* New devices are online by default. */ 178 179 ZCRYPT_DBF_INFO("%s queue=%02x.%04x register online=1\n", 180 __func__, AP_QID_CARD(zq->queue->qid), 181 AP_QID_QUEUE(zq->queue->qid)); 182 183 list_add_tail(&zq->list, &zc->zqueues); 184 spin_unlock(&zcrypt_list_lock); 185 186 rc = sysfs_create_group(&zq->queue->ap_dev.device.kobj, 187 &zcrypt_queue_attr_group); 188 if (rc) 189 goto out; 190 191 if (zq->ops->rng) { 192 rc = zcrypt_rng_device_add(); 193 if (rc) 194 goto out_unregister; 195 } 196 return 0; 197 198 out_unregister: 199 sysfs_remove_group(&zq->queue->ap_dev.device.kobj, 200 &zcrypt_queue_attr_group); 201 out: 202 spin_lock(&zcrypt_list_lock); 203 list_del_init(&zq->list); 204 spin_unlock(&zcrypt_list_lock); 205 zcrypt_card_put(zc); 206 return rc; 207 } 208 EXPORT_SYMBOL(zcrypt_queue_register); 209 210 /** 211 * zcrypt_queue_unregister(): Unregister a crypto queue device. 212 * @zq: Pointer to crypto queue device 213 * 214 * Unregister a crypto queue device. 215 */ 216 void zcrypt_queue_unregister(struct zcrypt_queue *zq) 217 { 218 struct zcrypt_card *zc; 219 220 ZCRYPT_DBF_INFO("%s queue=%02x.%04x unregister\n", 221 __func__, AP_QID_CARD(zq->queue->qid), 222 AP_QID_QUEUE(zq->queue->qid)); 223 224 zc = zq->zcard; 225 spin_lock(&zcrypt_list_lock); 226 list_del_init(&zq->list); 227 spin_unlock(&zcrypt_list_lock); 228 if (zq->ops->rng) 229 zcrypt_rng_device_remove(); 230 sysfs_remove_group(&zq->queue->ap_dev.device.kobj, 231 &zcrypt_queue_attr_group); 232 zcrypt_card_put(zc); 233 zcrypt_queue_put(zq); 234 } 235 EXPORT_SYMBOL(zcrypt_queue_unregister); 236