10 #include <linux/module.h>
11 #include <linux/list.h>
12 #include <linux/slab.h>
17 #ifdef HAVE_JUMP_LABEL
22 void jump_label_lock(
void)
27 void jump_label_unlock(
void)
32 static int jump_label_cmp(
const void *
a,
const void *
b)
51 size = (((
unsigned long)stop - (
unsigned long)
start)
65 if (!jump_label_get_branch_default(key))
75 static void __static_key_slow_dec(
struct static_key *key,
80 "jump label: negative count!\n");
88 if (!jump_label_get_branch_default(key))
96 static void jump_label_update_timeout(
struct work_struct *work)
100 __static_key_slow_dec(&key->
key, 0,
NULL);
103 void static_key_slow_dec(
struct static_key *key)
105 __static_key_slow_dec(key, 0,
NULL);
111 __static_key_slow_dec(&key->
key, key->timeout, &key->work);
125 if (entry->
code <= (
unsigned long)end &&
132 static int __jump_label_text_reserved(
struct jump_entry *iter_start,
133 struct jump_entry *iter_stop,
void *start,
void *end)
138 while (iter < iter_stop) {
139 if (addr_conflict(iter, start, end))
156 arch_jump_label_transform(entry, type);
159 static void __jump_label_update(
struct static_key *key,
163 for (; (entry <
stop) &&
172 arch_jump_label_transform(entry, enable);
178 bool true_branch = jump_label_get_branch_default(key);
179 bool state = static_key_enabled(key);
181 if ((!true_branch && state) || (true_branch && !state))
187 void __init jump_label_init(
void)
189 struct jump_entry *iter_start = __start___jump_table;
190 struct jump_entry *iter_stop = __stop___jump_table;
195 jump_label_sort_entries(iter_start, iter_stop);
197 for (iter = iter_start; iter < iter_stop; iter++) {
209 *((
unsigned long *)&key->entries) += (
unsigned long)iter;
210 #ifdef CONFIG_MODULES
217 #ifdef CONFIG_MODULES
219 struct static_key_mod {
220 struct static_key_mod *
next;
225 static int __jump_label_mod_text_reserved(
void *start,
void *end)
235 return __jump_label_text_reserved(mod->jump_entries,
236 mod->jump_entries + mod->num_jump_entries,
240 static void __jump_label_mod_update(
struct static_key *key,
int enable)
242 struct static_key_mod *mod = key->next;
247 __jump_label_update(key, mod->entries,
248 m->jump_entries + m->num_jump_entries,
262 void jump_label_apply_nops(
struct module *mod)
264 struct jump_entry *iter_start = mod->jump_entries;
265 struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
269 if (iter_start == iter_stop)
272 for (iter = iter_start; iter < iter_stop; iter++) {
277 static int jump_label_add_module(
struct module *mod)
279 struct jump_entry *iter_start = mod->jump_entries;
280 struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
283 struct static_key_mod *jlm;
286 if (iter_start == iter_stop)
289 jump_label_sort_entries(iter_start, iter_stop);
291 for (iter = iter_start; iter < iter_stop; iter++) {
303 *((
unsigned long *)&key->entries) += (
unsigned long)iter;
307 jlm = kzalloc(
sizeof(
struct static_key_mod),
GFP_KERNEL);
312 jlm->next = key->next;
322 static void jump_label_del_module(
struct module *mod)
324 struct jump_entry *iter_start = mod->jump_entries;
325 struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
328 struct static_key_mod *jlm, **
prev;
330 for (iter = iter_start; iter < iter_stop; iter++) {
342 while (jlm && jlm->mod != mod) {
354 static void jump_label_invalidate_module_init(
struct module *mod)
356 struct jump_entry *iter_start = mod->jump_entries;
357 struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
360 for (iter = iter_start; iter < iter_stop; iter++) {
361 if (within_module_init(iter->
code, mod))
374 case MODULE_STATE_COMING:
376 ret = jump_label_add_module(mod);
378 jump_label_del_module(mod);
381 case MODULE_STATE_GOING:
383 jump_label_del_module(mod);
386 case MODULE_STATE_LIVE:
388 jump_label_invalidate_module_init(mod);
393 return notifier_from_errno(ret);
401 static __init int jump_label_init_module(
void)
422 int jump_label_text_reserved(
void *start,
void *end)
424 int ret = __jump_label_text_reserved(__start___jump_table,
425 __stop___jump_table, start, end);
430 #ifdef CONFIG_MODULES
431 ret = __jump_label_mod_text_reserved(start, end);
436 static void jump_label_update(
struct static_key *key,
int enable)
438 struct jump_entry *stop = __stop___jump_table;
439 struct jump_entry *entry = jump_label_get_entries(key);
441 #ifdef CONFIG_MODULES
444 __jump_label_mod_update(key, enable);
447 stop = mod->jump_entries + mod->num_jump_entries;
451 __jump_label_update(key, entry, stop, enable);