]> Gentwo Git Trees - linux/.git/commitdiff
efi/cper: Add a new helper function to print bitmasks
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Thu, 14 Aug 2025 16:52:54 +0000 (09:52 -0700)
committerArd Biesheuvel <ardb@kernel.org>
Fri, 21 Nov 2025 08:42:02 +0000 (09:42 +0100)
Add a helper function to print a string with names associated
to each bit field.

A typical example is:

const char * const bits[] = {
"bit 3 name",
"bit 4 name",
"bit 5 name",
};
char str[120];
        unsigned int bitmask = BIT(3) | BIT(5);

#define MASK  GENMASK(5,3)

cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask),
 bits, ARRAY_SIZE(bits));

The above code fills string "str" with "bit 3 name|bit 5 name".

Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
drivers/firmware/efi/cper.c
include/linux/cper.h

index 928409199a1a4009b11cf3189fe036ad8861169c..79ba688a64f8da7af2dad097b9331c72afc73864 100644 (file)
@@ -12,6 +12,7 @@
  * Specification version 2.4.
  */
 
+#include <linux/bitmap.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/time.h>
@@ -106,6 +107,65 @@ void cper_print_bits(const char *pfx, unsigned int bits,
                printk("%s\n", buf);
 }
 
+/**
+ * cper_bits_to_str - return a string for set bits
+ * @buf: buffer to store the output string
+ * @buf_size: size of the output string buffer
+ * @bits: bit mask
+ * @strs: string array, indexed by bit position
+ * @strs_size: size of the string array: @strs
+ *
+ * Add to @buf the bitmask in hexadecimal. Then, for each set bit in @bits,
+ * add the corresponding string describing the bit in @strs to @buf.
+ *
+ * A typical example is::
+ *
+ *     const char * const bits[] = {
+ *             "bit 3 name",
+ *             "bit 4 name",
+ *             "bit 5 name",
+ *     };
+ *     char str[120];
+ *     unsigned int bitmask = BIT(3) | BIT(5);
+ *     #define MASK GENMASK(5,3)
+ *
+ *     cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask),
+ *                      bits, ARRAY_SIZE(bits));
+ *
+ * The above code fills the string ``str`` with ``bit 3 name|bit 5 name``.
+ *
+ * Return: number of bytes stored or an error code if lower than zero.
+ */
+int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
+                    const char * const strs[], unsigned int strs_size)
+{
+       int len = buf_size;
+       char *str = buf;
+       int i, size;
+
+       *buf = '\0';
+
+       for_each_set_bit(i, &bits, strs_size) {
+               if (!(bits & BIT_ULL(i)))
+                       continue;
+
+               if (*buf && len > 0) {
+                       *str = '|';
+                       len--;
+                       str++;
+               }
+
+               size = strscpy(str, strs[i], len);
+               if (size < 0)
+                       return size;
+
+               len -= size;
+               str += size;
+       }
+       return len - buf_size;
+}
+EXPORT_SYMBOL_GPL(cper_bits_to_str);
+
 static const char * const proc_type_strs[] = {
        "IA32/X64",
        "IA64",
index 0ed60a91eca9d6425c9a41947a927b59f7aa2c71..58f40477c824e61c7f798978947bf1f441ce45ad 100644 (file)
@@ -588,6 +588,8 @@ const char *cper_mem_err_type_str(unsigned int);
 const char *cper_mem_err_status_str(u64 status);
 void cper_print_bits(const char *prefix, unsigned int bits,
                     const char * const strs[], unsigned int strs_size);
+int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
+                    const char * const strs[], unsigned int strs_size);
 void cper_mem_err_pack(const struct cper_sec_mem_err *,
                       struct cper_mem_err_compact *);
 const char *cper_mem_err_unpack(struct trace_seq *,