Skip to content

Commit a976d79

Browse files
mchehabardbiesheuvel
authored andcommitted
efi/cper: Add a new helper function to print bitmasks
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>
1 parent 8ad2c72 commit a976d79

2 files changed

Lines changed: 62 additions & 0 deletions

File tree

drivers/firmware/efi/cper.c

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
* Specification version 2.4.
1313
*/
1414

15+
#include <linux/bitmap.h>
1516
#include <linux/kernel.h>
1617
#include <linux/module.h>
1718
#include <linux/time.h>
@@ -106,6 +107,65 @@ void cper_print_bits(const char *pfx, unsigned int bits,
106107
printk("%s\n", buf);
107108
}
108109

110+
/**
111+
* cper_bits_to_str - return a string for set bits
112+
* @buf: buffer to store the output string
113+
* @buf_size: size of the output string buffer
114+
* @bits: bit mask
115+
* @strs: string array, indexed by bit position
116+
* @strs_size: size of the string array: @strs
117+
*
118+
* Add to @buf the bitmask in hexadecimal. Then, for each set bit in @bits,
119+
* add the corresponding string describing the bit in @strs to @buf.
120+
*
121+
* A typical example is::
122+
*
123+
* const char * const bits[] = {
124+
* "bit 3 name",
125+
* "bit 4 name",
126+
* "bit 5 name",
127+
* };
128+
* char str[120];
129+
* unsigned int bitmask = BIT(3) | BIT(5);
130+
* #define MASK GENMASK(5,3)
131+
*
132+
* cper_bits_to_str(str, sizeof(str), FIELD_GET(MASK, bitmask),
133+
* bits, ARRAY_SIZE(bits));
134+
*
135+
* The above code fills the string ``str`` with ``bit 3 name|bit 5 name``.
136+
*
137+
* Return: number of bytes stored or an error code if lower than zero.
138+
*/
139+
int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
140+
const char * const strs[], unsigned int strs_size)
141+
{
142+
int len = buf_size;
143+
char *str = buf;
144+
int i, size;
145+
146+
*buf = '\0';
147+
148+
for_each_set_bit(i, &bits, strs_size) {
149+
if (!(bits & BIT_ULL(i)))
150+
continue;
151+
152+
if (*buf && len > 0) {
153+
*str = '|';
154+
len--;
155+
str++;
156+
}
157+
158+
size = strscpy(str, strs[i], len);
159+
if (size < 0)
160+
return size;
161+
162+
len -= size;
163+
str += size;
164+
}
165+
return len - buf_size;
166+
}
167+
EXPORT_SYMBOL_GPL(cper_bits_to_str);
168+
109169
static const char * const proc_type_strs[] = {
110170
"IA32/X64",
111171
"IA64",

include/linux/cper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@ const char *cper_mem_err_type_str(unsigned int);
588588
const char *cper_mem_err_status_str(u64 status);
589589
void cper_print_bits(const char *prefix, unsigned int bits,
590590
const char * const strs[], unsigned int strs_size);
591+
int cper_bits_to_str(char *buf, int buf_size, unsigned long bits,
592+
const char * const strs[], unsigned int strs_size);
591593
void cper_mem_err_pack(const struct cper_sec_mem_err *,
592594
struct cper_mem_err_compact *);
593595
const char *cper_mem_err_unpack(struct trace_seq *,

0 commit comments

Comments
 (0)