s390/zcrypt: Rework zcrypt function zcrypt_device_status_mask_ext

Rework the existing function zcrypt_device_status_mask_ext():
Add two new parameters to provide upper limits for
cards and queues. The existing implementation needed an
array of 256 * 256 * 4 = 256 KB which is really huge. The
reworked function is more flexible in the sense that the
caller can decide the upper limit for cards and domains to
be stored into the status array. So for example a caller may
decide to only query for cards 0...127 and queues 0...127
and thus only an array of size 128 * 128 * 4 = 64 KB is needed.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Link: https://lore.kernel.org/r/20250424133619.16495-9-freude@linux.ibm.com
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
Harald Freudenberger
2025-04-24 15:36:02 +02:00
committed by Heiko Carstens
parent 366367a725
commit a01e748101
4 changed files with 33 additions and 13 deletions

View File

@@ -1304,19 +1304,25 @@ static void zcrypt_device_status_mask(struct zcrypt_device_status *devstatus)
spin_unlock(&zcrypt_list_lock);
}
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus)
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus,
int maxcard, int maxqueue)
{
struct zcrypt_card *zc;
struct zcrypt_queue *zq;
struct zcrypt_device_status_ext *stat;
int card, queue;
maxcard = min_t(int, maxcard, MAX_ZDEV_CARDIDS_EXT);
maxqueue = min_t(int, maxqueue, MAX_ZDEV_DOMAINS_EXT);
spin_lock(&zcrypt_list_lock);
for_each_zcrypt_card(zc) {
for_each_zcrypt_queue(zq, zc) {
card = AP_QID_CARD(zq->queue->qid);
queue = AP_QID_QUEUE(zq->queue->qid);
stat = &devstatus[card * AP_DOMAINS + queue];
if (card >= maxcard || queue >= maxqueue)
continue;
stat = &devstatus[card * maxqueue + queue];
stat->hwtype = zc->card->ap_dev.device_type;
stat->functions = zc->card->hwinfo.fac >> 26;
stat->qid = zq->queue->qid;
@@ -1622,7 +1628,9 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
zcrypt_device_status_mask_ext(device_status);
zcrypt_device_status_mask_ext(device_status,
MAX_ZDEV_CARDIDS_EXT,
MAX_ZDEV_DOMAINS_EXT);
if (copy_to_user((char __user *)arg, device_status,
total_size))
rc = -EFAULT;

View File

@@ -172,7 +172,8 @@ int zcrypt_api_init(void);
void zcrypt_api_exit(void);
long zcrypt_send_cprb(struct ica_xcRB *xcRB, u32 xflags);
long zcrypt_send_ep11_cprb(struct ep11_urb *urb, u32 xflags);
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus,
int maxcard, int maxqueue);
int zcrypt_device_status_ext(int card, int queue,
struct zcrypt_device_status_ext *devstatus);

View File

@@ -1806,7 +1806,10 @@ static int findcard(u64 mkvp, u16 *pcardnr, u16 *pdomain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
zcrypt_device_status_mask_ext(device_status);
zcrypt_device_status_mask_ext(device_status,
MAX_ZDEV_CARDIDS_EXT,
MAX_ZDEV_DOMAINS_EXT);
/* walk through all crypto cards */
for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
@@ -1913,7 +1916,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
{
struct zcrypt_device_status_ext *device_status;
u32 *_apqns = NULL, _nr_apqns = 0;
int i, card, dom, curmatch, oldmatch, rc = 0;
int i, card, dom, curmatch, oldmatch, rc;
struct cca_info ci;
/* fetch status of all crypto cards */
@@ -1922,13 +1925,16 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
zcrypt_device_status_mask_ext(device_status);
zcrypt_device_status_mask_ext(device_status,
MAX_ZDEV_CARDIDS_EXT,
MAX_ZDEV_DOMAINS_EXT);
/* allocate 1k space for up to 256 apqns */
_apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
if (!_apqns) {
kvfree(device_status);
return -ENOMEM;
rc = -ENOMEM;
goto out;
}
/* walk through all the crypto apqnss */
@@ -1993,6 +1999,7 @@ int cca_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
rc = 0;
}
out:
kvfree(device_status);
return rc;
}

View File

@@ -1598,7 +1598,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
{
struct zcrypt_device_status_ext *device_status;
u32 *_apqns = NULL, _nr_apqns = 0;
int i, card, dom, rc = -ENOMEM;
int i, card, dom, rc;
struct ep11_domain_info edi;
struct ep11_card_info eci;
@@ -1608,13 +1608,16 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
GFP_KERNEL);
if (!device_status)
return -ENOMEM;
zcrypt_device_status_mask_ext(device_status);
zcrypt_device_status_mask_ext(device_status,
MAX_ZDEV_CARDIDS_EXT,
MAX_ZDEV_DOMAINS_EXT);
/* allocate 1k space for up to 256 apqns */
_apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
if (!_apqns) {
kvfree(device_status);
return -ENOMEM;
rc = -ENOMEM;
goto out;
}
/* walk through all the crypto apqnss */
@@ -1668,6 +1671,7 @@ int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
rc = 0;
}
out:
kvfree(device_status);
return rc;
}