[PATCH] riscv: Add support for early boot errata application on MIPS chips
Aleksa Paunovic <[email protected]>
| Newsgroups | org.kernel.feeds.b4-sent,org.infradead.lists.linux-riscv,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
MIPS errata implementation previously skipped early boot application entirely. Although the only currently existing MIPS erratum does not require this, amending this now should make any future addition easier to implement. This commit was based on the existing T-Head implementation. Suggested-by: Jesse Taube <[email protected]> Link: https://lore.kernel.org/linux-riscv/CADRr4bcbD57hmR0XGgo8BjgNp4shEADOondZEtwscCJ9-nxXRQ@mail.gmail.com/ Signed-off-by: Aleksa Paunovic <[email protected]> --- The patch was motivated by Jesse's suggestion to implement [2] as an early boot erratum. However, since it's in conflict with [1] as well, I decided against sending this one and the ZALRSC patch as a series, opting for rebasing [1] and [2] once it's clear we should move forward with this approach. I tested this on an eight-hart QEMU config. The testing was done by rebasing [1] and [2] onto the patch and running most of the same tests used to verify those patches. This includes: coremark testing, futex kselftests and GDB to check errata application. The same tests were run on the Boston board, configured with a single P8700 core. Links: [1] https://lore.kernel.org/linux-riscv/[email protected]/ [2] https://lore.kernel.org/linux-riscv/[email protected]/ --- arch/riscv/Kconfig.errata | 1 + arch/riscv/errata/mips/Makefile | 6 ++++++ arch/riscv/errata/mips/errata.c | 38 +++++++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata index 3c945d086c7d0266b685f9506d58b0662af071c4..45f3a4a7c9e234e1dc95ff4595a91922ce6176d1 100644 --- a/arch/riscv/Kconfig.errata +++ b/arch/riscv/Kconfig.errata @@ -24,6 +24,7 @@ config ERRATA_ANDES_CMO config ERRATA_MIPS bool "MIPS errata" depends on RISCV_ALTERNATIVE + select RISCV_ALTERNATIVE_EARLY help All MIPS errata Kconfig depend on this Kconfig. Disabling this Kconfig will disable all MIPS errata. Please say "Y" diff --git a/arch/riscv/errata/mips/Makefile b/arch/riscv/errata/mips/Makefile index 6278c389b801ee6e54e808c80e6e236c026329c7..137e700d9d3f8ed79ac03f996934c54af99a56b3 100644 --- a/arch/riscv/errata/mips/Makefile +++ b/arch/riscv/errata/mips/Makefile @@ -1,5 +1,11 @@ ifdef CONFIG_RISCV_ALTERNATIVE_EARLY CFLAGS_errata.o := -mcmodel=medany +ifdef CONFIG_FTRACE +CFLAGS_REMOVE_errata.o = $(CC_FLAGS_FTRACE) +endif +ifdef CONFIG_KASAN +KASAN_SANITIZE_errata.o := n +endif endif obj-y += errata.o diff --git a/arch/riscv/errata/mips/errata.c b/arch/riscv/errata/mips/errata.c index 2c3dc2259e93e9e5181d60843e66da5625bda56f..ac9a12d0a30c9d2bf5d4920d5f6e9d2ed22fe0e5 100644 --- a/arch/riscv/errata/mips/errata.c +++ b/arch/riscv/errata/mips/errata.c @@ -7,12 +7,13 @@ #include <linux/module.h> #include <asm/text-patching.h> #include <asm/alternative.h> +#include <asm/cacheflush.h> #include <asm/errata_list.h> #include <asm/vendorid_list.h> #include <asm/vendor_extensions.h> #include <asm/vendor_extensions/mips.h> -static inline bool errata_probe_pause(void) +static inline bool errata_probe_pause(unsigned int stage) { if (!IS_ENABLED(CONFIG_ERRATA_MIPS_P8700_PAUSE_OPCODE)) return false; @@ -20,14 +21,17 @@ static inline bool errata_probe_pause(void) if (!riscv_isa_vendor_extension_available(MIPS_VENDOR_ID, XMIPSEXECTL)) return false; + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + return false; + return true; } -static u32 mips_errata_probe(void) +static u32 mips_errata_probe(unsigned int stage) { u32 cpu_req_errata = 0; - if (errata_probe_pause()) + if (errata_probe_pause(stage)) cpu_req_errata |= BIT(ERRATA_MIPS_P8700_PAUSE_OPCODE); return cpu_req_errata; @@ -38,30 +42,34 @@ void mips_errata_patch_func(struct alt_entry *begin, struct alt_entry *end, unsigned int stage) { struct alt_entry *alt; - u32 cpu_req_errata = mips_errata_probe(); + u32 cpu_req_errata = mips_errata_probe(stage); u32 tmp; + void *oldptr, *altptr; BUILD_BUG_ON(ERRATA_MIPS_NUMBER >= RISCV_VENDOR_EXT_ALTERNATIVES_BASE); - if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) - return; - for (alt = begin; alt < end; alt++) { if (alt->vendor_id != MIPS_VENDOR_ID) continue; - if (alt->patch_id >= ERRATA_MIPS_NUMBER) { - WARN(1, "MIPS errata id:%d not in kernel errata list\n", - alt->patch_id); + if (alt->patch_id >= ERRATA_MIPS_NUMBER) continue; - } tmp = (1U << alt->patch_id); if (cpu_req_errata & tmp) { - mutex_lock(&text_mutex); - patch_text_nosync(ALT_OLD_PTR(alt), ALT_ALT_PTR(alt), - alt->alt_len); - mutex_unlock(&text_mutex); + oldptr = ALT_OLD_PTR(alt); + altptr = ALT_ALT_PTR(alt); + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) { + memcpy(oldptr, altptr, alt->alt_len); + } else { + mutex_lock(&text_mutex); + patch_text_nosync(oldptr, altptr, alt->alt_len); + mutex_unlock(&text_mutex); + } } } + + if (stage == RISCV_ALTERNATIVES_EARLY_BOOT) + local_flush_icache_all(); } --- base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff change-id: 20260731-p8700-early-boot-64ee225e8a1c Best regards, -- Aleksa Paunovic <[email protected]>