Merge patch series "riscv: Extension parsing fixes"

Charlie Jenkins <charlie@rivosinc.com> says:

This series contains two minor fixes for the extension parsing in
cpufeature.c.

Some T-Head boards without vector 1.0 support report "v" in the isa
string in their DT which will cause the kernel to run vector code. The
code to blacklist "v" from these boards was doing so by using
riscv_cached_mvendorid() which has not been populated at the time of
extension parsing. This fix instead greedily reads the mvendorid CSR of
the boot hart to determine if the cpu is from T-Head.

The other fix is for an incorrect indexing bug. riscv extensions
sometimes imply other extensions. When adding these "subset" extensions
to the hardware capabilities array, they need to be checked if they are
valid. The current code only checks if the extension that is including
other extensions is valid and not the subset extensions.

These patches were previously included in:
https://lore.kernel.org/lkml/20240420-dev-charlie-support_thead_vector_6_9-v3-0-67cff4271d1d@rivosinc.com/

* b4-shazam-merge:
  riscv: cpufeature: Fix extension subset checking
  riscv: cpufeature: Fix thead vector hwcap removal

Link: https://lore.kernel.org/r/20240502-cpufeature_fixes-v4-0-b3d1a088722d@rivosinc.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Palmer Dabbelt 2024-05-22 09:41:05 -07:00
commit c6c901b7d9
No known key found for this signature in database
GPG key ID: 2E1319F35FBB1889
3 changed files with 45 additions and 7 deletions

View file

@ -382,6 +382,8 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
static inline void sbi_init(void) {} static inline void sbi_init(void) {}
#endif /* CONFIG_RISCV_SBI */ #endif /* CONFIG_RISCV_SBI */
unsigned long riscv_get_mvendorid(void);
unsigned long riscv_get_marchid(void);
unsigned long riscv_cached_mvendorid(unsigned int cpu_id); unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
unsigned long riscv_cached_marchid(unsigned int cpu_id); unsigned long riscv_cached_marchid(unsigned int cpu_id);
unsigned long riscv_cached_mimpid(unsigned int cpu_id); unsigned long riscv_cached_mimpid(unsigned int cpu_id);

View file

@ -139,6 +139,34 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
return -1; return -1;
} }
unsigned long __init riscv_get_marchid(void)
{
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
#if IS_ENABLED(CONFIG_RISCV_SBI)
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
ci->marchid = csr_read(CSR_MARCHID);
#else
ci->marchid = 0;
#endif
return ci->marchid;
}
unsigned long __init riscv_get_mvendorid(void)
{
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();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
ci->mvendorid = csr_read(CSR_MVENDORID);
#else
ci->mvendorid = 0;
#endif
return ci->mvendorid;
}
DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo); DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
unsigned long riscv_cached_mvendorid(unsigned int cpu_id) unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
@ -170,12 +198,16 @@ static int riscv_cpuinfo_starting(unsigned int cpu)
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo); struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
#if IS_ENABLED(CONFIG_RISCV_SBI) #if IS_ENABLED(CONFIG_RISCV_SBI)
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid(); if (!ci->mvendorid)
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid(); ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
if (!ci->marchid)
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid(); ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
#elif IS_ENABLED(CONFIG_RISCV_M_MODE) #elif IS_ENABLED(CONFIG_RISCV_M_MODE)
ci->mvendorid = csr_read(CSR_MVENDORID); if (!ci->mvendorid)
ci->marchid = csr_read(CSR_MARCHID); ci->mvendorid = csr_read(CSR_MVENDORID);
if (!ci->marchid)
ci->marchid = csr_read(CSR_MARCHID);
ci->mimpid = csr_read(CSR_MIMPID); ci->mimpid = csr_read(CSR_MIMPID);
#else #else
ci->mvendorid = 0; ci->mvendorid = 0;

View file

@ -490,6 +490,8 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
struct acpi_table_header *rhct; struct acpi_table_header *rhct;
acpi_status status; acpi_status status;
unsigned int cpu; unsigned int cpu;
u64 boot_vendorid;
u64 boot_archid;
if (!acpi_disabled) { if (!acpi_disabled) {
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct); status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
@ -497,6 +499,9 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
return; return;
} }
boot_vendorid = riscv_get_mvendorid();
boot_archid = riscv_get_marchid();
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
struct riscv_isainfo *isainfo = &hart_isa[cpu]; struct riscv_isainfo *isainfo = &hart_isa[cpu];
unsigned long this_hwcap = 0; unsigned long this_hwcap = 0;
@ -544,8 +549,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
* CPU cores with the ratified spec will contain non-zero * CPU cores with the ratified spec will contain non-zero
* marchid. * marchid.
*/ */
if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID && if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
riscv_cached_marchid(cpu) == 0x0) {
this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v]; this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
clear_bit(RISCV_ISA_EXT_v, isainfo->isa); clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
} }
@ -599,7 +603,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
if (ext->subset_ext_size) { if (ext->subset_ext_size) {
for (int j = 0; j < ext->subset_ext_size; j++) { for (int j = 0; j < ext->subset_ext_size; j++) {
if (riscv_isa_extension_check(ext->subset_ext_ids[i])) if (riscv_isa_extension_check(ext->subset_ext_ids[j]))
set_bit(ext->subset_ext_ids[j], isainfo->isa); set_bit(ext->subset_ext_ids[j], isainfo->isa);
} }
} }