linux/drivers/s390/crypto/zcrypt_queue.c

235 lines
5.4 KiB
C
Raw Permalink Normal View History

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright IBM Corp. 2001, 2012
* Author(s): Robert Burroughs
* Eric Rossman (edrossma@us.ibm.com)
* Cornelia Huck <cornelia.huck@de.ibm.com>
*
* Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
* Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
* Ralph Wuerthner <rwuerthn@de.ibm.com>
* MSGTYPE restruct: Holger Dengler <hd@linux.vnet.ibm.com>
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/compat.h>
#include <linux/slab.h>
#include <linux/atomic.h>
#include <linux/uaccess.h>
#include <linux/hw_random.h>
#include <linux/debugfs.h>
#include <asm/debug.h>
#include "zcrypt_debug.h"
#include "zcrypt_api.h"
#include "zcrypt_msgtype6.h"
#include "zcrypt_msgtype50.h"
/*
* Device attributes common for all crypto queue devices.
*/
static ssize_t online_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct zcrypt_queue *zq = dev_get_drvdata(dev);
struct ap_queue *aq = to_ap_queue(dev);
int online = aq->config && !aq->chkstop && zq->online ? 1 : 0;
return sysfs_emit(buf, "%d\n", online);
}
static ssize_t online_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct zcrypt_queue *zq = dev_get_drvdata(dev);
struct ap_queue *aq = to_ap_queue(dev);
struct zcrypt_card *zc = zq->zcard;
int online;
if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
return -EINVAL;
if (online && (!aq->config || !aq->card->config ||
aq->chkstop || aq->card->chkstop))
return -ENODEV;
if (online && !zc->online)
return -EINVAL;
zq->online = online;
ZCRYPT_DBF_INFO("%s queue=%02x.%04x online=%d\n",
__func__, AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid), online);
s390/ap/zcrypt: notify userspace with online, config and mode info This patch brings 3 reworked/new uevent changes: * All AP uevents caused by an ap card or queue device now carry an additional uevent env value MODE=<accel|cca|ep11>. Here is an example: KERNEL[1267.301292] add /devices/ap/card0a (ap) ACTION=add DEVPATH=/devices/ap/card0a SUBSYSTEM=ap DEVTYPE=ap_card DEV_TYPE=000D MODALIAS=ap:t0D MODE=ep11 <- this is new SEQNUM=1095 This is true for bind, unbind, add, remove, and change uevents related to ap card or ap queue devices. * On a change of the soft online attribute on a zcrypt queue or card device a new CHANGE uevent is sent with an env value ONLINE=<0|1>. Example uevent: KERNEL[613.067531] change /devices/ap/card09/09.0011 (ap) ACTION=change DEVPATH=/devices/ap/card09/09.0011 SUBSYSTEM=ap ONLINE=0 <- this is new DEVTYPE=ap_queue DRIVER=cex4queue MODE=cca SEQNUM=1070 - On a change of the config state of an zcrypt card device a new CHANGE uevent is sent with an env value CONFIG=<0|1>. Example uevent: KERNEL[876.258680] change /devices/ap/card09 (ap) ACTION=change DEVPATH=/devices/ap/card09 SUBSYSTEM=ap CONFIG=0 <- this is new DEVTYPE=ap_card DRIVER=cex4card DEV_TYPE=000D MODALIAS=ap:t0D MODE=cca SEQNUM=1073 Setting a card config on/off causes the dependent queue devices to follow the config state change and thus uevents informing about the config state change for the queue devices are also emitted. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-04-13 16:11:09 +00:00
ap_send_online_uevent(&aq->ap_dev, online);
if (!online)
ap_flush_queue(zq->queue);
return count;
}
static DEVICE_ATTR_RW(online);
static ssize_t load_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct zcrypt_queue *zq = dev_get_drvdata(dev);
return sysfs_emit(buf, "%d\n", atomic_read(&zq->load));
}
static DEVICE_ATTR_RO(load);
static struct attribute *zcrypt_queue_attrs[] = {
&dev_attr_online.attr,
&dev_attr_load.attr,
NULL,
};
static const struct attribute_group zcrypt_queue_attr_group = {
.attrs = zcrypt_queue_attrs,
};
s390/ap/zcrypt: notify userspace with online, config and mode info This patch brings 3 reworked/new uevent changes: * All AP uevents caused by an ap card or queue device now carry an additional uevent env value MODE=<accel|cca|ep11>. Here is an example: KERNEL[1267.301292] add /devices/ap/card0a (ap) ACTION=add DEVPATH=/devices/ap/card0a SUBSYSTEM=ap DEVTYPE=ap_card DEV_TYPE=000D MODALIAS=ap:t0D MODE=ep11 <- this is new SEQNUM=1095 This is true for bind, unbind, add, remove, and change uevents related to ap card or ap queue devices. * On a change of the soft online attribute on a zcrypt queue or card device a new CHANGE uevent is sent with an env value ONLINE=<0|1>. Example uevent: KERNEL[613.067531] change /devices/ap/card09/09.0011 (ap) ACTION=change DEVPATH=/devices/ap/card09/09.0011 SUBSYSTEM=ap ONLINE=0 <- this is new DEVTYPE=ap_queue DRIVER=cex4queue MODE=cca SEQNUM=1070 - On a change of the config state of an zcrypt card device a new CHANGE uevent is sent with an env value CONFIG=<0|1>. Example uevent: KERNEL[876.258680] change /devices/ap/card09 (ap) ACTION=change DEVPATH=/devices/ap/card09 SUBSYSTEM=ap CONFIG=0 <- this is new DEVTYPE=ap_card DRIVER=cex4card DEV_TYPE=000D MODALIAS=ap:t0D MODE=cca SEQNUM=1073 Setting a card config on/off causes the dependent queue devices to follow the config state change and thus uevents informing about the config state change for the queue devices are also emitted. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-04-13 16:11:09 +00:00
bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online)
{
s390/ap/zcrypt: notify userspace with online, config and mode info This patch brings 3 reworked/new uevent changes: * All AP uevents caused by an ap card or queue device now carry an additional uevent env value MODE=<accel|cca|ep11>. Here is an example: KERNEL[1267.301292] add /devices/ap/card0a (ap) ACTION=add DEVPATH=/devices/ap/card0a SUBSYSTEM=ap DEVTYPE=ap_card DEV_TYPE=000D MODALIAS=ap:t0D MODE=ep11 <- this is new SEQNUM=1095 This is true for bind, unbind, add, remove, and change uevents related to ap card or ap queue devices. * On a change of the soft online attribute on a zcrypt queue or card device a new CHANGE uevent is sent with an env value ONLINE=<0|1>. Example uevent: KERNEL[613.067531] change /devices/ap/card09/09.0011 (ap) ACTION=change DEVPATH=/devices/ap/card09/09.0011 SUBSYSTEM=ap ONLINE=0 <- this is new DEVTYPE=ap_queue DRIVER=cex4queue MODE=cca SEQNUM=1070 - On a change of the config state of an zcrypt card device a new CHANGE uevent is sent with an env value CONFIG=<0|1>. Example uevent: KERNEL[876.258680] change /devices/ap/card09 (ap) ACTION=change DEVPATH=/devices/ap/card09 SUBSYSTEM=ap CONFIG=0 <- this is new DEVTYPE=ap_card DRIVER=cex4card DEV_TYPE=000D MODALIAS=ap:t0D MODE=cca SEQNUM=1073 Setting a card config on/off causes the dependent queue devices to follow the config state change and thus uevents informing about the config state change for the queue devices are also emitted. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-04-13 16:11:09 +00:00
if (!!zq->online != !!online) {
zq->online = online;
if (!online)
ap_flush_queue(zq->queue);
return true;
}
return false;
}
s390/AP: support new dynamic AP bus size limit This patch provides support for new dynamic AP bus message limit with the existing zcrypt device driver and AP bus core code. There is support for a new field 'ml' from TAPQ query. The field gives if != 0 the AP bus limit for this card in 4k chunk units. The actual message size limit per card is shown as a new read-only sysfs attribute. The sysfs attribute /sys/devices/ap/cardxx/max_msg_size shows the upper limit in bytes used by the AP bus and zcrypt device driver for requests and replies send to and received from this card. Currently up to CEX7 support only max 12kB msg size and thus the field shows 12288 meaning the upper limit of a valid msg for this card is 12kB. Please note that the usable payload is somewhat lower and depends on the msg type and thus the header struct which is to be prepended by the zcrypt dd. The dispatcher responsible for choosing the right card and queue is aware of the individual card AP bus message limit. So a request is only assigned to a queue of a card which is able to handle the size of the request (e.g. a 14kB request will never go to a max 12kB card). If no such card is found the ioctl will fail with ENODEV. The reply buffer held by the device driver is determined by the ml field of the TAPQ for this card. If a response from the card exceeds this limit however, the response is not truncated but the ioctl for this request will fail with errno EMSGSIZE to indicate that the device driver has dropped the response because it would overflow the buffer limit. If the request size does not indicate to the dispatcher that an adapter with extended limit is to be used, a random card will be chosen when no specific card is addressed (ANY addressing). This may result in an ioctl failure when the reply size needs an adapter with extended limit but the randomly chosen one is not capable of handling the broader reply size. The user space application needs to use dedicated addressing to forward such a request only to suitable cards to get requests like this processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-06-25 10:29:46 +00:00
struct zcrypt_queue *zcrypt_queue_alloc(size_t reply_buf_size)
{
struct zcrypt_queue *zq;
zq = kzalloc(sizeof(*zq), GFP_KERNEL);
if (!zq)
return NULL;
s390/AP: support new dynamic AP bus size limit This patch provides support for new dynamic AP bus message limit with the existing zcrypt device driver and AP bus core code. There is support for a new field 'ml' from TAPQ query. The field gives if != 0 the AP bus limit for this card in 4k chunk units. The actual message size limit per card is shown as a new read-only sysfs attribute. The sysfs attribute /sys/devices/ap/cardxx/max_msg_size shows the upper limit in bytes used by the AP bus and zcrypt device driver for requests and replies send to and received from this card. Currently up to CEX7 support only max 12kB msg size and thus the field shows 12288 meaning the upper limit of a valid msg for this card is 12kB. Please note that the usable payload is somewhat lower and depends on the msg type and thus the header struct which is to be prepended by the zcrypt dd. The dispatcher responsible for choosing the right card and queue is aware of the individual card AP bus message limit. So a request is only assigned to a queue of a card which is able to handle the size of the request (e.g. a 14kB request will never go to a max 12kB card). If no such card is found the ioctl will fail with ENODEV. The reply buffer held by the device driver is determined by the ml field of the TAPQ for this card. If a response from the card exceeds this limit however, the response is not truncated but the ioctl for this request will fail with errno EMSGSIZE to indicate that the device driver has dropped the response because it would overflow the buffer limit. If the request size does not indicate to the dispatcher that an adapter with extended limit is to be used, a random card will be chosen when no specific card is addressed (ANY addressing). This may result in an ioctl failure when the reply size needs an adapter with extended limit but the randomly chosen one is not capable of handling the broader reply size. The user space application needs to use dedicated addressing to forward such a request only to suitable cards to get requests like this processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-06-25 10:29:46 +00:00
zq->reply.msg = kmalloc(reply_buf_size, GFP_KERNEL);
if (!zq->reply.msg)
goto out_free;
s390/AP: support new dynamic AP bus size limit This patch provides support for new dynamic AP bus message limit with the existing zcrypt device driver and AP bus core code. There is support for a new field 'ml' from TAPQ query. The field gives if != 0 the AP bus limit for this card in 4k chunk units. The actual message size limit per card is shown as a new read-only sysfs attribute. The sysfs attribute /sys/devices/ap/cardxx/max_msg_size shows the upper limit in bytes used by the AP bus and zcrypt device driver for requests and replies send to and received from this card. Currently up to CEX7 support only max 12kB msg size and thus the field shows 12288 meaning the upper limit of a valid msg for this card is 12kB. Please note that the usable payload is somewhat lower and depends on the msg type and thus the header struct which is to be prepended by the zcrypt dd. The dispatcher responsible for choosing the right card and queue is aware of the individual card AP bus message limit. So a request is only assigned to a queue of a card which is able to handle the size of the request (e.g. a 14kB request will never go to a max 12kB card). If no such card is found the ioctl will fail with ENODEV. The reply buffer held by the device driver is determined by the ml field of the TAPQ for this card. If a response from the card exceeds this limit however, the response is not truncated but the ioctl for this request will fail with errno EMSGSIZE to indicate that the device driver has dropped the response because it would overflow the buffer limit. If the request size does not indicate to the dispatcher that an adapter with extended limit is to be used, a random card will be chosen when no specific card is addressed (ANY addressing). This may result in an ioctl failure when the reply size needs an adapter with extended limit but the randomly chosen one is not capable of handling the broader reply size. The user space application needs to use dedicated addressing to forward such a request only to suitable cards to get requests like this processed properly. Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Reviewed-by: Ingo Tuchscherer <ingo.tuchscherer@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2021-06-25 10:29:46 +00:00
zq->reply.bufsize = reply_buf_size;
INIT_LIST_HEAD(&zq->list);
kref_init(&zq->refcount);
return zq;
out_free:
kfree(zq);
return NULL;
}
EXPORT_SYMBOL(zcrypt_queue_alloc);
void zcrypt_queue_free(struct zcrypt_queue *zq)
{
kfree(zq->reply.msg);
kfree(zq);
}
EXPORT_SYMBOL(zcrypt_queue_free);
static void zcrypt_queue_release(struct kref *kref)
{
struct zcrypt_queue *zq =
container_of(kref, struct zcrypt_queue, refcount);
zcrypt_queue_free(zq);
}
void zcrypt_queue_get(struct zcrypt_queue *zq)
{
kref_get(&zq->refcount);
}
EXPORT_SYMBOL(zcrypt_queue_get);
int zcrypt_queue_put(struct zcrypt_queue *zq)
{
return kref_put(&zq->refcount, zcrypt_queue_release);
}
EXPORT_SYMBOL(zcrypt_queue_put);
/**
* zcrypt_queue_register() - Register a crypto queue device.
* @zq: Pointer to a crypto queue device
*
* Register a crypto queue device. Returns 0 if successful.
*/
int zcrypt_queue_register(struct zcrypt_queue *zq)
{
struct zcrypt_card *zc;
int rc;
spin_lock(&zcrypt_list_lock);
zc = dev_get_drvdata(&zq->queue->card->ap_dev.device);
zcrypt_card_get(zc);
zq->zcard = zc;
zq->online = 1; /* New devices are online by default. */
ZCRYPT_DBF_INFO("%s queue=%02x.%04x register online=1\n",
__func__, AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
list_add_tail(&zq->list, &zc->zqueues);
spin_unlock(&zcrypt_list_lock);
rc = sysfs_create_group(&zq->queue->ap_dev.device.kobj,
&zcrypt_queue_attr_group);
if (rc)
goto out;
if (zq->ops->rng) {
rc = zcrypt_rng_device_add();
if (rc)
goto out_unregister;
}
return 0;
out_unregister:
sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
&zcrypt_queue_attr_group);
out:
spin_lock(&zcrypt_list_lock);
list_del_init(&zq->list);
spin_unlock(&zcrypt_list_lock);
zcrypt_card_put(zc);
return rc;
}
EXPORT_SYMBOL(zcrypt_queue_register);
/**
* zcrypt_queue_unregister(): Unregister a crypto queue device.
* @zq: Pointer to crypto queue device
*
* Unregister a crypto queue device.
*/
void zcrypt_queue_unregister(struct zcrypt_queue *zq)
{
struct zcrypt_card *zc;
ZCRYPT_DBF_INFO("%s queue=%02x.%04x unregister\n",
__func__, AP_QID_CARD(zq->queue->qid),
AP_QID_QUEUE(zq->queue->qid));
zc = zq->zcard;
spin_lock(&zcrypt_list_lock);
list_del_init(&zq->list);
spin_unlock(&zcrypt_list_lock);
if (zq->ops->rng)
zcrypt_rng_device_remove();
sysfs_remove_group(&zq->queue->ap_dev.device.kobj,
&zcrypt_queue_attr_group);
s390/ap: fix ap devices reference counting With the last rework of the AP bus scan function one get_device() is missing causing the reference counter to be one instance too low. Together with binding/unbinding device drivers to an ap device it may end up in an segfault because the ap device is freed but a device driver still assumes it's pointer to the ap device is valid: Unable to handle kernel pointer dereference in virtual kernel address space Failing address: 6b6b6b6b6b6b6000 TEID: 6b6b6b6b6b6b6803 Fault in home space mode while using kernel ASCE. Krnl PSW : 0404e00180000000 000000001472f3b6 (klist_next+0x7e/0x180) R:0 T:1 IO:0 EX:0 Key:0 M:1 W:0 P:0 AS:3 CC:2 PM:0 RI:0 EA:3 Call Trace: [<000000001472f3b6>] klist_next+0x7e/0x180 ([<000000001472f36a>] klist_next+0x32/0x180) [<00000000147c14de>] bus_for_each_dev+0x66/0xb8 [<0000000014aab0d4>] ap_scan_adapter+0xcc/0x6c0 [<0000000014aab74a>] ap_scan_bus+0x82/0x140 [<0000000013f3b654>] process_one_work+0x27c/0x478 [<0000000013f3b8b6>] worker_thread+0x66/0x368 [<0000000013f44e32>] kthread+0x17a/0x1a0 [<0000000014af23e4>] ret_from_fork+0x24/0x2c Kernel panic - not syncing: Fatal exception: panic_on_oops Fixed by adjusting the reference count with get_device() on the right place. Also now the device drivers don't need to adjust the ap device's reference counting any more. This is now done in the ap bus probe and remove functions. Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com> Fixes: 4f2fcccdb547 ("s390/ap: add card/queue deconfig state") Signed-off-by: Harald Freudenberger <freude@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
2020-10-20 10:20:30 +00:00
zcrypt_card_put(zc);
zcrypt_queue_put(zq);
}
EXPORT_SYMBOL(zcrypt_queue_unregister);