diff options
author | Harald Freudenberger <freude@linux.vnet.ibm.com> | 2018-04-09 16:18:37 +0200 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2018-04-11 10:36:27 +0200 |
commit | af4a72276d49da117dbc99799afee740a26f8f10 (patch) | |
tree | bf702e269fde807e249f60346abc6b1a685ba419 /drivers/s390 | |
parent | 71cbbff8c4fd1467b59b8c15a06093ac03cd11c7 (diff) | |
download | linux-stable-af4a72276d49da117dbc99799afee740a26f8f10.tar.gz linux-stable-af4a72276d49da117dbc99799afee740a26f8f10.tar.bz2 linux-stable-af4a72276d49da117dbc99799afee740a26f8f10.zip |
s390/zcrypt: Support up to 256 crypto adapters.
There was an artificial restriction on the card/adapter id
to only 6 bits but all the AP commands do support adapter
ids with 8 bit. This patch removes this restriction to 64
adapters and now up to 256 adapter can get addressed.
Some of the ioctl calls work on the max number of cards
possible (which was 64). These ioctls are now deprecated
but still supported. All the defines, structs and ioctl
interface declarations have been kept for compabibility.
There are now new ioctls (and defines for these) with an
additional '2' appended which provide the extended versions
with 256 cards supported.
Signed-off-by: Harald Freudenberger <freude@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/crypto/ap_bus.h | 2 | ||||
-rw-r--r-- | drivers/s390/crypto/pkey_api.c | 41 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.c | 182 | ||||
-rw-r--r-- | drivers/s390/crypto/zcrypt_api.h | 2 |
4 files changed, 156 insertions, 71 deletions
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h index 951ab595dc18..02184cf35834 100644 --- a/drivers/s390/crypto/ap_bus.h +++ b/drivers/s390/crypto/ap_bus.h @@ -17,7 +17,7 @@ #include <linux/types.h> #include <asm/ap.h> -#define AP_DEVICES 64 /* Number of AP devices. */ +#define AP_DEVICES 256 /* Number of AP devices. */ #define AP_DOMAINS 256 /* Number of AP domains. */ #define AP_RESET_TIMEOUT (HZ*0.7) /* Time in ticks for reset timeouts. */ #define AP_CONFIG_TIME 30 /* Time in seconds between AP bus rescans. */ diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c index e7c2e4f9529a..ed80d00cdb6f 100644 --- a/drivers/s390/crypto/pkey_api.c +++ b/drivers/s390/crypto/pkey_api.c @@ -889,7 +889,7 @@ int pkey_findcard(const struct pkey_seckey *seckey, u16 *pcardnr, u16 *pdomain, int verify) { struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; - struct zcrypt_device_matrix *device_matrix; + struct zcrypt_device_status_ext *device_status; u16 card, dom; u64 mkvp[2]; int i, rc, oi = -1; @@ -899,18 +899,19 @@ int pkey_findcard(const struct pkey_seckey *seckey, return -EINVAL; /* fetch status of all crypto cards */ - device_matrix = kmalloc(sizeof(struct zcrypt_device_matrix), + device_status = kmalloc(MAX_ZDEV_ENTRIES_EXT + * sizeof(struct zcrypt_device_status_ext), GFP_KERNEL); - if (!device_matrix) + if (!device_status) return -ENOMEM; - zcrypt_device_status_mask(device_matrix); + zcrypt_device_status_mask_ext(device_status); /* walk through all crypto cards */ - for (i = 0; i < MAX_ZDEV_ENTRIES; i++) { - card = AP_QID_CARD(device_matrix->device[i].qid); - dom = AP_QID_QUEUE(device_matrix->device[i].qid); - if (device_matrix->device[i].online && - device_matrix->device[i].functions & 0x04) { + for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { + card = AP_QID_CARD(device_status[i].qid); + dom = AP_QID_QUEUE(device_status[i].qid); + if (device_status[i].online && + device_status[i].functions & 0x04) { /* an enabled CCA Coprocessor card */ /* try cached mkvp */ if (mkvp_cache_fetch(card, dom, mkvp) == 0 && @@ -930,14 +931,14 @@ int pkey_findcard(const struct pkey_seckey *seckey, mkvp_cache_scrub(card, dom); } } - if (i >= MAX_ZDEV_ENTRIES) { + if (i >= MAX_ZDEV_ENTRIES_EXT) { /* nothing found, so this time without cache */ - for (i = 0; i < MAX_ZDEV_ENTRIES; i++) { - if (!(device_matrix->device[i].online && - device_matrix->device[i].functions & 0x04)) + for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { + if (!(device_status[i].online && + device_status[i].functions & 0x04)) continue; - card = AP_QID_CARD(device_matrix->device[i].qid); - dom = AP_QID_QUEUE(device_matrix->device[i].qid); + card = AP_QID_CARD(device_status[i].qid); + dom = AP_QID_QUEUE(device_status[i].qid); /* fresh fetch mkvp from adapter */ if (fetch_mkvp(card, dom, mkvp) == 0) { mkvp_cache_update(card, dom, mkvp); @@ -947,13 +948,13 @@ int pkey_findcard(const struct pkey_seckey *seckey, oi = i; } } - if (i >= MAX_ZDEV_ENTRIES && oi >= 0) { + if (i >= MAX_ZDEV_ENTRIES_EXT && oi >= 0) { /* old mkvp matched, use this card then */ - card = AP_QID_CARD(device_matrix->device[oi].qid); - dom = AP_QID_QUEUE(device_matrix->device[oi].qid); + card = AP_QID_CARD(device_status[oi].qid); + dom = AP_QID_QUEUE(device_status[oi].qid); } } - if (i < MAX_ZDEV_ENTRIES || oi >= 0) { + if (i < MAX_ZDEV_ENTRIES_EXT || oi >= 0) { if (pcardnr) *pcardnr = card; if (pdomain) @@ -962,7 +963,7 @@ int pkey_findcard(const struct pkey_seckey *seckey, } else rc = -ENODEV; - kfree(device_matrix); + kfree(device_status); return rc; } EXPORT_SYMBOL(pkey_findcard); diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 63cfdefe0537..5efd84862ccb 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -605,19 +605,24 @@ out: return rc; } -void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix) +static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus) { struct zcrypt_card *zc; struct zcrypt_queue *zq; struct zcrypt_device_status *stat; + int card, queue; + + memset(devstatus, 0, MAX_ZDEV_ENTRIES + * sizeof(struct zcrypt_device_status)); - 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); + card = AP_QID_CARD(zq->queue->qid); + if (card >= MAX_ZDEV_CARDIDS) + continue; + queue = AP_QID_QUEUE(zq->queue->qid); + stat = &devstatus[card * AP_DOMAINS + queue]; stat->hwtype = zc->card->ap_dev.device_type; stat->functions = zc->card->functions >> 26; stat->qid = zq->queue->qid; @@ -626,40 +631,70 @@ void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix) } spin_unlock(&zcrypt_list_lock); } -EXPORT_SYMBOL(zcrypt_device_status_mask); -static void zcrypt_status_mask(char status[AP_DEVICES]) +void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus) { struct zcrypt_card *zc; struct zcrypt_queue *zq; + struct zcrypt_device_status_ext *stat; + int card, queue; + + memset(devstatus, 0, MAX_ZDEV_ENTRIES_EXT + * sizeof(struct zcrypt_device_status_ext)); - memset(status, 0, sizeof(char) * AP_DEVICES); spin_lock(&zcrypt_list_lock); for_each_zcrypt_card(zc) { for_each_zcrypt_queue(zq, zc) { - if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) + card = AP_QID_CARD(zq->queue->qid); + queue = AP_QID_QUEUE(zq->queue->qid); + stat = &devstatus[card * AP_DOMAINS + queue]; + 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_ext); + +static void zcrypt_status_mask(char status[], size_t max_adapters) +{ + struct zcrypt_card *zc; + struct zcrypt_queue *zq; + int card; + + memset(status, 0, max_adapters); + spin_lock(&zcrypt_list_lock); + for_each_zcrypt_card(zc) { + for_each_zcrypt_queue(zq, zc) { + card = AP_QID_CARD(zq->queue->qid); + if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index + || card >= max_adapters) continue; - status[AP_QID_CARD(zq->queue->qid)] = - zc->online ? zc->user_space_type : 0x0d; + status[card] = zc->online ? zc->user_space_type : 0x0d; } } spin_unlock(&zcrypt_list_lock); } -static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES]) +static void zcrypt_qdepth_mask(char qdepth[], size_t max_adapters) { struct zcrypt_card *zc; struct zcrypt_queue *zq; + int card; - memset(qdepth, 0, sizeof(char) * AP_DEVICES); + memset(qdepth, 0, max_adapters); spin_lock(&zcrypt_list_lock); local_bh_disable(); for_each_zcrypt_card(zc) { for_each_zcrypt_queue(zq, zc) { - if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) + card = AP_QID_CARD(zq->queue->qid); + if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index + || card >= max_adapters) continue; spin_lock(&zq->queue->lock); - qdepth[AP_QID_CARD(zq->queue->qid)] = + qdepth[card] = zq->queue->pendingq_count + zq->queue->requestq_count; spin_unlock(&zq->queue->lock); @@ -669,21 +704,23 @@ static void zcrypt_qdepth_mask(char qdepth[AP_DEVICES]) spin_unlock(&zcrypt_list_lock); } -static void zcrypt_perdev_reqcnt(int reqcnt[AP_DEVICES]) +static void zcrypt_perdev_reqcnt(int reqcnt[], size_t max_adapters) { struct zcrypt_card *zc; struct zcrypt_queue *zq; + int card; - memset(reqcnt, 0, sizeof(int) * AP_DEVICES); + memset(reqcnt, 0, sizeof(int) * max_adapters); spin_lock(&zcrypt_list_lock); local_bh_disable(); for_each_zcrypt_card(zc) { for_each_zcrypt_queue(zq, zc) { - if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index) + card = AP_QID_CARD(zq->queue->qid); + if (AP_QID_QUEUE(zq->queue->qid) != ap_domain_index + || card >= max_adapters) continue; spin_lock(&zq->queue->lock); - reqcnt[AP_QID_CARD(zq->queue->qid)] = - zq->queue->total_request_count; + reqcnt[card] = zq->queue->total_request_count; spin_unlock(&zq->queue->lock); } } @@ -740,7 +777,7 @@ static int zcrypt_requestq_count(void) static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { - int rc; + int rc = 0; switch (cmd) { case ICARSAMODEXPO: { @@ -819,48 +856,48 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, return -EFAULT; return rc; } - case ZDEVICESTATUS: { - struct zcrypt_device_matrix *device_status; + case ZCRYPT_DEVICE_STATUS: { + struct zcrypt_device_status_ext *device_status; + size_t total_size = MAX_ZDEV_ENTRIES_EXT + * sizeof(struct zcrypt_device_status_ext); - device_status = kzalloc(sizeof(struct zcrypt_device_matrix), - GFP_KERNEL); + device_status = kzalloc(total_size, GFP_KERNEL); if (!device_status) return -ENOMEM; - - zcrypt_device_status_mask(device_status); - + zcrypt_device_status_mask_ext(device_status); if (copy_to_user((char __user *) arg, device_status, - sizeof(struct zcrypt_device_matrix))) { - kfree(device_status); - return -EFAULT; - } - + total_size)) + rc = -EFAULT; kfree(device_status); - return 0; + return rc; } - case Z90STAT_STATUS_MASK: { + case ZCRYPT_STATUS_MASK: { char status[AP_DEVICES]; - zcrypt_status_mask(status); - if (copy_to_user((char __user *) arg, status, - sizeof(char) * AP_DEVICES)) + + zcrypt_status_mask(status, AP_DEVICES); + if (copy_to_user((char __user *) arg, status, sizeof(status))) return -EFAULT; return 0; } - case Z90STAT_QDEPTH_MASK: { + case ZCRYPT_QDEPTH_MASK: { char qdepth[AP_DEVICES]; - zcrypt_qdepth_mask(qdepth); - if (copy_to_user((char __user *) arg, qdepth, - sizeof(char) * AP_DEVICES)) + + zcrypt_qdepth_mask(qdepth, AP_DEVICES); + if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth))) return -EFAULT; return 0; } - case Z90STAT_PERDEV_REQCNT: { - int reqcnt[AP_DEVICES]; - zcrypt_perdev_reqcnt(reqcnt); - if (copy_to_user((int __user *) arg, reqcnt, - sizeof(int) * AP_DEVICES)) - return -EFAULT; - return 0; + case ZCRYPT_PERDEV_REQCNT: { + int *reqcnt; + + reqcnt = kcalloc(AP_DEVICES, sizeof(int), GFP_KERNEL); + if (!reqcnt) + return -ENOMEM; + zcrypt_perdev_reqcnt(reqcnt, AP_DEVICES); + if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) + rc = -EFAULT; + kfree(reqcnt); + return rc; } case Z90STAT_REQUESTQ_COUNT: return put_user(zcrypt_requestq_count(), (int __user *) arg); @@ -871,8 +908,55 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd, (int __user *) arg); case Z90STAT_DOMAIN_INDEX: return put_user(ap_domain_index, (int __user *) arg); + /* + * Deprecated ioctls + */ + case ZDEVICESTATUS: { + /* the old ioctl supports only 64 adapters */ + struct zcrypt_device_status *device_status; + size_t total_size = MAX_ZDEV_ENTRIES + * sizeof(struct zcrypt_device_status); + + device_status = kzalloc(total_size, GFP_KERNEL); + if (!device_status) + return -ENOMEM; + zcrypt_device_status_mask(device_status); + if (copy_to_user((char __user *) arg, device_status, + total_size)) + rc = -EFAULT; + kfree(device_status); + return rc; + } + case Z90STAT_STATUS_MASK: { + /* the old ioctl supports only 64 adapters */ + char status[MAX_ZDEV_CARDIDS]; + + zcrypt_status_mask(status, MAX_ZDEV_CARDIDS); + if (copy_to_user((char __user *) arg, status, sizeof(status))) + return -EFAULT; + return 0; + } + case Z90STAT_QDEPTH_MASK: { + /* the old ioctl supports only 64 adapters */ + char qdepth[MAX_ZDEV_CARDIDS]; + + zcrypt_qdepth_mask(qdepth, MAX_ZDEV_CARDIDS); + if (copy_to_user((char __user *) arg, qdepth, sizeof(qdepth))) + return -EFAULT; + return 0; + } + case Z90STAT_PERDEV_REQCNT: { + /* the old ioctl supports only 64 adapters */ + int reqcnt[MAX_ZDEV_CARDIDS]; + + zcrypt_perdev_reqcnt(reqcnt, MAX_ZDEV_CARDIDS); + if (copy_to_user((int __user *) arg, reqcnt, sizeof(reqcnt))) + return -EFAULT; + return 0; + } /* unknown ioctl number */ default: + ZCRYPT_DBF(DBF_DEBUG, "unknown ioctl 0x%08x\n", cmd); return -ENOIOCTLCMD; } } diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index 8cc5f8055d24..f149a8fee60d 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h @@ -155,6 +155,6 @@ struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int); int zcrypt_api_init(void); void zcrypt_api_exit(void); long zcrypt_send_cprb(struct ica_xcRB *xcRB); -void zcrypt_device_status_mask(struct zcrypt_device_matrix *devstatus); +void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); #endif /* _ZCRYPT_API_H_ */ |