s390/pai: export number of sysfs attribute files
authorThomas Richter <tmricht@linux.ibm.com>
Thu, 18 Jan 2024 12:46:08 +0000 (13:46 +0100)
committerHeiko Carstens <hca@linux.ibm.com>
Fri, 9 Feb 2024 12:58:14 +0000 (13:58 +0100)
The number of sysfs files to be exported by the PAI device drivers
depends on the hardware version level. Use the value returned by
the hardware as the maximum number of counters to be exported
in the sysfs attribute tree.

Without the fix, older machine generation export counter names
based on paiXXXX_ctrnames static array info, which can be inaccurate,
as this array could also contain newer counter names in the
future.  This ensures proper pai counter sysfs attributes for
both newer generation and older generation processors.

Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Acked-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
arch/s390/kernel/perf_pai_crypto.c
arch/s390/kernel/perf_pai_ext.c

index 69639ff1c5e0326757215b1a2fad52f8480ba819..ffde6d5001b797b712e4a822eb2dcee62fe2651c 100644 (file)
@@ -694,6 +694,12 @@ static int __init attr_event_init_one(struct attribute **attrs, int num)
 {
        struct perf_pmu_events_attr *pa;
 
+       /* Index larger than array_size, no counter name available */
+       if (num >= ARRAY_SIZE(paicrypt_ctrnames)) {
+               attrs[num] = NULL;
+               return 0;
+       }
+
        pa = kzalloc(sizeof(*pa), GFP_KERNEL);
        if (!pa)
                return -ENOMEM;
@@ -714,11 +720,10 @@ static int __init attr_event_init(void)
        struct attribute **attrs;
        int ret, i;
 
-       attrs = kmalloc_array(ARRAY_SIZE(paicrypt_ctrnames) + 1, sizeof(*attrs),
-                             GFP_KERNEL);
+       attrs = kmalloc_array(paicrypt_cnt + 2, sizeof(*attrs), GFP_KERNEL);
        if (!attrs)
                return -ENOMEM;
-       for (i = 0; i < ARRAY_SIZE(paicrypt_ctrnames); i++) {
+       for (i = 0; i <= paicrypt_cnt; i++) {
                ret = attr_event_init_one(attrs, i);
                if (ret) {
                        attr_event_free(attrs, i);
index 95d1a890640a389f3f3917b9a1bb7a46fdd736a5..4d86130bcf14442ce353176bc327f7453d365aa2 100644 (file)
@@ -584,6 +584,12 @@ static int __init attr_event_init_one(struct attribute **attrs, int num)
 {
        struct perf_pmu_events_attr *pa;
 
+       /* Index larger than array_size, no counter name available */
+       if (num >= ARRAY_SIZE(paiext_ctrnames)) {
+               attrs[num] = NULL;
+               return 0;
+       }
+
        pa = kzalloc(sizeof(*pa), GFP_KERNEL);
        if (!pa)
                return -ENOMEM;
@@ -604,11 +610,10 @@ static int __init attr_event_init(void)
        struct attribute **attrs;
        int ret, i;
 
-       attrs = kmalloc_array(ARRAY_SIZE(paiext_ctrnames) + 1, sizeof(*attrs),
-                             GFP_KERNEL);
+       attrs = kmalloc_array(paiext_cnt + 2, sizeof(*attrs), GFP_KERNEL);
        if (!attrs)
                return -ENOMEM;
-       for (i = 0; i < ARRAY_SIZE(paiext_ctrnames); i++) {
+       for (i = 0; i <= paiext_cnt; i++) {
                ret = attr_event_init_one(attrs, i);
                if (ret) {
                        attr_event_free(attrs, i);