Skip to content

Commit 18f3fdb

Browse files
charlie-rivosgregkh
authored andcommitted
riscv: cpufeature: Fix thead vector hwcap removal
[ Upstream commit e482eab ] 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 <charlie@rivosinc.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Reviewed-by: Guo Ren <guoren@kernel.org> Link: https://lore.kernel.org/r/20240502-cpufeature_fixes-v4-1-b3d1a088722d@rivosinc.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 5915b89 commit 18f3fdb

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
@@ -327,6 +327,8 @@ static inline int sbi_remote_fence_i(const struct cpumask *cpu_mask) { return -1
327327
static inline void sbi_init(void) {}
328328
#endif /* CONFIG_RISCV_SBI */
329329

330+
unsigned long riscv_get_mvendorid(void);
331+
unsigned long riscv_get_marchid(void);
330332
unsigned long riscv_cached_mvendorid(unsigned int cpu_id);
331333
unsigned long riscv_cached_marchid(unsigned int cpu_id);
332334
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
@@ -351,13 +351,18 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
351351
struct acpi_table_header *rhct;
352352
acpi_status status;
353353
unsigned int cpu;
354+
u64 boot_vendorid;
355+
u64 boot_archid;
354356

355357
if (!acpi_disabled) {
356358
status = acpi_get_table(ACPI_SIG_RHCT, 0, &rhct);
357359
if (ACPI_FAILURE(status))
358360
return;
359361
}
360362

363+
boot_vendorid = riscv_get_mvendorid();
364+
boot_archid = riscv_get_marchid();
365+
361366
for_each_possible_cpu(cpu) {
362367
struct riscv_isainfo *isainfo = &hart_isa[cpu];
363368
unsigned long this_hwcap = 0;
@@ -405,8 +410,7 @@ static void __init riscv_fill_hwcap_from_isa_string(unsigned long *isa2hwcap)
405410
* CPU cores with the ratified spec will contain non-zero
406411
* marchid.
407412
*/
408-
if (acpi_disabled && riscv_cached_mvendorid(cpu) == THEAD_VENDOR_ID &&
409-
riscv_cached_marchid(cpu) == 0x0) {
413+
if (acpi_disabled && boot_vendorid == THEAD_VENDOR_ID && boot_archid == 0x0) {
410414
this_hwcap &= ~isa2hwcap[RISCV_ISA_EXT_v];
411415
clear_bit(RISCV_ISA_EXT_v, isainfo->isa);
412416
}

0 commit comments

Comments
 (0)