Skip to content

Commit 5892144

Browse files
Ahmed S. DarwishKAGA-KOKO
authored andcommitted
tools/x86/kcpuid: Parse subleaf ranges if provided
It's a common pattern in cpuid leaves to have the same bitfields format repeated across a number of subleaves. Typically, this is used for enumerating hierarchial structures like cache and TLB levels, CPU topology levels, etc. Modify kcpuid.c to handle subleaf ranges in the CSV file subleaves column. For example, make it able to parse lines in the form: # LEAF, SUBLEAVES, reg, bits, short_name , ... 0xb, 1:0, eax, 4:0, x2apic_id_shift , ... 0xb, 1:0, ebx, 15:0, domain_lcpus_count , ... 0xb, 1:0, ecx, 7:0, domain_nr , ... This way, full output can be printed to the user. Signed-off-by: Ahmed S. Darwish <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Link: https://lore.kernel.org/all/[email protected]
1 parent b0a59d1 commit 5892144

File tree

1 file changed

+32
-18
lines changed

1 file changed

+32
-18
lines changed

tools/arch/x86/kcpuid/kcpuid.c

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ static int parse_line(char *line)
305305
struct bits_desc *bdesc;
306306
int reg_index;
307307
char *start, *end;
308+
u32 subleaf_start, subleaf_end;
309+
unsigned bit_start, bit_end;
308310

309311
/* Skip comments and NULL line */
310312
if (line[0] == '#' || line[0] == '\n')
@@ -343,13 +345,25 @@ static int parse_line(char *line)
343345
return 0;
344346

345347
/* subleaf */
346-
sub = strtoul(tokens[1], NULL, 0);
347-
if ((int)sub > func->nr)
348-
return -1;
348+
buf = tokens[1];
349+
end = strtok(buf, ":");
350+
start = strtok(NULL, ":");
351+
subleaf_end = strtoul(end, NULL, 0);
352+
353+
/* A subleaf range is given? */
354+
if (start) {
355+
subleaf_start = strtoul(start, NULL, 0);
356+
subleaf_end = min(subleaf_end, (u32)(func->nr - 1));
357+
if (subleaf_start > subleaf_end)
358+
return 0;
359+
} else {
360+
subleaf_start = subleaf_end;
361+
if (subleaf_start > (u32)(func->nr - 1))
362+
return 0;
363+
}
349364

350-
leaf = &func->leafs[sub];
365+
/* register */
351366
buf = tokens[2];
352-
353367
if (strcasestr(buf, "EAX"))
354368
reg_index = R_EAX;
355369
else if (strcasestr(buf, "EBX"))
@@ -361,23 +375,23 @@ static int parse_line(char *line)
361375
else
362376
goto err_exit;
363377

364-
reg = &leaf->info[reg_index];
365-
bdesc = &reg->descs[reg->nr++];
366-
367378
/* bit flag or bits field */
368379
buf = tokens[3];
369-
370380
end = strtok(buf, ":");
371-
bdesc->end = strtoul(end, NULL, 0);
372-
bdesc->start = bdesc->end;
373-
374-
/* start != NULL means it is bit fields */
375381
start = strtok(NULL, ":");
376-
if (start)
377-
bdesc->start = strtoul(start, NULL, 0);
378-
379-
strcpy(bdesc->simp, strtok(tokens[4], " \t"));
380-
strcpy(bdesc->detail, tokens[5]);
382+
bit_end = strtoul(end, NULL, 0);
383+
bit_start = (start) ? strtoul(start, NULL, 0) : bit_end;
384+
385+
for (sub = subleaf_start; sub <= subleaf_end; sub++) {
386+
leaf = &func->leafs[sub];
387+
reg = &leaf->info[reg_index];
388+
bdesc = &reg->descs[reg->nr++];
389+
390+
bdesc->end = bit_end;
391+
bdesc->start = bit_start;
392+
strcpy(bdesc->simp, strtok(tokens[4], " \t"));
393+
strcpy(bdesc->detail, tokens[5]);
394+
}
381395
return 0;
382396

383397
err_exit:

0 commit comments

Comments
 (0)