summaryrefslogtreecommitdiffstats
path: root/drivers/s390/crypto/zcrypt_card.c
diff options
context:
space:
mode:
authorHarald Freudenberger <freude@linux.ibm.com>2021-04-13 18:11:09 +0200
committerVasily Gorbik <gor@linux.ibm.com>2021-06-16 23:46:18 +0200
commitdf6f508c68dbc65def0098cbdf8de7683ae551d2 (patch)
treed1cbc60422c08f5e9d01bdbacd0a5f7cf36d64d1 /drivers/s390/crypto/zcrypt_card.c
parents390/decompressor: replace use of perl with simple sed/tr (diff)
downloadlinux-df6f508c68dbc65def0098cbdf8de7683ae551d2.tar.xz
linux-df6f508c68dbc65def0098cbdf8de7683ae551d2.zip
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>
Diffstat (limited to 'drivers/s390/crypto/zcrypt_card.c')
-rw-r--r--drivers/s390/crypto/zcrypt_card.c30
1 files changed, 28 insertions, 2 deletions
diff --git a/drivers/s390/crypto/zcrypt_card.c b/drivers/s390/crypto/zcrypt_card.c
index 09fe6bb8880b..40fd5d37d26a 100644
--- a/drivers/s390/crypto/zcrypt_card.c
+++ b/drivers/s390/crypto/zcrypt_card.c
@@ -64,7 +64,8 @@ static ssize_t online_store(struct device *dev,
struct ap_card *ac = to_ap_card(dev);
struct zcrypt_card *zc = ac->private;
struct zcrypt_queue *zq;
- int online, id;
+ int online, id, i = 0, maxzqs = 0;
+ struct zcrypt_queue **zq_uelist = NULL;
if (sscanf(buf, "%d\n", &online) != 1 || online < 0 || online > 1)
return -EINVAL;
@@ -77,10 +78,35 @@ static ssize_t online_store(struct device *dev,
ZCRYPT_DBF(DBF_INFO, "card=%02x online=%d\n", id, online);
+ ap_send_online_uevent(&ac->ap_dev, online);
+
spin_lock(&zcrypt_list_lock);
+ /*
+ * As we are in atomic context here, directly sending uevents
+ * does not work. So collect the zqueues in a dynamic array
+ * and process them after zcrypt_list_lock release. As we get/put
+ * the zqueue objects, we make sure they exist after lock release.
+ */
+ list_for_each_entry(zq, &zc->zqueues, list)
+ maxzqs++;
+ if (maxzqs > 0)
+ zq_uelist = kcalloc(maxzqs + 1, sizeof(zq), GFP_ATOMIC);
list_for_each_entry(zq, &zc->zqueues, list)
- zcrypt_queue_force_online(zq, online);
+ if (zcrypt_queue_force_online(zq, online))
+ if (zq_uelist) {
+ zcrypt_queue_get(zq);
+ zq_uelist[i++] = zq;
+ }
spin_unlock(&zcrypt_list_lock);
+ if (zq_uelist) {
+ for (i = 0; zq_uelist[i]; i++) {
+ zq = zq_uelist[i];
+ ap_send_online_uevent(&zq->queue->ap_dev, online);
+ zcrypt_queue_put(zq);
+ }
+ kfree(zq_uelist);
+ }
+
return count;
}