Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Harald Freudenberger and committed by
Heiko Carstens
a01e7481 366367a7

+33 -13
+11 -3
drivers/s390/crypto/zcrypt_api.c
··· 1304 1304 spin_unlock(&zcrypt_list_lock); 1305 1305 } 1306 1306 1307 - void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus) 1307 + void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus, 1308 + int maxcard, int maxqueue) 1308 1309 { 1309 1310 struct zcrypt_card *zc; 1310 1311 struct zcrypt_queue *zq; 1311 1312 struct zcrypt_device_status_ext *stat; 1312 1313 int card, queue; 1313 1314 1315 + maxcard = min_t(int, maxcard, MAX_ZDEV_CARDIDS_EXT); 1316 + maxqueue = min_t(int, maxqueue, MAX_ZDEV_DOMAINS_EXT); 1317 + 1314 1318 spin_lock(&zcrypt_list_lock); 1315 1319 for_each_zcrypt_card(zc) { 1316 1320 for_each_zcrypt_queue(zq, zc) { 1317 1321 card = AP_QID_CARD(zq->queue->qid); 1318 1322 queue = AP_QID_QUEUE(zq->queue->qid); 1319 - stat = &devstatus[card * AP_DOMAINS + queue]; 1323 + if (card >= maxcard || queue >= maxqueue) 1324 + continue; 1325 + stat = &devstatus[card * maxqueue + queue]; 1320 1326 stat->hwtype = zc->card->ap_dev.device_type; 1321 1327 stat->functions = zc->card->hwinfo.fac >> 26; 1322 1328 stat->qid = zq->queue->qid; ··· 1628 1622 GFP_KERNEL); 1629 1623 if (!device_status) 1630 1624 return -ENOMEM; 1631 - zcrypt_device_status_mask_ext(device_status); 1625 + zcrypt_device_status_mask_ext(device_status, 1626 + MAX_ZDEV_CARDIDS_EXT, 1627 + MAX_ZDEV_DOMAINS_EXT); 1632 1628 if (copy_to_user((char __user *)arg, device_status, 1633 1629 total_size)) 1634 1630 rc = -EFAULT;
+2 -1
drivers/s390/crypto/zcrypt_api.h
··· 172 172 void zcrypt_api_exit(void); 173 173 long zcrypt_send_cprb(struct ica_xcRB *xcRB, u32 xflags); 174 174 long zcrypt_send_ep11_cprb(struct ep11_urb *urb, u32 xflags); 175 - void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus); 175 + void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus, 176 + int maxcard, int maxqueue); 176 177 int zcrypt_device_status_ext(int card, int queue, 177 178 struct zcrypt_device_status_ext *devstatus); 178 179
+12 -5
drivers/s390/crypto/zcrypt_ccamisc.c
··· 1806 1806 GFP_KERNEL); 1807 1807 if (!device_status) 1808 1808 return -ENOMEM; 1809 - zcrypt_device_status_mask_ext(device_status); 1809 + 1810 + zcrypt_device_status_mask_ext(device_status, 1811 + MAX_ZDEV_CARDIDS_EXT, 1812 + MAX_ZDEV_DOMAINS_EXT); 1810 1813 1811 1814 /* walk through all crypto cards */ 1812 1815 for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) { ··· 1916 1913 { 1917 1914 struct zcrypt_device_status_ext *device_status; 1918 1915 u32 *_apqns = NULL, _nr_apqns = 0; 1919 - int i, card, dom, curmatch, oldmatch, rc = 0; 1916 + int i, card, dom, curmatch, oldmatch, rc; 1920 1917 struct cca_info ci; 1921 1918 1922 1919 /* fetch status of all crypto cards */ ··· 1925 1922 GFP_KERNEL); 1926 1923 if (!device_status) 1927 1924 return -ENOMEM; 1928 - zcrypt_device_status_mask_ext(device_status); 1925 + 1926 + zcrypt_device_status_mask_ext(device_status, 1927 + MAX_ZDEV_CARDIDS_EXT, 1928 + MAX_ZDEV_DOMAINS_EXT); 1929 1929 1930 1930 /* allocate 1k space for up to 256 apqns */ 1931 1931 _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL); 1932 1932 if (!_apqns) { 1933 - kvfree(device_status); 1934 - return -ENOMEM; 1933 + rc = -ENOMEM; 1934 + goto out; 1935 1935 } 1936 1936 1937 1937 /* walk through all the crypto apqnss */ ··· 1999 1993 rc = 0; 2000 1994 } 2001 1995 1996 + out: 2002 1997 kvfree(device_status); 2003 1998 return rc; 2004 1999 }
+8 -4
drivers/s390/crypto/zcrypt_ep11misc.c
··· 1598 1598 { 1599 1599 struct zcrypt_device_status_ext *device_status; 1600 1600 u32 *_apqns = NULL, _nr_apqns = 0; 1601 - int i, card, dom, rc = -ENOMEM; 1601 + int i, card, dom, rc; 1602 1602 struct ep11_domain_info edi; 1603 1603 struct ep11_card_info eci; 1604 1604 ··· 1608 1608 GFP_KERNEL); 1609 1609 if (!device_status) 1610 1610 return -ENOMEM; 1611 - zcrypt_device_status_mask_ext(device_status); 1611 + 1612 + zcrypt_device_status_mask_ext(device_status, 1613 + MAX_ZDEV_CARDIDS_EXT, 1614 + MAX_ZDEV_DOMAINS_EXT); 1612 1615 1613 1616 /* allocate 1k space for up to 256 apqns */ 1614 1617 _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL); 1615 1618 if (!_apqns) { 1616 - kvfree(device_status); 1617 - return -ENOMEM; 1619 + rc = -ENOMEM; 1620 + goto out; 1618 1621 } 1619 1622 1620 1623 /* walk through all the crypto apqnss */ ··· 1671 1668 rc = 0; 1672 1669 } 1673 1670 1671 + out: 1674 1672 kvfree(device_status); 1675 1673 return rc; 1676 1674 }