s390/ap: filter ap card functions, new queue functions attribute
authorHarald Freudenberger <freude@linux.ibm.com>
Wed, 7 Sep 2022 15:25:45 +0000 (17:25 +0200)
committerHeiko Carstens <hca@linux.ibm.com>
Mon, 20 Mar 2023 10:12:48 +0000 (11:12 +0100)
With SE SB (Secure Binding) some currently unused and thus always
zero bits in the TAPQ GR2 result are now used to show the binding
state of a queue. So to check if a card has changed the comparing
base is exactly this GR2 value shown as 'ap_function' in sysfs
(/sys/devices/ap/cardxx/ap_functions). Now there is some queue
specific info in this info and so a new mask TAPQ_CARD_FUNC_CMP_MASK
is used to filter out only the relevant bits for card compare.

For the same reason now the function bits (including exactly this
bind/associate information) need to be exposed to user space now.
So tools like lszcrypt can evaluate binding/association state on a
queue base. So here comes a new sysfs attribute

  /sys/devices/ap/cardxx/xx.yyyy/ap_functions

This sysfs attribute is similar to the already existing
ap_functions attribute at ap card level. It shows the
upper 32 bits of GR2 from an invocation of TAPQ for this
AP queue.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
drivers/s390/crypto/ap_bus.c
drivers/s390/crypto/ap_bus.h
drivers/s390/crypto/ap_queue.c

index ab37818faeabdee8c4000cb4feeeed466fdb8240..05e4fe1384a86ba224dd6667641dfc2b8c93227e 100644 (file)
@@ -1999,7 +1999,6 @@ static inline void ap_scan_adapter(int ap)
                }
                return;
        }
-
        if (ac) {
                /* Check APQN against existing card device for changes */
                if (ac->raw_hwtype != type) {
@@ -2008,9 +2007,10 @@ static inline void ap_scan_adapter(int ap)
                        ap_scan_rm_card_dev_and_queue_devs(ac);
                        put_device(dev);
                        ac = NULL;
-               } else if (ac->functions != func) {
+               } else if ((ac->functions & TAPQ_CARD_FUNC_CMP_MASK) !=
+                          (func & TAPQ_CARD_FUNC_CMP_MASK)) {
                        AP_DBF_INFO("%s(%d) functions 0x%08x changed, rm card and queue devs\n",
-                                   __func__, ap, type);
+                                   __func__, ap, func);
                        ap_scan_rm_card_dev_and_queue_devs(ac);
                        put_device(dev);
                        ac = NULL;
index 5ce020879a38b1c8065a1222e181590ea1529fa5..f09a3fd4d7bdc7652c10ba807a30fdd2960684e6 100644 (file)
@@ -178,7 +178,7 @@ struct ap_device {
 struct ap_card {
        struct ap_device ap_dev;
        int raw_hwtype;                 /* AP raw hardware type. */
-       unsigned int functions;         /* AP device function bitfield. */
+       unsigned int functions;         /* TAPQ GR2 upper 32 facility bits */
        int queue_depth;                /* AP queue depth.*/
        int id;                         /* AP card number. */
        unsigned int maxmsgsize;        /* AP msg limit for this card */
@@ -187,6 +187,8 @@ struct ap_card {
        atomic64_t total_request_count; /* # requests ever for this AP device.*/
 };
 
+#define TAPQ_CARD_FUNC_CMP_MASK 0xFFFF0000
+
 #define to_ap_card(x) container_of((x), struct ap_card, ap_dev.device)
 
 struct ap_queue {
index 57028a35be980b49a0b6058f91d6191742d611c8..1c08b282987ccc8cdbfb6d56749274c071657d91 100644 (file)
@@ -630,6 +630,26 @@ static ssize_t chkstop_show(struct device *dev,
 
 static DEVICE_ATTR_RO(chkstop);
 
+static ssize_t ap_functions_show(struct device *dev,
+                                struct device_attribute *attr, char *buf)
+{
+       struct ap_queue *aq = to_ap_queue(dev);
+       struct ap_queue_status status;
+       struct ap_tapq_gr2 info;
+
+       status = ap_test_queue(aq->qid, 1, &info);
+       if (status.response_code > AP_RESPONSE_BUSY) {
+               AP_DBF_DBG("%s RC 0x%02x on tapq(0x%02x.%04x)\n",
+                          __func__, status.response_code,
+                          AP_QID_CARD(aq->qid), AP_QID_QUEUE(aq->qid));
+               return -EIO;
+       }
+
+       return sysfs_emit(buf, "0x%08X\n", info.fac);
+}
+
+static DEVICE_ATTR_RO(ap_functions);
+
 #ifdef CONFIG_ZCRYPT_DEBUG
 static ssize_t states_show(struct device *dev,
                           struct device_attribute *attr, char *buf)
@@ -738,6 +758,7 @@ static struct attribute *ap_queue_dev_attrs[] = {
        &dev_attr_interrupt.attr,
        &dev_attr_config.attr,
        &dev_attr_chkstop.attr,
+       &dev_attr_ap_functions.attr,
 #ifdef CONFIG_ZCRYPT_DEBUG
        &dev_attr_states.attr,
        &dev_attr_last_err_rc.attr,