2019-05-29 07:18:00 -07:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2017-07-10 18:00:26 -07:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2012 Regents of the University of California
|
|
|
|
*/
|
|
|
|
|
2023-05-15 11:19:22 +05:30
|
|
|
#include <linux/acpi.h>
|
2022-07-27 10:08:29 +05:30
|
|
|
#include <linux/cpu.h>
|
2023-05-02 00:17:38 +08:00
|
|
|
#include <linux/ctype.h>
|
2017-07-10 18:00:26 -07:00
|
|
|
#include <linux/init.h>
|
|
|
|
#include <linux/seq_file.h>
|
|
|
|
#include <linux/of.h>
|
2023-05-15 11:19:22 +05:30
|
|
|
#include <asm/acpi.h>
|
2023-04-07 16:10:58 -07:00
|
|
|
#include <asm/cpufeature.h>
|
2022-07-27 10:08:29 +05:30
|
|
|
#include <asm/csr.h>
|
2022-03-14 13:38:45 -07:00
|
|
|
#include <asm/hwcap.h>
|
2022-07-27 10:08:29 +05:30
|
|
|
#include <asm/sbi.h>
|
2018-10-02 12:15:05 -07:00
|
|
|
#include <asm/smp.h>
|
2021-12-06 11:46:52 +01:00
|
|
|
#include <asm/pgtable.h>
|
2017-07-10 18:00:26 -07:00
|
|
|
|
riscv: Fix CPU feature detection with SMP disabled
commit 914d6f44fc50 ("RISC-V: only iterate over possible CPUs in ISA
string parser") changed riscv_fill_hwcap() from iterating over CPU DT
nodes to iterating over logical CPU IDs. Since this function runs long
before cpu_dev_init() creates CPU devices, it hits the fallback path in
of_cpu_device_node_get(), which itself iterates over the DT nodes,
searching for a node with the requested CPU ID. (Incidentally, this
makes riscv_fill_hwcap() now take quadratic time.)
riscv_fill_hwcap() passes a logical CPU ID to of_cpu_device_node_get(),
which uses the arch_match_cpu_phys_id() hook to translate the logical ID
to a physical ID as found in the DT.
arch_match_cpu_phys_id() has a generic weak definition, and RISC-V
provides a strong definition using cpuid_to_hartid_map(). However, the
RISC-V specific implementation is located in arch/riscv/kernel/smp.c,
and that file is only compiled when SMP is enabled.
As a result, when SMP is disabled, the generic definition is used, and
riscv_isa gets initialized based on the ISA string of hart 0, not the
boot hart. On FU740, this means has_fpu() returns false, and userspace
crashes when trying to use floating-point instructions.
Fix this by moving arch_match_cpu_phys_id() to a file which is always
compiled.
Fixes: 70114560b285 ("RISC-V: Add RISC-V specific arch_match_cpu_phys_id")
Fixes: 914d6f44fc50 ("RISC-V: only iterate over possible CPUs in ISA string parser")
Reported-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230803012608.3540081-1-samuel.holland@sifive.com
Cc: stable@vger.kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-08-02 18:26:06 -07:00
|
|
|
bool arch_match_cpu_phys_id(int cpu, u64 phys_id)
|
|
|
|
{
|
|
|
|
return phys_id == cpuid_to_hartid_map(cpu);
|
|
|
|
}
|
|
|
|
|
2018-10-02 12:15:00 -07:00
|
|
|
/*
|
2019-01-18 15:03:06 +01:00
|
|
|
* Returns the hart ID of the given device tree node, or -ENODEV if the node
|
|
|
|
* isn't an enabled and valid RISC-V hart node.
|
2018-10-02 12:15:00 -07:00
|
|
|
*/
|
2022-05-27 10:47:42 +05:30
|
|
|
int riscv_of_processor_hartid(struct device_node *node, unsigned long *hart)
|
2023-06-07 21:28:26 +01:00
|
|
|
{
|
|
|
|
int cpu;
|
|
|
|
|
|
|
|
*hart = (unsigned long)of_get_cpu_hwid(node, 0);
|
|
|
|
if (*hart == ~0UL) {
|
|
|
|
pr_warn("Found CPU without hart ID\n");
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
cpu = riscv_hartid_to_cpuid(*hart);
|
|
|
|
if (cpu < 0)
|
|
|
|
return cpu;
|
|
|
|
|
|
|
|
if (!cpu_possible(cpu))
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-07-13 13:11:09 +01:00
|
|
|
int __init riscv_early_of_processor_hartid(struct device_node *node, unsigned long *hart)
|
2017-07-10 18:00:26 -07:00
|
|
|
{
|
2019-01-18 15:03:07 +01:00
|
|
|
const char *isa;
|
2017-07-10 18:00:26 -07:00
|
|
|
|
|
|
|
if (!of_device_is_compatible(node, "riscv")) {
|
|
|
|
pr_warn("Found incompatible CPU\n");
|
2019-01-18 15:03:06 +01:00
|
|
|
return -ENODEV;
|
2017-07-10 18:00:26 -07:00
|
|
|
}
|
|
|
|
|
2023-06-07 21:28:26 +01:00
|
|
|
*hart = (unsigned long)of_get_cpu_hwid(node, 0);
|
2022-05-27 10:47:42 +05:30
|
|
|
if (*hart == ~0UL) {
|
2017-07-10 18:00:26 -07:00
|
|
|
pr_warn("Found CPU without hart ID\n");
|
2019-01-18 15:03:06 +01:00
|
|
|
return -ENODEV;
|
2017-07-10 18:00:26 -07:00
|
|
|
}
|
|
|
|
|
2019-01-18 15:03:07 +01:00
|
|
|
if (!of_device_is_available(node)) {
|
2022-05-27 10:47:42 +05:30
|
|
|
pr_info("CPU with hartid=%lu is not available\n", *hart);
|
2019-01-18 15:03:06 +01:00
|
|
|
return -ENODEV;
|
2017-07-10 18:00:26 -07:00
|
|
|
}
|
|
|
|
|
2023-07-13 13:11:08 +01:00
|
|
|
if (of_property_read_string(node, "riscv,isa-base", &isa))
|
|
|
|
goto old_interface;
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_32BIT) && strncasecmp(isa, "rv32i", 5)) {
|
|
|
|
pr_warn("CPU with hartid=%lu does not support rv32i", *hart);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (IS_ENABLED(CONFIG_64BIT) && strncasecmp(isa, "rv64i", 5)) {
|
|
|
|
pr_warn("CPU with hartid=%lu does not support rv64i", *hart);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!of_property_present(node, "riscv,isa-extensions"))
|
|
|
|
return -ENODEV;
|
|
|
|
|
|
|
|
if (of_property_match_string(node, "riscv,isa-extensions", "i") < 0 ||
|
|
|
|
of_property_match_string(node, "riscv,isa-extensions", "m") < 0 ||
|
|
|
|
of_property_match_string(node, "riscv,isa-extensions", "a") < 0) {
|
|
|
|
pr_warn("CPU with hartid=%lu does not support ima", *hart);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
old_interface:
|
2023-07-13 13:11:09 +01:00
|
|
|
if (!riscv_isa_fallback) {
|
|
|
|
pr_warn("CPU with hartid=%lu is invalid: this kernel does not parse \"riscv,isa\"",
|
|
|
|
*hart);
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
|
2017-07-10 18:00:26 -07:00
|
|
|
if (of_property_read_string(node, "riscv,isa", &isa)) {
|
2023-07-13 13:11:08 +01:00
|
|
|
pr_warn("CPU with hartid=%lu has no \"riscv,isa-base\" or \"riscv,isa\" property\n",
|
|
|
|
*hart);
|
2019-01-18 15:03:06 +01:00
|
|
|
return -ENODEV;
|
2017-07-10 18:00:26 -07:00
|
|
|
}
|
2023-06-07 21:28:27 +01:00
|
|
|
|
2023-07-13 13:10:59 +01:00
|
|
|
if (IS_ENABLED(CONFIG_32BIT) && strncasecmp(isa, "rv32ima", 7)) {
|
|
|
|
pr_warn("CPU with hartid=%lu does not support rv32ima", *hart);
|
2023-06-07 21:28:27 +01:00
|
|
|
return -ENODEV;
|
2023-07-13 13:10:59 +01:00
|
|
|
}
|
2023-06-07 21:28:27 +01:00
|
|
|
|
2023-07-13 13:10:59 +01:00
|
|
|
if (IS_ENABLED(CONFIG_64BIT) && strncasecmp(isa, "rv64ima", 7)) {
|
|
|
|
pr_warn("CPU with hartid=%lu does not support rv64ima", *hart);
|
2019-01-18 15:03:06 +01:00
|
|
|
return -ENODEV;
|
2023-07-13 13:10:59 +01:00
|
|
|
}
|
2017-07-10 18:00:26 -07:00
|
|
|
|
2022-05-27 10:47:42 +05:30
|
|
|
return 0;
|
2017-07-10 18:00:26 -07:00
|
|
|
}
|
|
|
|
|
2020-06-01 14:45:39 +05:30
|
|
|
/*
|
|
|
|
* Find hart ID of the CPU DT node under which given DT node falls.
|
|
|
|
*
|
|
|
|
* To achieve this, we walk up the DT tree until we find an active
|
|
|
|
* RISC-V core (HART) node and extract the cpuid from it.
|
|
|
|
*/
|
2022-05-27 10:47:42 +05:30
|
|
|
int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
|
2020-06-01 14:45:39 +05:30
|
|
|
{
|
|
|
|
for (; node; node = node->parent) {
|
2022-05-27 10:47:42 +05:30
|
|
|
if (of_device_is_compatible(node, "riscv")) {
|
2023-10-27 21:12:53 +05:30
|
|
|
*hartid = (unsigned long)of_get_cpu_hwid(node, 0);
|
|
|
|
if (*hartid == ~0UL) {
|
|
|
|
pr_warn("Found CPU without hart ID\n");
|
|
|
|
return -ENODEV;
|
|
|
|
}
|
|
|
|
return 0;
|
2022-05-27 10:47:42 +05:30
|
|
|
}
|
2020-06-01 14:45:39 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2023-04-07 16:10:58 -07:00
|
|
|
DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
|
2022-07-27 10:08:29 +05:30
|
|
|
|
2022-10-12 01:18:40 +02:00
|
|
|
unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
|
|
|
|
{
|
|
|
|
struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
|
|
|
|
|
|
|
|
return ci->mvendorid;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(riscv_cached_mvendorid);
|
|
|
|
|
|
|
|
unsigned long riscv_cached_marchid(unsigned int cpu_id)
|
|
|
|
{
|
|
|
|
struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
|
|
|
|
|
|
|
|
return ci->marchid;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(riscv_cached_marchid);
|
|
|
|
|
|
|
|
unsigned long riscv_cached_mimpid(unsigned int cpu_id)
|
|
|
|
{
|
|
|
|
struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
|
|
|
|
|
|
|
|
return ci->mimpid;
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(riscv_cached_mimpid);
|
|
|
|
|
2022-07-27 10:08:29 +05:30
|
|
|
static int riscv_cpuinfo_starting(unsigned int cpu)
|
|
|
|
{
|
|
|
|
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
|
|
|
|
|
|
|
|
#if IS_ENABLED(CONFIG_RISCV_SBI)
|
|
|
|
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
|
|
|
|
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
|
|
|
|
ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
|
|
|
|
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
|
|
|
|
ci->mvendorid = csr_read(CSR_MVENDORID);
|
|
|
|
ci->marchid = csr_read(CSR_MARCHID);
|
|
|
|
ci->mimpid = csr_read(CSR_MIMPID);
|
|
|
|
#else
|
|
|
|
ci->mvendorid = 0;
|
|
|
|
ci->marchid = 0;
|
|
|
|
ci->mimpid = 0;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int __init riscv_cpuinfo_init(void)
|
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "riscv/cpuinfo:starting",
|
|
|
|
riscv_cpuinfo_starting, NULL);
|
|
|
|
if (ret < 0) {
|
|
|
|
pr_err("cpuinfo: failed to register hotplug callbacks.\n");
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2022-10-12 01:18:40 +02:00
|
|
|
arch_initcall(riscv_cpuinfo_init);
|
|
|
|
|
|
|
|
#ifdef CONFIG_PROC_FS
|
2022-07-27 10:08:29 +05:30
|
|
|
|
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 <evan@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231106232439.3176268-1-evan@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-11-06 15:24:39 -08:00
|
|
|
static void print_isa(struct seq_file *f, const unsigned long *isa_bitmap)
|
2022-03-14 13:38:45 -07:00
|
|
|
{
|
|
|
|
|
2023-07-13 13:11:00 +01:00
|
|
|
if (IS_ENABLED(CONFIG_32BIT))
|
|
|
|
seq_write(f, "rv32", 4);
|
|
|
|
else
|
|
|
|
seq_write(f, "rv64", 4);
|
2022-03-14 13:38:45 -07:00
|
|
|
|
2023-07-13 13:11:05 +01:00
|
|
|
for (int i = 0; i < riscv_isa_ext_count; i++) {
|
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 <evan@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231106232439.3176268-1-evan@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-11-06 15:24:39 -08:00
|
|
|
if (!__riscv_isa_extension_available(isa_bitmap, riscv_isa_ext[i].id))
|
2022-03-14 13:38:45 -07:00
|
|
|
continue;
|
|
|
|
|
2023-07-13 13:11:05 +01:00
|
|
|
/* Only multi-letter extensions are split by underscores */
|
|
|
|
if (strnlen(riscv_isa_ext[i].name, 2) != 1)
|
|
|
|
seq_puts(f, "_");
|
2017-07-10 18:00:26 -07:00
|
|
|
|
2023-07-13 13:11:05 +01:00
|
|
|
seq_printf(f, "%s", riscv_isa_ext[i].name);
|
2022-03-14 13:38:45 -07:00
|
|
|
}
|
2023-07-13 13:11:05 +01:00
|
|
|
|
2018-10-02 12:15:06 -07:00
|
|
|
seq_puts(f, "\n");
|
2018-10-02 12:14:56 -07:00
|
|
|
}
|
|
|
|
|
2021-12-06 11:46:52 +01:00
|
|
|
static void print_mmu(struct seq_file *f)
|
2018-10-02 12:14:56 -07:00
|
|
|
{
|
2023-08-02 00:21:58 +00:00
|
|
|
const char *sv_type;
|
2021-12-06 11:46:52 +01:00
|
|
|
|
2022-04-14 19:30:36 +02:00
|
|
|
#ifdef CONFIG_MMU
|
2018-10-02 12:14:56 -07:00
|
|
|
#if defined(CONFIG_32BIT)
|
2023-08-02 00:21:58 +00:00
|
|
|
sv_type = "sv32";
|
2018-10-02 12:14:56 -07:00
|
|
|
#elif defined(CONFIG_64BIT)
|
2022-01-27 10:48:43 +08:00
|
|
|
if (pgtable_l5_enabled)
|
2023-08-02 00:21:58 +00:00
|
|
|
sv_type = "sv57";
|
2022-01-27 10:48:43 +08:00
|
|
|
else if (pgtable_l4_enabled)
|
2023-08-02 00:21:58 +00:00
|
|
|
sv_type = "sv48";
|
2021-12-06 11:46:52 +01:00
|
|
|
else
|
2023-08-02 00:21:58 +00:00
|
|
|
sv_type = "sv39";
|
2018-10-02 12:14:56 -07:00
|
|
|
#endif
|
2022-04-14 19:30:36 +02:00
|
|
|
#else
|
2023-08-02 00:21:58 +00:00
|
|
|
sv_type = "none";
|
2022-04-14 19:30:36 +02:00
|
|
|
#endif /* CONFIG_MMU */
|
2021-12-06 11:46:52 +01:00
|
|
|
seq_printf(f, "mmu\t\t: %s\n", sv_type);
|
2018-10-02 12:14:56 -07:00
|
|
|
}
|
|
|
|
|
2017-07-10 18:00:26 -07:00
|
|
|
static void *c_start(struct seq_file *m, loff_t *pos)
|
|
|
|
{
|
2022-10-14 17:58:44 +02:00
|
|
|
if (*pos == nr_cpu_ids)
|
|
|
|
return NULL;
|
|
|
|
|
2017-07-10 18:00:26 -07:00
|
|
|
*pos = cpumask_next(*pos - 1, cpu_online_mask);
|
|
|
|
if ((*pos) < nr_cpu_ids)
|
|
|
|
return (void *)(uintptr_t)(1 + *pos);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *c_next(struct seq_file *m, void *v, loff_t *pos)
|
|
|
|
{
|
|
|
|
(*pos)++;
|
|
|
|
return c_start(m, pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void c_stop(struct seq_file *m, void *v)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static int c_show(struct seq_file *m, void *v)
|
|
|
|
{
|
2018-10-02 12:15:05 -07:00
|
|
|
unsigned long cpu_id = (unsigned long)v - 1;
|
2022-07-27 10:08:29 +05:30
|
|
|
struct riscv_cpuinfo *ci = per_cpu_ptr(&riscv_cpuinfo, cpu_id);
|
2023-05-15 11:19:22 +05:30
|
|
|
struct device_node *node;
|
2023-07-13 13:11:00 +01:00
|
|
|
const char *compat;
|
2017-07-10 18:00:26 -07:00
|
|
|
|
2018-10-02 12:15:06 -07:00
|
|
|
seq_printf(m, "processor\t: %lu\n", cpu_id);
|
|
|
|
seq_printf(m, "hart\t\t: %lu\n", cpuid_to_hartid_map(cpu_id));
|
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 <evan@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231106232439.3176268-1-evan@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-11-06 15:24:39 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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);
|
2023-07-13 13:11:00 +01:00
|
|
|
print_mmu(m);
|
2023-05-15 11:19:22 +05:30
|
|
|
|
|
|
|
if (acpi_disabled) {
|
|
|
|
node = of_get_cpu_node(cpu_id, NULL);
|
|
|
|
|
|
|
|
if (!of_property_read_string(node, "compatible", &compat) &&
|
|
|
|
strcmp(compat, "riscv"))
|
|
|
|
seq_printf(m, "uarch\t\t: %s\n", compat);
|
|
|
|
|
|
|
|
of_node_put(node);
|
|
|
|
}
|
|
|
|
|
2022-07-27 10:08:29 +05:30
|
|
|
seq_printf(m, "mvendorid\t: 0x%lx\n", ci->mvendorid);
|
|
|
|
seq_printf(m, "marchid\t\t: 0x%lx\n", ci->marchid);
|
|
|
|
seq_printf(m, "mimpid\t\t: 0x%lx\n", ci->mimpid);
|
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 <evan@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20231106232439.3176268-1-evan@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
2023-11-06 15:24:39 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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);
|
2017-07-10 18:00:26 -07:00
|
|
|
seq_puts(m, "\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct seq_operations cpuinfo_op = {
|
|
|
|
.start = c_start,
|
|
|
|
.next = c_next,
|
|
|
|
.stop = c_stop,
|
|
|
|
.show = c_show
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* CONFIG_PROC_FS */
|