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>
This commit is contained in:
Heiko Stuebner 2022-05-11 21:29:10 +02:00 committed by Palmer Dabbelt
parent 3123109284
commit e64f737ad7
No known key found for this signature in database
GPG Key ID: EF4CA1502CCBAB41
11 changed files with 26 additions and 20 deletions

View File

@ -324,6 +324,15 @@ config NODES_SHIFT
Specify the maximum number of NUMA Nodes available on the target
system. Increases memory reserved to accommodate various tables.
config RISCV_ALTERNATIVE
bool
depends on !XIP_KERNEL
help
This Kconfig allows the kernel to automatically patch the
errata required by the execution platform at run time. The
code patching is performed once in the boot stages. It means
that the overhead from this mechanism is just taken once.
config RISCV_ISA_C
bool "Emit compressed instructions when building Linux"
default y

View File

@ -1,18 +1,9 @@
menu "CPU errata selection"
config RISCV_ERRATA_ALTERNATIVE
bool "RISC-V alternative scheme"
depends on !XIP_KERNEL
default y
help
This Kconfig allows the kernel to automatically patch the
errata required by the execution platform at run time. The
code patching is performed once in the boot stages. It means
that the overhead from this mechanism is just taken once.
config ERRATA_SIFIVE
bool "SiFive errata"
depends on RISCV_ERRATA_ALTERNATIVE
depends on !XIP_KERNEL
select RISCV_ALTERNATIVE
help
All SiFive errata Kconfig depend on this Kconfig. Disabling
this Kconfig will disable all SiFive errata. Please say "Y"

View File

@ -14,7 +14,6 @@ config SOC_SIFIVE
select CLK_SIFIVE
select CLK_SIFIVE_PRCI
select SIFIVE_PLIC
select RISCV_ERRATA_ALTERNATIVE if !XIP_KERNEL
select ERRATA_SIFIVE if !XIP_KERNEL
help
This enables support for SiFive SoC platform hardware.

View File

@ -103,7 +103,7 @@ endif
head-y := arch/riscv/kernel/head.o
core-$(CONFIG_RISCV_ERRATA_ALTERNATIVE) += arch/riscv/errata/
core-y += arch/riscv/errata/
core-$(CONFIG_KVM) += arch/riscv/kvm/
libs-y += arch/riscv/lib/

View File

@ -1,2 +1 @@
obj-y += alternative.o
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/

View File

@ -2,7 +2,7 @@
#ifndef __ASM_ALTERNATIVE_MACROS_H
#define __ASM_ALTERNATIVE_MACROS_H
#ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE
#ifdef CONFIG_RISCV_ALTERNATIVE
#ifdef __ASSEMBLY__
@ -76,7 +76,7 @@
#endif /* __ASSEMBLY__ */
#else /* !CONFIG_RISCV_ERRATA_ALTERNATIVE*/
#else /* CONFIG_RISCV_ALTERNATIVE */
#ifdef __ASSEMBLY__
.macro __ALTERNATIVE_CFG old_c
@ -95,7 +95,8 @@
__ALTERNATIVE_CFG(old_c)
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_RISCV_ERRATA_ALTERNATIVE */
#endif /* CONFIG_RISCV_ALTERNATIVE */
/*
* Usage:
* ALTERNATIVE(old_content, new_content, vendor_id, errata_id, CONFIG_k)

View File

@ -12,6 +12,8 @@
#ifndef __ASSEMBLY__
#ifdef CONFIG_RISCV_ALTERNATIVE
#include <linux/init.h>
#include <linux/types.h>
#include <linux/stddef.h>
@ -35,5 +37,11 @@ struct errata_checkfunc_id {
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid);
#else /* CONFIG_RISCV_ALTERNATIVE */
static inline void apply_boot_alternatives(void) { }
#endif /* CONFIG_RISCV_ALTERNATIVE */
#endif
#endif

View File

@ -18,6 +18,7 @@ extra-y += head.o
extra-y += vmlinux.lds
obj-y += soc.o
obj-$(CONFIG_RISCV_ALTERNATIVE) += alternative.o
obj-y += cpu.o
obj-y += cpufeature.o
obj-y += entry.o

View File

@ -41,9 +41,7 @@ static DECLARE_COMPLETION(cpu_running);
void __init smp_prepare_boot_cpu(void)
{
init_cpu_topology();
#ifdef CONFIG_RISCV_ERRATA_ALTERNATIVE
apply_boot_alternatives();
#endif
}
void __init smp_prepare_cpus(unsigned int max_cpus)

View File

@ -86,7 +86,7 @@ static void do_trap_error(struct pt_regs *regs, int signo, int code,
}
}
#if defined (CONFIG_XIP_KERNEL) && defined (CONFIG_RISCV_ERRATA_ALTERNATIVE)
#if defined(CONFIG_XIP_KERNEL) && defined(CONFIG_RISCV_ALTERNATIVE)
#define __trap_section __section(".xip.traps")
#else
#define __trap_section