diff mbox series

[1/4] RISC-V: use bit-values instead of numbers to identify patched cpu-features

Message ID 20230113212351.3534769-2-heiko@sntech.de (mailing list archive)
State Deferred, archived
Delegated to: Palmer Dabbelt
Headers show
Series Zbb + fast-unaligned string optimization | expand

Checks

Context Check Description
conchuod/tree_selection fail Failed to apply to next/pending-fixes or riscv/for-next

Commit Message

Heiko Stuebner Jan. 13, 2023, 9:23 p.m. UTC
From: Heiko Stuebner <heiko.stuebner@vrull.eu>

RISC-V cpufeatures are often based on available extensions and maybe even
some combination of them. Using a bitfield for the errata-id gives us a
simple way to also require a combination of extensions for a specific
alternative patch.

Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
---
 arch/riscv/include/asm/errata_list.h |  6 +++---
 arch/riscv/kernel/cpufeature.c       | 12 +++++-------
 2 files changed, 8 insertions(+), 10 deletions(-)

Comments

Conor Dooley Jan. 14, 2023, 5:54 p.m. UTC | #1
On Fri, Jan 13, 2023 at 10:23:48PM +0100, Heiko Stuebner wrote:
> From: Heiko Stuebner <heiko.stuebner@vrull.eu>
> 
> RISC-V cpufeatures are often based on available extensions and maybe even
> some combination of them. Using a bitfield for the errata-id gives us a
> simple way to also require a combination of extensions for a specific
> alternative patch.
> 
> Signed-off-by: Heiko Stuebner <heiko.stuebner@vrull.eu>
> ---

> diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
> index 7bfc6eb9a5cf..8c83bd9d0e22 100644
> --- a/arch/riscv/kernel/cpufeature.c
> +++ b/arch/riscv/kernel/cpufeature.c
> @@ -350,13 +350,13 @@ 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);
> +		cpu_req_feature |= CPUFEATURE_SVPBMT;
>  
>  	if (cpufeature_probe_zicbom(stage))
> -		cpu_req_feature |= BIT(CPUFEATURE_ZICBOM);
> +		cpu_req_feature |= CPUFEATURE_ZICBOM;

I know the behaviour isn't changing here, but using a bit per feature
seems like scarily few, especially if people come along with variants
they want for all the various dinky extensions that exit.
Probably gonna need an iteration on this stuff in the not-too-distant
future...
diff mbox series

Patch

diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index 95e626b7281e..40c9e9c3295b 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -22,9 +22,9 @@ 
 #define	ERRATA_THEAD_NUMBER 3
 #endif
 
-#define	CPUFEATURE_SVPBMT 0
-#define	CPUFEATURE_ZICBOM 1
-#define	CPUFEATURE_ZBB 2
+#define	CPUFEATURE_SVPBMT 	(1 << 0)
+#define	CPUFEATURE_ZICBOM	(1 << 1)
+#define	CPUFEATURE_ZBB		(1 << 2)
 #define	CPUFEATURE_NUMBER 3
 
 #ifdef __ASSEMBLY__
diff --git a/arch/riscv/kernel/cpufeature.c b/arch/riscv/kernel/cpufeature.c
index 7bfc6eb9a5cf..8c83bd9d0e22 100644
--- a/arch/riscv/kernel/cpufeature.c
+++ b/arch/riscv/kernel/cpufeature.c
@@ -350,13 +350,13 @@  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);
+		cpu_req_feature |= CPUFEATURE_SVPBMT;
 
 	if (cpufeature_probe_zicbom(stage))
-		cpu_req_feature |= BIT(CPUFEATURE_ZICBOM);
+		cpu_req_feature |= CPUFEATURE_ZICBOM;
 
 	if (cpufeature_probe_zbb(stage))
-		cpu_req_feature |= BIT(CPUFEATURE_ZBB);
+		cpu_req_feature |= CPUFEATURE_ZBB;
 
 	return cpu_req_feature;
 }
@@ -367,19 +367,17 @@  void __init_or_module riscv_cpufeature_patch_func(struct alt_entry *begin,
 {
 	u32 cpu_req_feature = cpufeature_probe(stage);
 	struct alt_entry *alt;
-	u32 tmp;
 
 	for (alt = begin; alt < end; alt++) {
 		if (alt->vendor_id != 0)
 			continue;
-		if (alt->errata_id >= CPUFEATURE_NUMBER) {
+		if (alt->errata_id & GENMASK(31, CPUFEATURE_NUMBER)) {
 			WARN(1, "This feature id:%d is not in kernel cpufeature list",
 				alt->errata_id);
 			continue;
 		}
 
-		tmp = (1U << alt->errata_id);
-		if (cpu_req_feature & tmp) {
+		if ((cpu_req_feature & alt->errata_id) == alt->errata_id) {
 			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);