Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit c6c901b

Browse files
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>
2 parents 9d5328e + e67e98e commit c6c901b

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

arch/riscv/include/asm/sbi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,8 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
382382
static inline void sbi_init(void) {}
383383
#endif /* CONFIG_RISCV_SBI */
384384

385+
unsigned long riscv_get_mvendorid(void);
386+
unsigned long riscv_get_marchid(void);
385387
unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
386388
unsigned long riscv_cached_marchid(unsigned int cpu_id);
387389
unsigned long riscv_cached_mimpid(unsigned int cpu_id);

arch/riscv/kernel/cpu.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,34 @@ int riscv_of_parent_hartid(struct device_node *node, unsigned long *hartid)
139139
return -1;
140140
}
141141

142+
unsigned long __init riscv_get_marchid(void)
143+
{
144+
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
145+
146+
#if IS_ENABLED(CONFIG_RISCV_SBI)
147+
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
148+
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
149+
ci->marchid = csr_read(CSR_MARCHID);
150+
#else
151+
ci->marchid = 0;
152+
#endif
153+
return ci->marchid;
154+
}
155+
156+
unsigned long __init riscv_get_mvendorid(void)
157+
{
158+
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
159+
160+
#if IS_ENABLED(CONFIG_RISCV_SBI)
161+
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
162+
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
163+
ci->mvendorid = csr_read(CSR_MVENDORID);
164+
#else
165+
ci->mvendorid = 0;
166+
#endif
167+
return ci->mvendorid;
168+
}
169+
142170
DEFINE_PER_CPU(struct riscv_cpuinfo, riscv_cpuinfo);
143171

144172
unsigned long riscv_cached_mvendorid(unsigned int cpu_id)
@@ -170,12 +198,16 @@ static int riscv_cpuinfo_starting(unsigned int cpu)
170198
struct riscv_cpuinfo *ci = this_cpu_ptr(&riscv_cpuinfo);
171199

172200
#if IS_ENABLED(CONFIG_RISCV_SBI)
173-
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
174-
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
201+
if (!ci->mvendorid)
202+
ci->mvendorid = sbi_spec_is_0_1() ? 0 : sbi_get_mvendorid();
203+
if (!ci->marchid)
204+
ci->marchid = sbi_spec_is_0_1() ? 0 : sbi_get_marchid();
175205
ci->mimpid = sbi_spec_is_0_1() ? 0 : sbi_get_mimpid();
176206
#elif IS_ENABLED(CONFIG_RISCV_M_MODE)
177-
ci->mvendorid = csr_read(CSR_MVENDORID);
178-
ci->marchid = csr_read(CSR_MARCHID);
207+
if (!ci->mvendorid)
208+
ci->mvendorid = csr_read(CSR_MVENDORID);
209+
if (!ci->marchid)
210+
ci->marchid = csr_read(CSR_MARCHID);
179211
ci->mimpid = csr_read(CSR_MIMPID);
180212
#else
181213
ci->mvendorid = 0;

arch/riscv/kernel/cpufeature.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -490,13 +490,18 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
490490
struct acpi_table_header *rhct;
491491
acpi_status status;
492492
unsigned int cpu;
493+
u64 boot_vendorid;
494+
u64 boot_archid;
493495

494496
if (!acpi_disabled) {
495497
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
496498
if (ACPI_FAILURE(status))
497499
return;
498500
}
499501

502+
boot_vendorid = riscv_get_mvendorid();
503+
boot_archid = riscv_get_marchid();
504+
500505
for_each_possible_cpu(cpu) {
501506
struct riscv_isainfo *isainfo = &hart_isa[cpu];
502507
unsigned long this_hwcap = 0;
@@ -544,8 +549,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
544549
* CPU cores with the ratified spec will contain non-zero
545550
* marchid.
546551
*/
547-
if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
548-
riscv_cached_marchid(cpu) == 0x0) {
552+
if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
549553
this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
550554
clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
551555
}
@@ -599,7 +603,7 @@ static int __init riscv_fill_hwcap_from_ext_list(unsigned long *isa2hwcap)
599603

600604
if (ext->subset_ext_size) {
601605
for (int j = 0; j < ext->subset_ext_size; j++) {
602-
if (riscv_isa_extension_check(ext->subset_ext_ids[i]))
606+
if (riscv_isa_extension_check(ext->subset_ext_ids[j]))
603607
set_bit(ext->subset_ext_ids[j], isainfo->isa);
604608
}
605609
}

0 commit comments

Comments
 (0)