Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  *  Copyright IBM Corp. 2001, 2012
0004  *  Author(s): Robert Burroughs
0005  *         Eric Rossman (edrossma@us.ibm.com)
0006  *         Cornelia Huck <cornelia.huck@de.ibm.com>
0007  *
0008  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
0009  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
0010  *                Ralph Wuerthner <rwuerthn@de.ibm.com>
0011  *  MSGTYPE restruct:         Holger Dengler <hd@linux.vnet.ibm.com>
0012  */
0013 
0014 #include <linux/module.h>
0015 #include <linux/init.h>
0016 #include <linux/interrupt.h>
0017 #include <linux/miscdevice.h>
0018 #include <linux/fs.h>
0019 #include <linux/proc_fs.h>
0020 #include <linux/seq_file.h>
0021 #include <linux/compat.h>
0022 #include <linux/slab.h>
0023 #include <linux/atomic.h>
0024 #include <linux/uaccess.h>
0025 #include <linux/hw_random.h>
0026 #include <linux/debugfs.h>
0027 #include <asm/debug.h>
0028 
0029 #include "zcrypt_debug.h"
0030 #include "zcrypt_api.h"
0031 
0032 #include "zcrypt_msgtype6.h"
0033 #include "zcrypt_msgtype50.h"
0034 
0035 /*
0036  * Device attributes common for all crypto queue devices.
0037  */
0038 
0039 static ssize_t online_show(struct device *dev,
0040                struct device_attribute *attr,
0041                char *buf)
0042 {
0043     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0044     struct ap_queue *aq = to_ap_queue(dev);
0045     int online = aq->config && zq->online ? 1 : 0;
0046 
0047     return scnprintf(buf, PAGE_SIZE, "%d\n", online);
0048 }
0049 
0050 static ssize_t online_store(struct device *dev,
0051                 struct device_attribute *attr,
0052                 const char *buf, size_t count)
0053 {
0054     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0055     struct ap_queue *aq = to_ap_queue(dev);
0056     struct zcrypt_card *zc = zq->zcard;
0057     int online;
0058 
0059     if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
0060         return -EINVAL;
0061 
0062     if (online && (!aq->config || !aq->card->config))
0063         return -ENODEV;
0064     if (online && !zc->online)
0065         return -EINVAL;
0066     zq->online = online;
0067 
0068     ZCRYPT_DBF_INFO("%s queue=%02x.%04x online=%d\n",
0069             __func__, AP_QID_CARD(zq->queue->qid),
0070             AP_QID_QUEUE(zq->queue->qid), online);
0071 
0072     ap_send_online_uevent(&aq->ap_dev, online);
0073 
0074     if (!online)
0075         ap_flush_queue(zq->queue);
0076     return count;
0077 }
0078 
0079 static DEVICE_ATTR_RW(online);
0080 
0081 static ssize_t load_show(struct device *dev,
0082              struct device_attribute *attr,
0083              char *buf)
0084 {
0085     struct zcrypt_queue *zq = dev_get_drvdata(dev);
0086 
0087     return scnprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&zq->load));
0088 }
0089 
0090 static DEVICE_ATTR_RO(load);
0091 
0092 static struct attribute *zcrypt_queue_attrs[] = {
0093     &dev_attr_online.attr,
0094     &dev_attr_load.attr,
0095     NULL,
0096 };
0097 
0098 static const struct attribute_group zcrypt_queue_attr_group = {
0099     .attrs = zcrypt_queue_attrs,
0100 };
0101 
0102 bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online)
0103 {
0104     if (!!zq->online != !!online) {
0105         zq->online = online;
0106         if (!online)
0107             ap_flush_queue(zq->queue);
0108         return true;
0109     }
0110     return false;
0111 }
0112 
0113 struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size)
0114 {
0115     struct zcrypt_queue *zq;
0116 
0117     zq = kzalloc(sizeof(*zq), GFP_KERNEL);
0118     if (!zq)
0119         return NULL;
0120     zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL);
0121     if (!zq->reply.msg)
0122         goto out_free;
0123     zq->reply.bufsize = reply_buf_size;
0124     INIT_LIST_HEAD(&zq->list);
0125     kref_init(&zq->refcount);
0126     return zq;
0127 
0128 out_free:
0129     kfree(zq);
0130     return NULL;
0131 }
0132 EXPORT_SYMBOL(zcrypt_queue_alloc);
0133 
0134 void zcrypt_queue_free(struct zcrypt_queue *zq)
0135 {
0136     kfree(zq->reply.msg);
0137     kfree(zq);
0138 }
0139 EXPORT_SYMBOL(zcrypt_queue_free);
0140 
0141 static void zcrypt_queue_release(struct kref *kref)
0142 {
0143     struct zcrypt_queue *zq =
0144         container_of(kref, struct zcrypt_queue, refcount);
0145     zcrypt_queue_free(zq);
0146 }
0147 
0148 void zcrypt_queue_get(struct zcrypt_queue *zq)
0149 {
0150     kref_get(&zq->refcount);
0151 }
0152 EXPORT_SYMBOL(zcrypt_queue_get);
0153 
0154 int zcrypt_queue_put(struct zcrypt_queue *zq)
0155 {
0156     return kref_put(&zq->refcount, zcrypt_queue_release);
0157 }
0158 EXPORT_SYMBOL(zcrypt_queue_put);
0159 
0160 /**
0161  * zcrypt_queue_register() - Register a crypto queue device.
0162  * @zq: Pointer to a crypto queue device
0163  *
0164  * Register a crypto queue device. Returns 0 if successful.
0165  */
0166 int zcrypt_queue_register(struct zcrypt_queue *zq)
0167 {
0168     struct zcrypt_card *zc;
0169     int rc;
0170 
0171     spin_lock(&zcrypt_list_lock);
0172     zc = dev_get_drvdata(&zq->queue->card->ap_dev.device);
0173     zcrypt_card_get(zc);
0174     zq->zcard = zc;
0175     zq->online = 1; /* New devices are online by default. */
0176 
0177     ZCRYPT_DBF_INFO("%s queue=%02x.%04x register online=1\n",
0178             __func__, AP_QID_CARD(zq->queue->qid),
0179             AP_QID_QUEUE(zq->queue->qid));
0180 
0181     list_add_tail(&zq->list, &zc->zqueues);
0182     spin_unlock(&zcrypt_list_lock);
0183 
0184     rc = sysfs_create_group(&zq->queue->ap_dev.device.kobj,
0185                 &zcrypt_queue_attr_group);
0186     if (rc)
0187         goto out;
0188 
0189     if (zq->ops->rng) {
0190         rc = zcrypt_rng_device_add();
0191         if (rc)
0192             goto out_unregister;
0193     }
0194     return 0;
0195 
0196 out_unregister:
0197     sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
0198                &zcrypt_queue_attr_group);
0199 out:
0200     spin_lock(&zcrypt_list_lock);
0201     list_del_init(&zq->list);
0202     spin_unlock(&zcrypt_list_lock);
0203     zcrypt_card_put(zc);
0204     return rc;
0205 }
0206 EXPORT_SYMBOL(zcrypt_queue_register);
0207 
0208 /**
0209  * zcrypt_queue_unregister(): Unregister a crypto queue device.
0210  * @zq: Pointer to crypto queue device
0211  *
0212  * Unregister a crypto queue device.
0213  */
0214 void zcrypt_queue_unregister(struct zcrypt_queue *zq)
0215 {
0216     struct zcrypt_card *zc;
0217 
0218     ZCRYPT_DBF_INFO("%s queue=%02x.%04x unregister\n",
0219             __func__, AP_QID_CARD(zq->queue->qid),
0220             AP_QID_QUEUE(zq->queue->qid));
0221 
0222     zc = zq->zcard;
0223     spin_lock(&zcrypt_list_lock);
0224     list_del_init(&zq->list);
0225     spin_unlock(&zcrypt_list_lock);
0226     if (zq->ops->rng)
0227         zcrypt_rng_device_remove();
0228     sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
0229                &zcrypt_queue_attr_group);
0230     zcrypt_card_put(zc);
0231     zcrypt_queue_put(zq);
0232 }
0233 EXPORT_SYMBOL(zcrypt_queue_unregister);