|
@@ -373,14 +373,15 @@ static enum jump_label_type jump_label_type(struct jump_entry *entry)
|
|
|
|
|
|
static void __jump_label_update(struct static_key *key,
|
|
|
struct jump_entry *entry,
|
|
|
- struct jump_entry *stop)
|
|
|
+ struct jump_entry *stop,
|
|
|
+ bool init)
|
|
|
{
|
|
|
for (; (entry < stop) && (jump_entry_key(entry) == key); entry++) {
|
|
|
/*
|
|
|
* An entry->code of 0 indicates an entry which has been
|
|
|
* disabled because it was in an init text area.
|
|
|
*/
|
|
|
- if (!jump_entry_is_init(entry)) {
|
|
|
+ if (init || !jump_entry_is_init(entry)) {
|
|
|
if (kernel_text_address(jump_entry_code(entry)))
|
|
|
arch_jump_label_transform(entry, jump_label_type(entry));
|
|
|
else
|
|
@@ -420,6 +421,9 @@ void __init jump_label_init(void)
|
|
|
if (jump_label_type(iter) == JUMP_LABEL_NOP)
|
|
|
arch_jump_label_transform_static(iter, JUMP_LABEL_NOP);
|
|
|
|
|
|
+ if (init_section_contains((void *)jump_entry_code(iter), 1))
|
|
|
+ jump_entry_set_init(iter);
|
|
|
+
|
|
|
iterk = jump_entry_key(iter);
|
|
|
if (iterk == key)
|
|
|
continue;
|
|
@@ -432,19 +436,6 @@ void __init jump_label_init(void)
|
|
|
cpus_read_unlock();
|
|
|
}
|
|
|
|
|
|
-/* Disable any jump label entries in __init/__exit code */
|
|
|
-void __init jump_label_invalidate_initmem(void)
|
|
|
-{
|
|
|
- struct jump_entry *iter_start = __start___jump_table;
|
|
|
- struct jump_entry *iter_stop = __stop___jump_table;
|
|
|
- struct jump_entry *iter;
|
|
|
-
|
|
|
- for (iter = iter_start; iter < iter_stop; iter++) {
|
|
|
- if (init_section_contains((void *)jump_entry_code(iter), 1))
|
|
|
- jump_entry_set_init(iter);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
#ifdef CONFIG_MODULES
|
|
|
|
|
|
static enum jump_label_type jump_label_init_type(struct jump_entry *entry)
|
|
@@ -524,7 +515,8 @@ static void __jump_label_mod_update(struct static_key *key)
|
|
|
stop = __stop___jump_table;
|
|
|
else
|
|
|
stop = m->jump_entries + m->num_jump_entries;
|
|
|
- __jump_label_update(key, mod->entries, stop);
|
|
|
+ __jump_label_update(key, mod->entries, stop,
|
|
|
+ m->state == MODULE_STATE_COMING);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -570,6 +562,9 @@ static int jump_label_add_module(struct module *mod)
|
|
|
for (iter = iter_start; iter < iter_stop; iter++) {
|
|
|
struct static_key *iterk;
|
|
|
|
|
|
+ if (within_module_init(jump_entry_code(iter), mod))
|
|
|
+ jump_entry_set_init(iter);
|
|
|
+
|
|
|
iterk = jump_entry_key(iter);
|
|
|
if (iterk == key)
|
|
|
continue;
|
|
@@ -605,7 +600,7 @@ static int jump_label_add_module(struct module *mod)
|
|
|
|
|
|
/* Only update if we've changed from our initial state */
|
|
|
if (jump_label_type(iter) != jump_label_init_type(iter))
|
|
|
- __jump_label_update(key, iter, iter_stop);
|
|
|
+ __jump_label_update(key, iter, iter_stop, true);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -661,19 +656,6 @@ static void jump_label_del_module(struct module *mod)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/* Disable any jump label entries in module init code */
|
|
|
-static void jump_label_invalidate_module_init(struct module *mod)
|
|
|
-{
|
|
|
- struct jump_entry *iter_start = mod->jump_entries;
|
|
|
- struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
|
|
|
- struct jump_entry *iter;
|
|
|
-
|
|
|
- for (iter = iter_start; iter < iter_stop; iter++) {
|
|
|
- if (within_module_init(jump_entry_code(iter), mod))
|
|
|
- jump_entry_set_init(iter);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static int
|
|
|
jump_label_module_notify(struct notifier_block *self, unsigned long val,
|
|
|
void *data)
|
|
@@ -695,9 +677,6 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val,
|
|
|
case MODULE_STATE_GOING:
|
|
|
jump_label_del_module(mod);
|
|
|
break;
|
|
|
- case MODULE_STATE_LIVE:
|
|
|
- jump_label_invalidate_module_init(mod);
|
|
|
- break;
|
|
|
}
|
|
|
|
|
|
jump_label_unlock();
|
|
@@ -767,7 +746,8 @@ static void jump_label_update(struct static_key *key)
|
|
|
entry = static_key_entries(key);
|
|
|
/* if there are no users, entry can be NULL */
|
|
|
if (entry)
|
|
|
- __jump_label_update(key, entry, stop);
|
|
|
+ __jump_label_update(key, entry, stop,
|
|
|
+ system_state < SYSTEM_RUNNING);
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_STATIC_KEYS_SELFTEST
|