Commit 676b2f99 authored by Nicholas Miehlbradt's avatar Nicholas Miehlbradt Committed by Michael Ellerman

powerpc: Add static_key_feature_checks_initialized flag

JUMP_LABEL_FEATURE_CHECK_DEBUG used static_key_intialized to determine
whether {cpu,mmu}_has_feature() is used before static keys were
initialized. However, {cpu,mmu}_has_feature() should not be used before
setup_feature_keys() is called but static_key_initialized is set well
before this by the call to jump_label_init() in early_init_devtree().
This creates a window in which JUMP_LABEL_FEATURE_CHECK_DEBUG will not
detect misuse and report errors. Add a flag specifically to indicate
when {cpu,mmu}_has_feature() is safe to use.
Signed-off-by: default avatarNicholas Miehlbradt <nicholas@linux.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/20240408052358.5030-1-nicholas@linux.ibm.com
parent 676abf7c
...@@ -29,7 +29,7 @@ static __always_inline bool cpu_has_feature(unsigned long feature) ...@@ -29,7 +29,7 @@ static __always_inline bool cpu_has_feature(unsigned long feature)
#endif #endif
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
if (!static_key_initialized) { if (!static_key_feature_checks_initialized) {
printk("Warning! cpu_has_feature() used prior to jump label init!\n"); printk("Warning! cpu_has_feature() used prior to jump label init!\n");
dump_stack(); dump_stack();
return early_cpu_has_feature(feature); return early_cpu_has_feature(feature);
......
...@@ -291,6 +291,8 @@ extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup; ...@@ -291,6 +291,8 @@ extern long __start___rfi_flush_fixup, __stop___rfi_flush_fixup;
extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup; extern long __start___barrier_nospec_fixup, __stop___barrier_nospec_fixup;
extern long __start__btb_flush_fixup, __stop__btb_flush_fixup; extern long __start__btb_flush_fixup, __stop__btb_flush_fixup;
extern bool static_key_feature_checks_initialized;
void apply_feature_fixups(void); void apply_feature_fixups(void);
void update_mmu_feature_fixups(unsigned long mask); void update_mmu_feature_fixups(unsigned long mask);
void setup_feature_keys(void); void setup_feature_keys(void);
......
...@@ -251,7 +251,7 @@ static __always_inline bool mmu_has_feature(unsigned long feature) ...@@ -251,7 +251,7 @@ static __always_inline bool mmu_has_feature(unsigned long feature)
#endif #endif
#ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG #ifdef CONFIG_JUMP_LABEL_FEATURE_CHECK_DEBUG
if (!static_key_initialized) { if (!static_key_feature_checks_initialized) {
printk("Warning! mmu_has_feature() used prior to jump label init!\n"); printk("Warning! mmu_has_feature() used prior to jump label init!\n");
dump_stack(); dump_stack();
return early_mmu_has_feature(feature); return early_mmu_has_feature(feature);
......
...@@ -25,6 +25,13 @@ ...@@ -25,6 +25,13 @@
#include <asm/firmware.h> #include <asm/firmware.h>
#include <asm/inst.h> #include <asm/inst.h>
/*
* Used to generate warnings if mmu or cpu feature check functions that
* use static keys before they are initialized.
*/
bool static_key_feature_checks_initialized __read_mostly;
EXPORT_SYMBOL_GPL(static_key_feature_checks_initialized);
struct fixup_entry { struct fixup_entry {
unsigned long mask; unsigned long mask;
unsigned long value; unsigned long value;
...@@ -679,6 +686,7 @@ void __init setup_feature_keys(void) ...@@ -679,6 +686,7 @@ void __init setup_feature_keys(void)
jump_label_init(); jump_label_init();
cpu_feature_keys_init(); cpu_feature_keys_init();
mmu_feature_keys_init(); mmu_feature_keys_init();
static_key_feature_checks_initialized = true;
} }
static int __init check_features(void) static int __init check_features(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment