From patchwork Mon Aug 16 13:27:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Frank Heimes X-Patchwork-Id: 1517186 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=JQv8puyQ; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GpFMj6m4mz9tD4; Mon, 16 Aug 2021 23:27:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1mFceU-0002Mf-2f; Mon, 16 Aug 2021 13:27:42 +0000 Received: from smtp-relay-canonical-1.internal ([10.131.114.174] helo=smtp-relay-canonical-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1mFceI-0002LR-Ti for kernel-team@lists.ubuntu.com; Mon, 16 Aug 2021 13:27:30 +0000 Received: from T570.fritz.box (p54abbd2e.dip0.t-ipconnect.de [84.171.189.46]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-canonical-1.canonical.com (Postfix) with ESMTPSA id 197E53F22F for ; Mon, 16 Aug 2021 13:27:30 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1629120450; bh=/2yDc5WSIBg59kWkcDazDR3cBrAmEVJMLqEMM525lPk=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=JQv8puyQon71D5o5S41a+gjD6/qiFSQVJN2dMzQMXt25It0hVMPBI4jFX48L1Eww2 Y7ioLU8FjG7CT2ao8T4FqUe5G3zKnIAO0ARj5vABm2moG2HAIoyGl7FhvkfBuwZo62 Gf3X85qwtn1Sb5LtE9plycYJLsN2m2xRQJO9vgOKZVqmoHwO/0knrhQcCJB4mduvWR r9XaX40x8pQ/egvW5Ghfb+buqe/ToWlzX7EI3UXA7ajznSNzHs9vlyPdI2KdCxDk3e 4bJRACcDTVXVAriGi4B4mnfs1lGyvOK+vgny0HbVDDYifndbgHbtF0P3Ve4NkmCho5 j1mJxr1A0eGKw== From: frank.heimes@canonical.com To: kernel-team@lists.ubuntu.com Subject: [I][PATCH 1/1] s390/ap/zcrypt: notify userspace with online, config and mode info Date: Mon, 16 Aug 2021 15:27:25 +0200 Message-Id: <20210816132725.31748-2-frank.heimes@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210816132725.31748-1-frank.heimes@canonical.com> References: <20210816132725.31748-1-frank.heimes@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Harald Freudenberger BugLink: https://bugs.launchpad.net/bugs/1933496 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=. 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 Reviewed-by: Ingo Franzki Signed-off-by: Vasily Gorbik (cherry picked from commit df6f508c68dbc65def0098cbdf8de7683ae551d2) Signed-off-by: Frank Heimes --- drivers/s390/crypto/ap_bus.c | 70 ++++++++++++++++++++++---- drivers/s390/crypto/ap_bus.h | 3 ++ drivers/s390/crypto/ap_card.c | 2 + drivers/s390/crypto/zcrypt_api.h | 2 +- drivers/s390/crypto/zcrypt_card.c | 30 ++++++++++- drivers/s390/crypto/zcrypt_msgtype50.c | 2 + drivers/s390/crypto/zcrypt_msgtype6.c | 5 ++ drivers/s390/crypto/zcrypt_queue.c | 14 ++++-- 8 files changed, 111 insertions(+), 17 deletions(-) diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 2758d05a802d..84e4884418ad 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -584,22 +584,47 @@ static int ap_bus_match(struct device *dev, struct device_driver *drv) */ static int ap_uevent(struct device *dev, struct kobj_uevent_env *env) { - int rc; + int rc = 0; struct ap_device *ap_dev = to_ap_dev(dev); /* Uevents from ap bus core don't need extensions to the env */ if (dev == ap_root_device) return 0; - /* Set up DEV_TYPE environment variable. */ - rc = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type); - if (rc) - return rc; + if (is_card_dev(dev)) { + struct ap_card *ac = to_ap_card(&ap_dev->device); - /* Add MODALIAS= */ - rc = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type); - if (rc) - return rc; + /* Set up DEV_TYPE environment variable. */ + rc = add_uevent_var(env, "DEV_TYPE=%04X", ap_dev->device_type); + if (rc) + return rc; + /* Add MODALIAS= */ + rc = add_uevent_var(env, "MODALIAS=ap:t%02X", ap_dev->device_type); + if (rc) + return rc; + + /* Add MODE= */ + if (ap_test_bit(&ac->functions, AP_FUNC_ACCEL)) + rc = add_uevent_var(env, "MODE=accel"); + else if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) + rc = add_uevent_var(env, "MODE=cca"); + else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) + rc = add_uevent_var(env, "MODE=ep11"); + if (rc) + return rc; + } else { + struct ap_queue *aq = to_ap_queue(&ap_dev->device); + + /* Add MODE= */ + if (ap_test_bit(&aq->card->functions, AP_FUNC_ACCEL)) + rc = add_uevent_var(env, "MODE=accel"); + else if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) + rc = add_uevent_var(env, "MODE=cca"); + else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) + rc = add_uevent_var(env, "MODE=ep11"); + if (rc) + return rc; + } return 0; } @@ -618,6 +643,28 @@ static void ap_send_bindings_complete_uevent(void) kobject_uevent_env(&ap_root_device->kobj, KOBJ_CHANGE, envp); } +void ap_send_config_uevent(struct ap_device *ap_dev, bool cfg) +{ + char buf[16]; + char *envp[] = { buf, NULL }; + + snprintf(buf, sizeof(buf), "CONFIG=%d", cfg ? 1 : 0); + + kobject_uevent_env(&ap_dev->device.kobj, KOBJ_CHANGE, envp); +} +EXPORT_SYMBOL(ap_send_config_uevent); + +void ap_send_online_uevent(struct ap_device *ap_dev, int online) +{ + char buf[16]; + char *envp[] = { buf, NULL }; + + snprintf(buf, sizeof(buf), "ONLINE=%d", online ? 1 : 0); + + kobject_uevent_env(&ap_dev->device.kobj, KOBJ_CHANGE, envp); +} +EXPORT_SYMBOL(ap_send_online_uevent); + /* * calc # of bound APQNs */ @@ -1540,6 +1587,7 @@ static inline void ap_scan_domains(struct ap_card *ac) spin_unlock_bh(&aq->lock); AP_DBF_INFO("%s(%d,%d) queue device config off\n", __func__, ac->id, dom); + ap_send_config_uevent(&aq->ap_dev, aq->config); /* 'receive' pending messages with -EAGAIN */ ap_flush_queue(aq); goto put_dev_and_continue; @@ -1554,6 +1602,7 @@ static inline void ap_scan_domains(struct ap_card *ac) spin_unlock_bh(&aq->lock); AP_DBF_INFO("%s(%d,%d) queue device config on\n", __func__, ac->id, dom); + ap_send_config_uevent(&aq->ap_dev, aq->config); goto put_dev_and_continue; } /* handle other error states */ @@ -1663,12 +1712,13 @@ static inline void ap_scan_adapter(int ap) ac->config = false; AP_DBF_INFO("%s(%d) card device config off\n", __func__, ap); - + ap_send_config_uevent(&ac->ap_dev, ac->config); } if (!decfg && !ac->config) { ac->config = true; AP_DBF_INFO("%s(%d) card device config on\n", __func__, ap); + ap_send_config_uevent(&ac->ap_dev, ac->config); } } } diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 472efd3a755c..230fec6510e2 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -362,4 +362,7 @@ int ap_parse_mask_str(const char *str, */ int ap_wait_init_apqn_bindings_complete(unsigned long timeout); +void ap_send_config_uevent(struct ap_device *ap_dev, bool cfg); +void ap_send_online_uevent(struct ap_device *ap_dev, int online); + #endif /* _AP_BUS_H_ */ diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index d98bdd28d23e..ca9afc5fcaf7 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -167,6 +167,8 @@ static ssize_t config_store(struct device *dev, ac->config = cfg ? true : false; + ap_send_config_uevent(&ac->ap_dev, ac->config); + return count; } diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index 16219efb2f61..2a90d35a9d4f 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h @@ -146,7 +146,7 @@ void zcrypt_queue_get(struct zcrypt_queue *); int zcrypt_queue_put(struct zcrypt_queue *); int zcrypt_queue_register(struct zcrypt_queue *); void zcrypt_queue_unregister(struct zcrypt_queue *); -void zcrypt_queue_force_online(struct zcrypt_queue *, int); +bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online); int zcrypt_rng_device_add(void); void zcrypt_rng_device_remove(void); 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; } diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c index bf14ee445f89..6d1800cb21df 100644 --- a/drivers/s390/crypto/zcrypt_msgtype50.c +++ b/drivers/s390/crypto/zcrypt_msgtype50.c @@ -375,6 +375,7 @@ static int convert_type80(struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), t80h->code); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } if (zq->zcard->user_space_type == ZCRYPT_CEX2A) @@ -412,6 +413,7 @@ static int convert_response_cex2a(struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) rtype); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } } diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c index 307f90657d1d..da6b2bf779a8 100644 --- a/drivers/s390/crypto/zcrypt_msgtype6.c +++ b/drivers/s390/crypto/zcrypt_msgtype6.c @@ -675,6 +675,7 @@ static int convert_type86_ica(struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) service_rc, (int) service_rs); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } data = msg->text; @@ -820,6 +821,7 @@ static int convert_response_ica(struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) msg->hdr.type); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } } @@ -854,6 +856,7 @@ static int convert_response_xcrb(bool userspace, struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) msg->hdr.type); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } } @@ -883,6 +886,7 @@ static int convert_response_ep11_xcrb(bool userspace, struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) msg->hdr.type); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } } @@ -913,6 +917,7 @@ static int convert_response_rng(struct zcrypt_queue *zq, AP_QID_CARD(zq->queue->qid), AP_QID_QUEUE(zq->queue->qid), (int) msg->hdr.type); + ap_send_online_uevent(&zq->queue->ap_dev, zq->online); return -EAGAIN; } } diff --git a/drivers/s390/crypto/zcrypt_queue.c b/drivers/s390/crypto/zcrypt_queue.c index c3ffbd26b73f..fd94e7f56336 100644 --- a/drivers/s390/crypto/zcrypt_queue.c +++ b/drivers/s390/crypto/zcrypt_queue.c @@ -70,6 +70,8 @@ static ssize_t online_store(struct device *dev, AP_QID_QUEUE(zq->queue->qid), online); + ap_send_online_uevent(&aq->ap_dev, online); + if (!online) ap_flush_queue(zq->queue); return count; @@ -98,11 +100,15 @@ static const struct attribute_group zcrypt_queue_attr_group = { .attrs = zcrypt_queue_attrs, }; -void zcrypt_queue_force_online(struct zcrypt_queue *zq, int online) +bool zcrypt_queue_force_online(struct zcrypt_queue *zq, int online) { - zq->online = online; - if (!online) - ap_flush_queue(zq->queue); + if (!!zq->online != !!online) { + zq->online = online; + if (!online) + ap_flush_queue(zq->queue); + return true; + } + return false; } struct zcrypt_queue *zcrypt_queue_alloc(size_t max_response_size)