s390/zcrypt: Introduce new zcrypt device status API
authorIngo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Thu, 25 Aug 2016 09:19:58 +0000 (11:19 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 14 Dec 2016 15:33:38 +0000 (16:33 +0100)
Introduce new ioctl (ZDEVICESTATUS) to provide detailed
information, like hardware type, domains, status and functionality
of available crypto devices.

Signed-off-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/uapi/asm/zcrypt.h
drivers/s390/crypto/zcrypt_api.c

index f2b18ea..a777f87 100644 (file)
@@ -215,6 +215,42 @@ struct ep11_urb {
        uint64_t                resp;
 } __attribute__((packed));
 
+/**
+ * struct zcrypt_device_status
+ * @hwtype:            raw hardware type
+ * @qid:               6 bit device index, 8 bit domain
+ * @functions:         AP device function bit field 'abcdef'
+ *                     a, b, c = reserved
+ *                     d = CCA coprocessor
+ *                     e = Accelerator
+ *                     f = EP11 coprocessor
+ * @online             online status
+ * @reserved           reserved
+ */
+struct zcrypt_device_status {
+       unsigned int hwtype:8;
+       unsigned int qid:14;
+       unsigned int online:1;
+       unsigned int functions:6;
+       unsigned int reserved:3;
+};
+
+#define MAX_ZDEV_CARDIDS 64
+#define MAX_ZDEV_DOMAINS 256
+
+/**
+ * Maximum number of zcrypt devices
+ */
+#define MAX_ZDEV_ENTRIES (MAX_ZDEV_CARDIDS * MAX_ZDEV_DOMAINS)
+
+/**
+ * zcrypt_device_matrix
+ * Device matrix of all zcrypt devices
+ */
+struct zcrypt_device_matrix {
+       struct zcrypt_device_status device[MAX_ZDEV_ENTRIES];
+};
+
 #define AUTOSELECT ((unsigned int)0xFFFFFFFF)
 
 #define ZCRYPT_IOCTL_MAGIC 'z'
@@ -321,6 +357,7 @@ struct ep11_urb {
 #define ICARSACRT      _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0)
 #define ZSECSENDCPRB   _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0)
 #define ZSENDEP11CPRB  _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x04, 0)
+#define ZDEVICESTATUS  _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x4f, 0)
 
 /* New status calls */
 #define Z90STAT_TOTALCOUNT     _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int)
index fd0ae8c..403af9d 100644 (file)
@@ -539,6 +539,29 @@ static long zcrypt_rng(char *buffer)
        return rc;
 }
 
+static void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix)
+{
+       struct zcrypt_card *zc;
+       struct zcrypt_queue *zq;
+       struct zcrypt_device_status *stat;
+
+       memset(matrix, 0, sizeof(*matrix));
+       spin_lock(&zcrypt_list_lock);
+       for_each_zcrypt_card(zc) {
+               for_each_zcrypt_queue(zq, zc) {
+                       stat = matrix->device;
+                       stat += AP_QID_CARD(zq->queue->qid) * MAX_ZDEV_DOMAINS;
+                       stat += AP_QID_QUEUE(zq->queue->qid);
+                       stat->hwtype = zc->card->ap_dev.device_type;
+                       stat->functions = zc->card->functions >> 26;
+                       stat->qid = zq->queue->qid;
+                       stat->online = zq->online ? 0x01 : 0x00;
+               }
+       }
+       spin_unlock(&zcrypt_list_lock);
+}
+EXPORT_SYMBOL(zcrypt_device_status_mask);
+
 static void zcrypt_status_mask(char status[AP_DEVICES])
 {
        struct zcrypt_card *zc;
@@ -764,6 +787,25 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
                        return -EFAULT;
                return rc;
        }
+       case ZDEVICESTATUS: {
+               struct zcrypt_device_matrix *device_status;
+
+               device_status = kzalloc(sizeof(struct zcrypt_device_matrix),
+                                       GFP_KERNEL);
+               if (!device_status)
+                       return -ENOMEM;
+
+               zcrypt_device_status_mask(device_status);
+
+               if (copy_to_user((char __user *) arg, device_status,
+                                sizeof(struct zcrypt_device_matrix))) {
+                       kfree(device_status);
+                       return -EFAULT;
+               }
+
+               kfree(device_status);
+               return 0;
+       }
        case Z90STAT_STATUS_MASK: {
                char status[AP_DEVICES];
                zcrypt_status_mask(status);