aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/s390/include/uapi/asm/zcrypt.h37
-rw-r--r--drivers/s390/crypto/zcrypt_api.c42
2 files changed, 79 insertions, 0 deletions
diff --git a/arch/s390/include/uapi/asm/zcrypt.h b/arch/s390/include/uapi/asm/zcrypt.h
index f2b18eacaca8..a777f87ef889 100644
--- a/arch/s390/include/uapi/asm/zcrypt.h
+++ b/arch/s390/include/uapi/asm/zcrypt.h
@@ -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)
diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c
index fd0ae8cd2bee..403af9d1ebde 100644
--- a/drivers/s390/crypto/zcrypt_api.c
+++ b/drivers/s390/crypto/zcrypt_api.c
@@ -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);