Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

riscv: integrate alternatives better into the main architecture

Right now the alternatives need to be explicitly enabled and
erratas are limited to SiFive ones.

We want to use alternatives not only for patching soc erratas,
but in the future also for handling different behaviour depending
on the existence of future extensions.

So move the core alternatives over to the kernel subdirectory
and move the CONFIG_RISCV_ALTERNATIVE to be a hidden symbol
which we expect relevant erratas and extensions to just select
if needed.

Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Philipp Tomsich <philipp.tomsich@vrull.eu>
Link: https://lore.kernel.org/r/20220511192921.2223629-2-heiko@sntech.de
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>

authored by

Heiko Stuebner and committed by
Palmer Dabbelt
e64f737a 31231092

+26 -20
+9
arch/riscv/Kconfig
··· 324 324 Specify the maximum number of NUMA Nodes available on the target 325 325 system. Increases memory reserved to accommodate various tables. 326 326 327 + config RISCV_ALTERNATIVE 328 + bool 329 + depends on !XIP_KERNEL 330 + help 331 + This Kconfig allows the kernel to automatically patch the 332 + errata required by the execution platform at run time. The 333 + code patching is performed once in the boot stages. It means 334 + that the overhead from this mechanism is just taken once. 335 + 327 336 config RISCV_ISA_C 328 337 bool "Emit compressed instructions when building Linux" 329 338 default y
+2 -11
arch/riscv/Kconfig.erratas
··· 1 1 menu "CPU errata selection" 2 2 3 - config RISCV_ERRATA_ALTERNATIVE 4 - bool "RISC-V alternative scheme" 5 - depends on !XIP_KERNEL 6 - default y 7 - help 8 - This Kconfig allows the kernel to automatically patch the 9 - errata required by the execution platform at run time. The 10 - code patching is performed once in the boot stages. It means 11 - that the overhead from this mechanism is just taken once. 12 - 13 3 config ERRATA_SIFIVE 14 4 bool "SiFive errata" 15 - depends on RISCV_ERRATA_ALTERNATIVE 5 + depends on !XIP_KERNEL 6 + select RISCV_ALTERNATIVE 16 7 help 17 8 All SiFive errata Kconfig depend on this Kconfig. Disabling 18 9 this Kconfig will disable all SiFive errata. Please say "Y"
-1
arch/riscv/Kconfig.socs
··· 14 14 select CLK_SIFIVE 15 15 select CLK_SIFIVE_PRCI 16 16 select SIFIVE_PLIC 17 - select RISCV_ERRATA_ALTERNATIVE if !XIP_KERNEL 18 17 select ERRATA_SIFIVE if !XIP_KERNEL 19 18 help 20 19 This enables support for SiFive SoC platform hardware.
+1 -1
arch/riscv/Makefile
··· 103 103 104 104 head-y := arch/riscv/kernel/head.o 105 105 106 - core-$(CONFIG_RISCV_ERRATA_ALTERNATIVE) += arch/riscv/errata/ 106 + core-y += arch/riscv/errata/ 107 107 core-$(CONFIG_KVM) += arch/riscv/kvm/ 108 108 109 109 libs-y += arch/riscv/lib/
-1
arch/riscv/errata/Makefile
··· 1 - obj-y += alternative.o 2 1 obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
arch/riscv/errata/alternative.c arch/riscv/kernel/alternative.c
+4 -3
arch/riscv/include/asm/alternative-macros.h
··· 2 2 #ifndef __ASM_ALTERNATIVE_MACROS_H 3 3 #define __ASM_ALTERNATIVE_MACROS_H 4 4 5 - #ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE 5 + #ifdef CONFIG_RISCV_ALTERNATIVE 6 6 7 7 #ifdef __ASSEMBLY__ 8 8 ··· 76 76 77 77 #endif /* __ASSEMBLY__ */ 78 78 79 - #else /* !CONFIG_RISCV_ERRATA_ALTERNATIVE*/ 79 + #else /* CONFIG_RISCV_ALTERNATIVE */ 80 80 #ifdef __ASSEMBLY__ 81 81 82 82 .macro __ALTERNATIVE_CFG old_c ··· 95 95 __ALTERNATIVE_CFG(old_c) 96 96 97 97 #endif /* __ASSEMBLY__ */ 98 - #endif /* CONFIG_RISCV_ERRATA_ALTERNATIVE */ 98 + #endif /* CONFIG_RISCV_ALTERNATIVE */ 99 + 99 100 /* 100 101 * Usage: 101 102 * ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k)
+8
arch/riscv/include/asm/alternative.h
··· 12 12 13 13 #ifndef __ASSEMBLY__ 14 14 15 + #ifdef CONFIG_RISCV_ALTERNATIVE 16 + 15 17 #include <linux/init.h> 16 18 #include <linux/types.h> 17 19 #include <linux/stddef.h> ··· 36 34 37 35 void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, 38 36 unsigned long archid, unsigned long impid); 37 + 38 + #else /* CONFIG_RISCV_ALTERNATIVE */ 39 + 40 + static inline void apply_boot_alternatives(void) { } 41 + 42 + #endif /* CONFIG_RISCV_ALTERNATIVE */ 39 43 40 44 #endif 41 45 #endif
+1
arch/riscv/kernel/Makefile
··· 18 18 extra-y += vmlinux.lds 19 19 20 20 obj-y += soc.o 21 + obj-$(CONFIG_RISCV_ALTERNATIVE) += alternative.o 21 22 obj-y += cpu.o 22 23 obj-y += cpufeature.o 23 24 obj-y += entry.o
-2
arch/riscv/kernel/smpboot.c
··· 41 41 void __init smp_prepare_boot_cpu(void) 42 42 { 43 43 init_cpu_topology(); 44 - #ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE 45 44 apply_boot_alternatives(); 46 - #endif 47 45 } 48 46 49 47 void __init smp_prepare_cpus(unsigned int max_cpus)
+1 -1
arch/riscv/kernel/traps.c
··· 86 86 } 87 87 } 88 88 89 - #if defined (CONFIG_XIP_KERNEL) && defined (CONFIG_RISCV_ERRATA_ALTERNATIVE) 89 + #if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE) 90 90 #define __trap_section __section(".xip.traps") 91 91 #else 92 92 #define __trap_section