riscv: allow different stages with alternatives

A patch from »SVPBMT + T-Head memory types next try« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko@...> Date: Fri, 17 Dec 2021 00:08:35 +0100

Commit-Message

Future features may need to be applied at a different time during boot, so allow defining stages for alternatives and handling them differently depending on the stage. Signed-off-by: Heiko Stuebner <heiko@...>

Patch-Comment

arch/riscv/errata/sifive/errata.c | 3 ++- arch/riscv/include/asm/alternative.h | 5 ++++- arch/riscv/kernel/alternative.c | 22 ++++++++++++++-------- 3 files changed, 20 insertions(+), 10 deletions(-)

Statistics

  • 20 lines added
  • 10 lines removed

Changes

---------------------- arch/riscv/errata/sifive/errata.c -----------------------
index f5e5ae70e829..4fe03ac41fd7 100644
@@ -80,7 +80,8 @@ static void __init warn_miss_errata(u32 miss_errata)
}
void __init sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
- unsigned long archid, unsigned long impid)
+ unsigned long archid, unsigned long impid,
+ unsigned int stage)
{
struct alt_entry *alt;
u32 cpu_req_errata = sifive_errata_probe(archid, impid);
--------------------- arch/riscv/include/asm/alternative.h ---------------------
index e625d3cafbed..811bdd8027db 100644
@@ -17,6 +17,8 @@
#include <linux/stddef.h>
#include <asm/hwcap.h>
+#define RISCV_ALTERNATIVES_BOOT 0 /* alternatives applied during regular boot */
+
void __init apply_boot_alternatives(void);
struct alt_entry {
@@ -33,7 +35,8 @@ struct errata_checkfunc_id {
};
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
- unsigned long archid, unsigned long impid);
+ unsigned long archid, unsigned long impid,
+ unsigned int stage);
#endif
#endif
----------------------- arch/riscv/kernel/alternative.c ------------------------
index 3b15885db70b..416e7a380ee4 100644
@@ -22,7 +22,8 @@ static struct cpu_manufacturer_info_t {
} cpu_mfr_info;
static void (*vendor_patch_func)(struct alt_entry *begin, struct alt_entry *end,
- unsigned long archid, unsigned long impid);
+ unsigned long archid, unsigned long impid,
+ unsigned int stage);
static inline void __init riscv_fill_cpu_mfr_info(void)
{
@@ -57,18 +58,23 @@ static void __init init_alternative(void)
* a feature detect on the boot CPU). No need to worry about other CPUs
* here.
*/
-void __init apply_boot_alternatives(void)
+static void __init _apply_alternatives(unsigned int stage)
{
- /* If called on non-boot cpu things could go wrong */
- WARN_ON(smp_processor_id() != 0);
-
- init_alternative();
-
if (!vendor_patch_func)
return;
vendor_patch_func((struct alt_entry *)__alt_start,
(struct alt_entry *)__alt_end,
- cpu_mfr_info.arch_id, cpu_mfr_info.imp_id);
+ cpu_mfr_info.arch_id, cpu_mfr_info.imp_id,
+ stage);
}
+void __init apply_boot_alternatives(void)
+{
+ /* If called on non-boot cpu things could go wrong */
+ WARN_ON(smp_processor_id() != 0);
+
+ init_alternative();
+
+ _apply_alternatives(RISCV_ALTERNATIVES_BOOT);
+}
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...