Commit d3d2cf1a authored by Evan Green's avatar Evan Green Committed by Palmer Dabbelt

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: default avatarEvan Green <evan@rivosinc.com>
Reviewed-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Reviewed-by: default avatarConor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231106232439.3176268-1-evan@rivosinc.comSigned-off-by: default avatarPalmer Dabbelt <palmer@rivosinc.com>
parent 28ea54ba
...@@ -42,6 +42,26 @@ An example string following the order is:: ...@@ -42,6 +42,26 @@ An example string following the order is::
rv64imadc_zifoo_zigoo_zafoo_sbar_scar_zxmbaz_xqux_xrux rv64imadc_zifoo_zigoo_zafoo_sbar_scar_zxmbaz_xqux_xrux
"isa" and "hart isa" lines in /proc/cpuinfo
-------------------------------------------
The "isa" line in /proc/cpuinfo describes the lowest common denominator of
RISC-V ISA extensions recognized by the kernel and implemented on all harts. The
"hart isa" line, in contrast, describes the set of extensions recognized by the
kernel on the particular hart being described, even if those extensions may not
be present on all harts in the system.
In both lines, the presence of an extension guarantees only that the hardware
has the described capability. Additional kernel support or policy changes may be
required before an extension's capability is fully usable by userspace programs.
Similarly, for S-mode extensions, presence in one of these lines does not
guarantee that the kernel is taking advantage of the extension, or that the
feature will be visible in guest VMs managed by this kernel.
Inversely, the absence of an extension in these lines does not necessarily mean
the hardware does not support that feature. The running kernel may not recognize
the extension, or may have deliberately removed it from the listing.
Misaligned accesses Misaligned accesses
------------------- -------------------
......
...@@ -202,9 +202,8 @@ arch_initcall(riscv_cpuinfo_init); ...@@ -202,9 +202,8 @@ arch_initcall(riscv_cpuinfo_init);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static void print_isa(struct seq_file *f) static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap)
{ {
seq_puts(f, "isa\t\t: ");
if (IS_ENABLED(CONFIG_32BIT)) if (IS_ENABLED(CONFIG_32BIT))
seq_write(f, "rv32", 4); seq_write(f, "rv32", 4);
...@@ -212,7 +211,7 @@ static void print_isa(struct seq_file *f) ...@@ -212,7 +211,7 @@ static void print_isa(struct seq_file *f)
seq_write(f, "rv64", 4); seq_write(f, "rv64", 4);
for (int i = 0; i < riscv_isa_ext_count; i++) { for (int i = 0; i < riscv_isa_ext_count; i++) {
if (!__riscv_isa_extension_available(NULL, riscv_isa_ext[i].id)) if (!__riscv_isa_extension_available(isa_bitmap, riscv_isa_ext[i].id))
continue; continue;
/* Only multi-letter extensions are split by underscores */ /* Only multi-letter extensions are split by underscores */
...@@ -276,7 +275,15 @@ static int c_show(struct seq_file *m, void *v) ...@@ -276,7 +275,15 @@ static int c_show(struct seq_file *m, void *v)
seq_printf(m, "processor\t: %lu\n", cpu_id); seq_printf(m, "processor\t: %lu\n", cpu_id);
seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id)); seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
print_isa(m);
/*
* For historical raisins, the isa: line is limited to the lowest common
* denominator of extensions supported across all harts. A true list of
* extensions supported on this hart is printed later in the hart isa:
* line.
*/
seq_puts(m, "isa\t\t: ");
print_isa(m, NULL);
print_mmu(m); print_mmu(m);
if (acpi_disabled) { if (acpi_disabled) {
...@@ -292,6 +299,13 @@ static int c_show(struct seq_file *m, void *v) ...@@ -292,6 +299,13 @@ static int c_show(struct seq_file *m, void *v)
seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid); seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid); seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid); seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
/*
* Print the ISA extensions specific to this hart, which may show
* additional extensions not present across all harts.
*/
seq_puts(m, "hart isa\t: ");
print_isa(m, hart_isa[cpu_id].isa);
seq_puts(m, "\n"); seq_puts(m, "\n");
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment