lib: sbi: change sbi_hart_features.extensions as an array
authorXiang W <wxjstz@126.com>
Mon, 30 Oct 2023 16:39:40 +0000 (00:39 +0800)
committerAnup Patel <anup@brainfault.org>
Fri, 17 Nov 2023 07:53:49 +0000 (13:23 +0530)
In the future there may be a lot of ISA extensions, a 'long' may not
be able to accommodate, changed to an array for the future.

Addresses-Coverity-ID: 1568357 Out-of-bounds access
Fixes: 6259b2ec2d09 ("lib: utils/fdt: Fix fdt_parse_isa_extensions()
implementation")
Signed-off-by: Xiang W <wxjstz@126.com>
Reviewed-by: Heinrich Schuchardt <heinrich.schuchardt@canonical.com>
Reviewed-by: Anup Patel <anup@brainfault.org>
include/sbi/sbi_hart.h
lib/sbi/sbi_hart.c
platform/generic/platform.c

index fe1124ab2d952b2d128ca5b74a1e47edf7667c8f..6ee49ffcd38c30b411cb32ce308b81e359f98a77 100644 (file)
@@ -11,6 +11,7 @@
 #define __SBI_HART_H__
 
 #include <sbi/sbi_types.h>
+#include <sbi/sbi_bitops.h>
 
 /** Possible privileged specification versions of a hart */
 enum sbi_hart_priv_versions {
@@ -67,7 +68,7 @@ enum sbi_hart_extensions {
 struct sbi_hart_features {
        bool detected;
        int priv_version;
-       unsigned long extensions;
+       unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)];
        unsigned int pmp_count;
        unsigned int pmp_addr_bits;
        unsigned long pmp_gran;
index b47f00b2ed125afb86fa3441d78ef3bbaf7bdc04..77eef49cbf8cf358ee352619cf46c9a578bfb167 100644 (file)
@@ -620,9 +620,9 @@ static inline void __sbi_hart_update_extension(
                                        bool enable)
 {
        if (enable)
-               hfeatures->extensions |= BIT(ext);
+               __set_bit(ext, hfeatures->extensions);
        else
-               hfeatures->extensions &= ~BIT(ext);
+               __clear_bit(ext, hfeatures->extensions);
 }
 
 /**
@@ -655,7 +655,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch,
        struct sbi_hart_features *hfeatures =
                        sbi_scratch_offset_ptr(scratch, hart_features_offset);
 
-       if (hfeatures->extensions & BIT(ext))
+       if (__test_bit(ext, hfeatures->extensions))
                return true;
        else
                return false;
@@ -721,24 +721,16 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
                return;
        sbi_memset(extensions_str, 0, nestr);
 
-       if (!hfeatures->extensions)
-               goto done;
-
-       do {
-               if (hfeatures->extensions & BIT(ext)) {
-                       temp = sbi_hart_extension_id2string(ext);
-                       if (temp) {
-                               sbi_snprintf(extensions_str + offset,
-                                            nestr - offset,
-                                            "%s,", temp);
-                               offset = offset + sbi_strlen(temp) + 1;
-                       }
+       for_each_set_bit(ext, hfeatures->extensions, SBI_HART_EXT_MAX) {
+               temp = sbi_hart_extension_id2string(ext);
+               if (temp) {
+                       sbi_snprintf(extensions_str + offset,
+                                    nestr - offset,
+                                    "%s,", temp);
+                       offset = offset + sbi_strlen(temp) + 1;
                }
+       }
 
-               ext++;
-       } while (ext < SBI_HART_EXT_MAX);
-
-done:
        if (offset)
                extensions_str[offset - 1] = '\0';
        else
@@ -808,7 +800,7 @@ static int hart_detect_features(struct sbi_scratch *scratch)
                return 0;
 
        /* Clear hart features */
-       hfeatures->extensions = 0;
+       sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions));
        hfeatures->pmp_count = 0;
        hfeatures->mhpm_mask = 0;
 
index 4246efdb1ad98a075e1daef0b5f0fa0b818aad35..85acecd7b8d861ea78bd1f5d3235fb80589a5071 100644 (file)
@@ -215,7 +215,7 @@ static int generic_extensions_init(struct sbi_hart_features *hfeatures)
 
        /* Parse the ISA string from FDT and enable the listed extensions */
        rc = fdt_parse_isa_extensions(fdt_get_address(), current_hartid(),
-                                     &hfeatures->extensions);
+                                     hfeatures->extensions);
 
        if (rc)
                return rc;