Skip to content

Commit d3d2cf1

Browse files
evangreenpalmer-dabbelt
authored andcommitted
RISC-V: Show accurate per-hart isa in /proc/cpuinfo
In /proc/cpuinfo, most of the information we show for each processor is specific to that hart: marchid, mvendorid, mimpid, processor, hart, compatible, and the mmu size. But the ISA string gets filtered through a lowest common denominator mask, so that if one CPU is missing an ISA extension, no CPUs will show it. Now that we track the ISA extensions for each hart, let's report ISA extension info accurately per-hart in /proc/cpuinfo. We cannot change the "isa:" line, as usermode may be relying on that line to show only the common set of extensions supported across all harts. Add a new "hart isa" line instead, which reports the true set of extensions for that hart. Signed-off-by: Evan Green <[email protected]> Reviewed-by: Andrew Jones <[email protected]> Reviewed-by: Conor Dooley <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 28ea54b commit d3d2cf1

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

Documentation/riscv/uabi.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ An example string following the order is::
4242

4343
rv64imadc_zifoo_zigoo_zafoo_sbar_scar_zxmbaz_xqux_xrux
4444

45+
"isa" and "hart isa" lines in /proc/cpuinfo
46+
-------------------------------------------
47+
48+
The "isa" line in /proc/cpuinfo describes the lowest common denominator of
49+
RISC-V ISA extensions recognized by the kernel and implemented on all harts. The
50+
"hart isa" line, in contrast, describes the set of extensions recognized by the
51+
kernel on the particular hart being described, even if those extensions may not
52+
be present on all harts in the system.
53+
54+
In both lines, the presence of an extension guarantees only that the hardware
55+
has the described capability. Additional kernel support or policy changes may be
56+
required before an extension's capability is fully usable by userspace programs.
57+
Similarly, for S-mode extensions, presence in one of these lines does not
58+
guarantee that the kernel is taking advantage of the extension, or that the
59+
feature will be visible in guest VMs managed by this kernel.
60+
61+
Inversely, the absence of an extension in these lines does not necessarily mean
62+
the hardware does not support that feature. The running kernel may not recognize
63+
the extension, or may have deliberately removed it from the listing.
64+
4565
Misaligned accesses
4666
-------------------
4767

arch/riscv/kernel/cpu.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,17 +202,16 @@ arch_initcall(riscv_cpuinfo_init);
202202

203203
#ifdef CONFIG_PROC_FS
204204

205-
static void print_isa(struct seq_file *f)
205+
static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap)
206206
{
207-
seq_puts(f, "isa\t\t: ");
208207

209208
if (IS_ENABLED(CONFIG_32BIT))
210209
seq_write(f, "rv32", 4);
211210
else
212211
seq_write(f, "rv64", 4);
213212

214213
for (int i = 0; i < riscv_isa_ext_count; i++) {
215-
if (!__riscv_isa_extension_available(NULL, riscv_isa_ext[i].id))
214+
if (!__riscv_isa_extension_available(isa_bitmap, riscv_isa_ext[i].id))
216215
continue;
217216

218217
/* Only multi-letter extensions are split by underscores */
@@ -276,7 +275,15 @@ static int c_show(struct seq_file *m, void *v)
276275

277276
seq_printf(m, "processor\t: %lu\n", cpu_id);
278277
seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
279-
print_isa(m);
278+
279+
/*
280+
* For historical raisins, the isa: line is limited to the lowest common
281+
* denominator of extensions supported across all harts. A true list of
282+
* extensions supported on this hart is printed later in the hart isa:
283+
* line.
284+
*/
285+
seq_puts(m, "isa\t\t: ");
286+
print_isa(m, NULL);
280287
print_mmu(m);
281288

282289
if (acpi_disabled) {
@@ -292,6 +299,13 @@ static int c_show(struct seq_file *m, void *v)
292299
seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
293300
seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
294301
seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
302+
303+
/*
304+
* Print the ISA extensions specific to this hart, which may show
305+
* additional extensions not present across all harts.
306+
*/
307+
seq_puts(m, "hart isa\t: ");
308+
print_isa(m, hart_isa[cpu_id].isa);
295309
seq_puts(m, "\n");
296310

297311
return 0;

0 commit comments

Comments
 (0)