riscv: cpufeature: extend riscv_cpufeature_patch_func to all ISA extensions

riscv_cpufeature_patch_func() currently only scans a limited set of
cpufeatures, explicitly defined with macros. Extend it to probe for all
ISA extensions.

Signed-off-by: Jisheng Zhang <jszhang@kernel.org>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Link: https://lore.kernel.org/r/20230128172856.3814-5-jszhang@kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
This commit is contained in:
Jisheng Zhang 2023-01-29 01:28:47 +08:00 committed by Palmer Dabbelt
parent d8a3d8a752
commit 4bf8860760
No known key found for this signature in database
GPG key ID: 2E1319F35FBB1889
2 changed files with 11 additions and 62 deletions

View file

@ -7,6 +7,7 @@
#include <asm/alternative.h>
#include <asm/csr.h>
#include <asm/hwcap.h>
#include <asm/vendorid_list.h>
#ifdef CONFIG_ERRATA_SIFIVE
@ -22,10 +23,6 @@
#define ERRATA_THEAD_NUMBER 3
#endif
#define CPUFEATURE_SVPBMT 0
#define CPUFEATURE_ZICBOM 1
#define CPUFEATURE_NUMBER 2
#ifdef __ASSEMBLY__
#define ALT_INSN_FAULT(x) \
@ -55,7 +52,7 @@ asm(ALTERNATIVE("sfence.vma %0", "sfence.vma", SIFIVE_VENDOR_ID, \
#define ALT_SVPBMT(_val, prot) \
asm(ALTERNATIVE_2("li %0, 0\t\nnop", \
"li %0, %1\t\nslli %0,%0,%3", 0, \
CPUFEATURE_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
RISCV_ISA_EXT_SVPBMT, CONFIG_RISCV_ISA_SVPBMT, \
"li %0, %2\t\nslli %0,%0,%4", THEAD_VENDOR_ID, \
ERRATA_THEAD_PBMT, CONFIG_ERRATA_THEAD_PBMT) \
: "=r"(_val) \
@ -129,7 +126,7 @@ asm volatile(ALTERNATIVE_2( \
"add a0, a0, %0\n\t" \
"2:\n\t" \
"bltu a0, %2, 3b\n\t" \
"nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
"nop", 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
"mv a0, %1\n\t" \
"j 2f\n\t" \
"3:\n\t" \

View file

@ -276,59 +276,11 @@ void __init riscv_fill_hwcap(void)
}
#ifdef CONFIG_RISCV_ALTERNATIVE
static bool __init_or_module cpufeature_probe_svpbmt(unsigned int stage)
{
if (!IS_ENABLED(CONFIG_RISCV_ISA_SVPBMT))
return false;
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
return false;
return riscv_isa_extension_available(NULL, SVPBMT);
}
static bool __init_or_module cpufeature_probe_zicbom(unsigned int stage)
{
if (!IS_ENABLED(CONFIG_RISCV_ISA_ZICBOM))
return false;
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
return false;
if (!riscv_isa_extension_available(NULL, ZICBOM))
return false;
return true;
}
/*
* Probe presence of individual extensions.
*
* This code may also be executed before kernel relocation, so we cannot use
* addresses generated by the address-of operator as they won't be valid in
* this context.
* Tests, unless otherwise required, are to be added in alphabetical order.
*/
static u32 __init_or_module cpufeature_probe(unsigned int stage)
{
u32 cpu_req_feature = 0;
if (cpufeature_probe_svpbmt(stage))
cpu_req_feature |= BIT(CPUFEATURE_SVPBMT);
if (cpufeature_probe_zicbom(stage))
cpu_req_feature |= BIT(CPUFEATURE_ZICBOM);
return cpu_req_feature;
}
void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
struct alt_entry *end,
unsigned int stage)
{
u32 cpu_req_feature = cpufeature_probe(stage);
struct alt_entry *alt;
u32 tmp;
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
return;
@ -336,18 +288,18 @@ void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
for (alt = begin; alt < end; alt++) {
if (alt->vendor_id != 0)
continue;
if (alt->errata_id >= CPUFEATURE_NUMBER) {
WARN(1, "This feature id:%d is not in kernel cpufeature list",
if (alt->errata_id >= RISCV_ISA_EXT_MAX) {
WARN(1, "This extension id:%d is not in ISA extension list",
alt->errata_id);
continue;
}
tmp = (1U << alt->errata_id);
if (cpu_req_feature & tmp) {
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
riscv_alternative_fix_offsets(alt->old_ptr, alt->alt_len,
alt->old_ptr - alt->alt_ptr);
}
if (!__riscv_isa_extension_available(NULL, alt->errata_id))
continue;
patch_text_nosync(alt->old_ptr, alt->alt_ptr, alt->alt_len);
riscv_alternative_fix_offsets(alt->old_ptr, alt->alt_len,
alt->old_ptr - alt->alt_ptr);
}
}
#endif