Skip to content

Commit e482eab

Browse files
charlie-rivospalmer-dabbelt
authored andcommitted
riscv: cpufeature: Fix thead vector hwcap removal
The riscv_cpuinfo struct that contains mvendorid and marchid is not populated until all harts are booted which happens after the DT parsing. Use the mvendorid/marchid from the boot hart to determine if the DT contains an invalid V. Fixes: d82f322 ("RISC-V: Ignore V from the riscv,isa DT property on older T-Head CPUs") Signed-off-by: Charlie Jenkins <[email protected]> Reviewed-by: Conor Dooley <[email protected]> Reviewed-by: Guo Ren <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 4cece76 commit e482eab

File tree

3 files changed

+44
-6
lines changed

3 files changed

+44
-6
lines changed

arch/riscv/include/asm/sbi.h

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

373+
unsigned long riscv_get_mvendorid(void);
374+
unsigned long riscv_get_marchid(void);
373375
unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
374376
unsigned long riscv_cached_marchid(unsigned int cpu_id);
375377
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: 6 additions & 2 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
}

0 commit comments

Comments
 (0)