]> asedeno.scripts.mit.edu Git - linux.git/blob - kernel/jump_label.c
jump_label: Abstract jump_entry member accessors
[linux.git] / kernel / jump_label.c
1 /*
2  * jump label support
3  *
4  * Copyright (C) 2009 Jason Baron <jbaron@redhat.com>
5  * Copyright (C) 2011 Peter Zijlstra
6  *
7  */
8 #include <linux/memory.h>
9 #include <linux/uaccess.h>
10 #include <linux/module.h>
11 #include <linux/list.h>
12 #include <linux/slab.h>
13 #include <linux/sort.h>
14 #include <linux/err.h>
15 #include <linux/static_key.h>
16 #include <linux/jump_label_ratelimit.h>
17 #include <linux/bug.h>
18 #include <linux/cpu.h>
19 #include <asm/sections.h>
20
21 #ifdef HAVE_JUMP_LABEL
22
23 /* mutex to protect coming/going of the the jump_label table */
24 static DEFINE_MUTEX(jump_label_mutex);
25
26 void jump_label_lock(void)
27 {
28         mutex_lock(&jump_label_mutex);
29 }
30
31 void jump_label_unlock(void)
32 {
33         mutex_unlock(&jump_label_mutex);
34 }
35
36 static int jump_label_cmp(const void *a, const void *b)
37 {
38         const struct jump_entry *jea = a;
39         const struct jump_entry *jeb = b;
40
41         if (jump_entry_key(jea) < jump_entry_key(jeb))
42                 return -1;
43
44         if (jump_entry_key(jea) > jump_entry_key(jeb))
45                 return 1;
46
47         return 0;
48 }
49
50 static void
51 jump_label_sort_entries(struct jump_entry *start, struct jump_entry *stop)
52 {
53         unsigned long size;
54
55         size = (((unsigned long)stop - (unsigned long)start)
56                                         / sizeof(struct jump_entry));
57         sort(start, size, sizeof(struct jump_entry), jump_label_cmp, NULL);
58 }
59
60 static void jump_label_update(struct static_key *key);
61
62 /*
63  * There are similar definitions for the !HAVE_JUMP_LABEL case in jump_label.h.
64  * The use of 'atomic_read()' requires atomic.h and its problematic for some
65  * kernel headers such as kernel.h and others. Since static_key_count() is not
66  * used in the branch statements as it is for the !HAVE_JUMP_LABEL case its ok
67  * to have it be a function here. Similarly, for 'static_key_enable()' and
68  * 'static_key_disable()', which require bug.h. This should allow jump_label.h
69  * to be included from most/all places for HAVE_JUMP_LABEL.
70  */
71 int static_key_count(struct static_key *key)
72 {
73         /*
74          * -1 means the first static_key_slow_inc() is in progress.
75          *  static_key_enabled() must return true, so return 1 here.
76          */
77         int n = atomic_read(&key->enabled);
78
79         return n >= 0 ? n : 1;
80 }
81 EXPORT_SYMBOL_GPL(static_key_count);
82
83 void static_key_slow_inc_cpuslocked(struct static_key *key)
84 {
85         int v, v1;
86
87         STATIC_KEY_CHECK_USE(key);
88
89         /*
90          * Careful if we get concurrent static_key_slow_inc() calls;
91          * later calls must wait for the first one to _finish_ the
92          * jump_label_update() process.  At the same time, however,
93          * the jump_label_update() call below wants to see
94          * static_key_enabled(&key) for jumps to be updated properly.
95          *
96          * So give a special meaning to negative key->enabled: it sends
97          * static_key_slow_inc() down the slow path, and it is non-zero
98          * so it counts as "enabled" in jump_label_update().  Note that
99          * atomic_inc_unless_negative() checks >= 0, so roll our own.
100          */
101         for (v = atomic_read(&key->enabled); v > 0; v = v1) {
102                 v1 = atomic_cmpxchg(&key->enabled, v, v + 1);
103                 if (likely(v1 == v))
104                         return;
105         }
106
107         jump_label_lock();
108         if (atomic_read(&key->enabled) == 0) {
109                 atomic_set(&key->enabled, -1);
110                 jump_label_update(key);
111                 /*
112                  * Ensure that if the above cmpxchg loop observes our positive
113                  * value, it must also observe all the text changes.
114                  */
115                 atomic_set_release(&key->enabled, 1);
116         } else {
117                 atomic_inc(&key->enabled);
118         }
119         jump_label_unlock();
120 }
121
122 void static_key_slow_inc(struct static_key *key)
123 {
124         cpus_read_lock();
125         static_key_slow_inc_cpuslocked(key);
126         cpus_read_unlock();
127 }
128 EXPORT_SYMBOL_GPL(static_key_slow_inc);
129
130 void static_key_enable_cpuslocked(struct static_key *key)
131 {
132         STATIC_KEY_CHECK_USE(key);
133
134         if (atomic_read(&key->enabled) > 0) {
135                 WARN_ON_ONCE(atomic_read(&key->enabled) != 1);
136                 return;
137         }
138
139         jump_label_lock();
140         if (atomic_read(&key->enabled) == 0) {
141                 atomic_set(&key->enabled, -1);
142                 jump_label_update(key);
143                 /*
144                  * See static_key_slow_inc().
145                  */
146                 atomic_set_release(&key->enabled, 1);
147         }
148         jump_label_unlock();
149 }
150 EXPORT_SYMBOL_GPL(static_key_enable_cpuslocked);
151
152 void static_key_enable(struct static_key *key)
153 {
154         cpus_read_lock();
155         static_key_enable_cpuslocked(key);
156         cpus_read_unlock();
157 }
158 EXPORT_SYMBOL_GPL(static_key_enable);
159
160 void static_key_disable_cpuslocked(struct static_key *key)
161 {
162         STATIC_KEY_CHECK_USE(key);
163
164         if (atomic_read(&key->enabled) != 1) {
165                 WARN_ON_ONCE(atomic_read(&key->enabled) != 0);
166                 return;
167         }
168
169         jump_label_lock();
170         if (atomic_cmpxchg(&key->enabled, 1, 0))
171                 jump_label_update(key);
172         jump_label_unlock();
173 }
174 EXPORT_SYMBOL_GPL(static_key_disable_cpuslocked);
175
176 void static_key_disable(struct static_key *key)
177 {
178         cpus_read_lock();
179         static_key_disable_cpuslocked(key);
180         cpus_read_unlock();
181 }
182 EXPORT_SYMBOL_GPL(static_key_disable);
183
184 static void __static_key_slow_dec_cpuslocked(struct static_key *key,
185                                            unsigned long rate_limit,
186                                            struct delayed_work *work)
187 {
188         /*
189          * The negative count check is valid even when a negative
190          * key->enabled is in use by static_key_slow_inc(); a
191          * __static_key_slow_dec() before the first static_key_slow_inc()
192          * returns is unbalanced, because all other static_key_slow_inc()
193          * instances block while the update is in progress.
194          */
195         if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) {
196                 WARN(atomic_read(&key->enabled) < 0,
197                      "jump label: negative count!\n");
198                 return;
199         }
200
201         if (rate_limit) {
202                 atomic_inc(&key->enabled);
203                 schedule_delayed_work(work, rate_limit);
204         } else {
205                 jump_label_update(key);
206         }
207         jump_label_unlock();
208 }
209
210 static void __static_key_slow_dec(struct static_key *key,
211                                   unsigned long rate_limit,
212                                   struct delayed_work *work)
213 {
214         cpus_read_lock();
215         __static_key_slow_dec_cpuslocked(key, rate_limit, work);
216         cpus_read_unlock();
217 }
218
219 static void jump_label_update_timeout(struct work_struct *work)
220 {
221         struct static_key_deferred *key =
222                 container_of(work, struct static_key_deferred, work.work);
223         __static_key_slow_dec(&key->key, 0, NULL);
224 }
225
226 void static_key_slow_dec(struct static_key *key)
227 {
228         STATIC_KEY_CHECK_USE(key);
229         __static_key_slow_dec(key, 0, NULL);
230 }
231 EXPORT_SYMBOL_GPL(static_key_slow_dec);
232
233 void static_key_slow_dec_cpuslocked(struct static_key *key)
234 {
235         STATIC_KEY_CHECK_USE(key);
236         __static_key_slow_dec_cpuslocked(key, 0, NULL);
237 }
238
239 void static_key_slow_dec_deferred(struct static_key_deferred *key)
240 {
241         STATIC_KEY_CHECK_USE(key);
242         __static_key_slow_dec(&key->key, key->timeout, &key->work);
243 }
244 EXPORT_SYMBOL_GPL(static_key_slow_dec_deferred);
245
246 void static_key_deferred_flush(struct static_key_deferred *key)
247 {
248         STATIC_KEY_CHECK_USE(key);
249         flush_delayed_work(&key->work);
250 }
251 EXPORT_SYMBOL_GPL(static_key_deferred_flush);
252
253 void jump_label_rate_limit(struct static_key_deferred *key,
254                 unsigned long rl)
255 {
256         STATIC_KEY_CHECK_USE(key);
257         key->timeout = rl;
258         INIT_DELAYED_WORK(&key->work, jump_label_update_timeout);
259 }
260 EXPORT_SYMBOL_GPL(jump_label_rate_limit);
261
262 static int addr_conflict(struct jump_entry *entry, void *start, void *end)
263 {
264         if (jump_entry_code(entry) <= (unsigned long)end &&
265             jump_entry_code(entry) + JUMP_LABEL_NOP_SIZE > (unsigned long)start)
266                 return 1;
267
268         return 0;
269 }
270
271 static int __jump_label_text_reserved(struct jump_entry *iter_start,
272                 struct jump_entry *iter_stop, void *start, void *end)
273 {
274         struct jump_entry *iter;
275
276         iter = iter_start;
277         while (iter < iter_stop) {
278                 if (addr_conflict(iter, start, end))
279                         return 1;
280                 iter++;
281         }
282
283         return 0;
284 }
285
286 /*
287  * Update code which is definitely not currently executing.
288  * Architectures which need heavyweight synchronization to modify
289  * running code can override this to make the non-live update case
290  * cheaper.
291  */
292 void __weak __init_or_module arch_jump_label_transform_static(struct jump_entry *entry,
293                                             enum jump_label_type type)
294 {
295         arch_jump_label_transform(entry, type);
296 }
297
298 static inline struct jump_entry *static_key_entries(struct static_key *key)
299 {
300         WARN_ON_ONCE(key->type & JUMP_TYPE_LINKED);
301         return (struct jump_entry *)(key->type & ~JUMP_TYPE_MASK);
302 }
303
304 static inline bool static_key_type(struct static_key *key)
305 {
306         return key->type & JUMP_TYPE_TRUE;
307 }
308
309 static inline bool static_key_linked(struct static_key *key)
310 {
311         return key->type & JUMP_TYPE_LINKED;
312 }
313
314 static inline void static_key_clear_linked(struct static_key *key)
315 {
316         key->type &= ~JUMP_TYPE_LINKED;
317 }
318
319 static inline void static_key_set_linked(struct static_key *key)
320 {
321         key->type |= JUMP_TYPE_LINKED;
322 }
323
324 /***
325  * A 'struct static_key' uses a union such that it either points directly
326  * to a table of 'struct jump_entry' or to a linked list of modules which in
327  * turn point to 'struct jump_entry' tables.
328  *
329  * The two lower bits of the pointer are used to keep track of which pointer
330  * type is in use and to store the initial branch direction, we use an access
331  * function which preserves these bits.
332  */
333 static void static_key_set_entries(struct static_key *key,
334                                    struct jump_entry *entries)
335 {
336         unsigned long type;
337
338         WARN_ON_ONCE((unsigned long)entries & JUMP_TYPE_MASK);
339         type = key->type & JUMP_TYPE_MASK;
340         key->entries = entries;
341         key->type |= type;
342 }
343
344 static enum jump_label_type jump_label_type(struct jump_entry *entry)
345 {
346         struct static_key *key = jump_entry_key(entry);
347         bool enabled = static_key_enabled(key);
348         bool branch = jump_entry_is_branch(entry);
349
350         /* See the comment in linux/jump_label.h */
351         return enabled ^ branch;
352 }
353
354 static void __jump_label_update(struct static_key *key,
355                                 struct jump_entry *entry,
356                                 struct jump_entry *stop)
357 {
358         for (; (entry < stop) && (jump_entry_key(entry) == key); entry++) {
359                 /*
360                  * An entry->code of 0 indicates an entry which has been
361                  * disabled because it was in an init text area.
362                  */
363                 if (!jump_entry_is_init(entry)) {
364                         if (kernel_text_address(jump_entry_code(entry)))
365                                 arch_jump_label_transform(entry, jump_label_type(entry));
366                         else
367                                 WARN_ONCE(1, "can't patch jump_label at %pS",
368                                           (void *)jump_entry_code(entry));
369                 }
370         }
371 }
372
373 void __init jump_label_init(void)
374 {
375         struct jump_entry *iter_start = __start___jump_table;
376         struct jump_entry *iter_stop = __stop___jump_table;
377         struct static_key *key = NULL;
378         struct jump_entry *iter;
379
380         /*
381          * Since we are initializing the static_key.enabled field with
382          * with the 'raw' int values (to avoid pulling in atomic.h) in
383          * jump_label.h, let's make sure that is safe. There are only two
384          * cases to check since we initialize to 0 or 1.
385          */
386         BUILD_BUG_ON((int)ATOMIC_INIT(0) != 0);
387         BUILD_BUG_ON((int)ATOMIC_INIT(1) != 1);
388
389         if (static_key_initialized)
390                 return;
391
392         cpus_read_lock();
393         jump_label_lock();
394         jump_label_sort_entries(iter_start, iter_stop);
395
396         for (iter = iter_start; iter < iter_stop; iter++) {
397                 struct static_key *iterk;
398
399                 /* rewrite NOPs */
400                 if (jump_label_type(iter) == JUMP_LABEL_NOP)
401                         arch_jump_label_transform_static(iter, JUMP_LABEL_NOP);
402
403                 iterk = jump_entry_key(iter);
404                 if (iterk == key)
405                         continue;
406
407                 key = iterk;
408                 static_key_set_entries(key, iter);
409         }
410         static_key_initialized = true;
411         jump_label_unlock();
412         cpus_read_unlock();
413 }
414
415 /* Disable any jump label entries in __init/__exit code */
416 void __init jump_label_invalidate_initmem(void)
417 {
418         struct jump_entry *iter_start = __start___jump_table;
419         struct jump_entry *iter_stop = __stop___jump_table;
420         struct jump_entry *iter;
421
422         for (iter = iter_start; iter < iter_stop; iter++) {
423                 if (init_section_contains((void *)jump_entry_code(iter), 1))
424                         jump_entry_set_init(iter);
425         }
426 }
427
428 #ifdef CONFIG_MODULES
429
430 static enum jump_label_type jump_label_init_type(struct jump_entry *entry)
431 {
432         struct static_key *key = jump_entry_key(entry);
433         bool type = static_key_type(key);
434         bool branch = jump_entry_is_branch(entry);
435
436         /* See the comment in linux/jump_label.h */
437         return type ^ branch;
438 }
439
440 struct static_key_mod {
441         struct static_key_mod *next;
442         struct jump_entry *entries;
443         struct module *mod;
444 };
445
446 static inline struct static_key_mod *static_key_mod(struct static_key *key)
447 {
448         WARN_ON_ONCE(!(key->type & JUMP_TYPE_LINKED));
449         return (struct static_key_mod *)(key->type & ~JUMP_TYPE_MASK);
450 }
451
452 /***
453  * key->type and key->next are the same via union.
454  * This sets key->next and preserves the type bits.
455  *
456  * See additional comments above static_key_set_entries().
457  */
458 static void static_key_set_mod(struct static_key *key,
459                                struct static_key_mod *mod)
460 {
461         unsigned long type;
462
463         WARN_ON_ONCE((unsigned long)mod & JUMP_TYPE_MASK);
464         type = key->type & JUMP_TYPE_MASK;
465         key->next = mod;
466         key->type |= type;
467 }
468
469 static int __jump_label_mod_text_reserved(void *start, void *end)
470 {
471         struct module *mod;
472
473         preempt_disable();
474         mod = __module_text_address((unsigned long)start);
475         WARN_ON_ONCE(__module_text_address((unsigned long)end) != mod);
476         preempt_enable();
477
478         if (!mod)
479                 return 0;
480
481
482         return __jump_label_text_reserved(mod->jump_entries,
483                                 mod->jump_entries + mod->num_jump_entries,
484                                 start, end);
485 }
486
487 static void __jump_label_mod_update(struct static_key *key)
488 {
489         struct static_key_mod *mod;
490
491         for (mod = static_key_mod(key); mod; mod = mod->next) {
492                 struct jump_entry *stop;
493                 struct module *m;
494
495                 /*
496                  * NULL if the static_key is defined in a module
497                  * that does not use it
498                  */
499                 if (!mod->entries)
500                         continue;
501
502                 m = mod->mod;
503                 if (!m)
504                         stop = __stop___jump_table;
505                 else
506                         stop = m->jump_entries + m->num_jump_entries;
507                 __jump_label_update(key, mod->entries, stop);
508         }
509 }
510
511 /***
512  * apply_jump_label_nops - patch module jump labels with arch_get_jump_label_nop()
513  * @mod: module to patch
514  *
515  * Allow for run-time selection of the optimal nops. Before the module
516  * loads patch these with arch_get_jump_label_nop(), which is specified by
517  * the arch specific jump label code.
518  */
519 void jump_label_apply_nops(struct module *mod)
520 {
521         struct jump_entry *iter_start = mod->jump_entries;
522         struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
523         struct jump_entry *iter;
524
525         /* if the module doesn't have jump label entries, just return */
526         if (iter_start == iter_stop)
527                 return;
528
529         for (iter = iter_start; iter < iter_stop; iter++) {
530                 /* Only write NOPs for arch_branch_static(). */
531                 if (jump_label_init_type(iter) == JUMP_LABEL_NOP)
532                         arch_jump_label_transform_static(iter, JUMP_LABEL_NOP);
533         }
534 }
535
536 static int jump_label_add_module(struct module *mod)
537 {
538         struct jump_entry *iter_start = mod->jump_entries;
539         struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
540         struct jump_entry *iter;
541         struct static_key *key = NULL;
542         struct static_key_mod *jlm, *jlm2;
543
544         /* if the module doesn't have jump label entries, just return */
545         if (iter_start == iter_stop)
546                 return 0;
547
548         jump_label_sort_entries(iter_start, iter_stop);
549
550         for (iter = iter_start; iter < iter_stop; iter++) {
551                 struct static_key *iterk;
552
553                 iterk = jump_entry_key(iter);
554                 if (iterk == key)
555                         continue;
556
557                 key = iterk;
558                 if (within_module((unsigned long)key, mod)) {
559                         static_key_set_entries(key, iter);
560                         continue;
561                 }
562                 jlm = kzalloc(sizeof(struct static_key_mod), GFP_KERNEL);
563                 if (!jlm)
564                         return -ENOMEM;
565                 if (!static_key_linked(key)) {
566                         jlm2 = kzalloc(sizeof(struct static_key_mod),
567                                        GFP_KERNEL);
568                         if (!jlm2) {
569                                 kfree(jlm);
570                                 return -ENOMEM;
571                         }
572                         preempt_disable();
573                         jlm2->mod = __module_address((unsigned long)key);
574                         preempt_enable();
575                         jlm2->entries = static_key_entries(key);
576                         jlm2->next = NULL;
577                         static_key_set_mod(key, jlm2);
578                         static_key_set_linked(key);
579                 }
580                 jlm->mod = mod;
581                 jlm->entries = iter;
582                 jlm->next = static_key_mod(key);
583                 static_key_set_mod(key, jlm);
584                 static_key_set_linked(key);
585
586                 /* Only update if we've changed from our initial state */
587                 if (jump_label_type(iter) != jump_label_init_type(iter))
588                         __jump_label_update(key, iter, iter_stop);
589         }
590
591         return 0;
592 }
593
594 static void jump_label_del_module(struct module *mod)
595 {
596         struct jump_entry *iter_start = mod->jump_entries;
597         struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
598         struct jump_entry *iter;
599         struct static_key *key = NULL;
600         struct static_key_mod *jlm, **prev;
601
602         for (iter = iter_start; iter < iter_stop; iter++) {
603                 if (jump_entry_key(iter) == key)
604                         continue;
605
606                 key = jump_entry_key(iter);
607
608                 if (within_module((unsigned long)key, mod))
609                         continue;
610
611                 /* No memory during module load */
612                 if (WARN_ON(!static_key_linked(key)))
613                         continue;
614
615                 prev = &key->next;
616                 jlm = static_key_mod(key);
617
618                 while (jlm && jlm->mod != mod) {
619                         prev = &jlm->next;
620                         jlm = jlm->next;
621                 }
622
623                 /* No memory during module load */
624                 if (WARN_ON(!jlm))
625                         continue;
626
627                 if (prev == &key->next)
628                         static_key_set_mod(key, jlm->next);
629                 else
630                         *prev = jlm->next;
631
632                 kfree(jlm);
633
634                 jlm = static_key_mod(key);
635                 /* if only one etry is left, fold it back into the static_key */
636                 if (jlm->next == NULL) {
637                         static_key_set_entries(key, jlm->entries);
638                         static_key_clear_linked(key);
639                         kfree(jlm);
640                 }
641         }
642 }
643
644 /* Disable any jump label entries in module init code */
645 static void jump_label_invalidate_module_init(struct module *mod)
646 {
647         struct jump_entry *iter_start = mod->jump_entries;
648         struct jump_entry *iter_stop = iter_start + mod->num_jump_entries;
649         struct jump_entry *iter;
650
651         for (iter = iter_start; iter < iter_stop; iter++) {
652                 if (within_module_init(jump_entry_code(iter), mod))
653                         jump_entry_set_init(iter);
654         }
655 }
656
657 static int
658 jump_label_module_notify(struct notifier_block *self, unsigned long val,
659                          void *data)
660 {
661         struct module *mod = data;
662         int ret = 0;
663
664         cpus_read_lock();
665         jump_label_lock();
666
667         switch (val) {
668         case MODULE_STATE_COMING:
669                 ret = jump_label_add_module(mod);
670                 if (ret) {
671                         WARN(1, "Failed to allocate memory: jump_label may not work properly.\n");
672                         jump_label_del_module(mod);
673                 }
674                 break;
675         case MODULE_STATE_GOING:
676                 jump_label_del_module(mod);
677                 break;
678         case MODULE_STATE_LIVE:
679                 jump_label_invalidate_module_init(mod);
680                 break;
681         }
682
683         jump_label_unlock();
684         cpus_read_unlock();
685
686         return notifier_from_errno(ret);
687 }
688
689 static struct notifier_block jump_label_module_nb = {
690         .notifier_call = jump_label_module_notify,
691         .priority = 1, /* higher than tracepoints */
692 };
693
694 static __init int jump_label_init_module(void)
695 {
696         return register_module_notifier(&jump_label_module_nb);
697 }
698 early_initcall(jump_label_init_module);
699
700 #endif /* CONFIG_MODULES */
701
702 /***
703  * jump_label_text_reserved - check if addr range is reserved
704  * @start: start text addr
705  * @end: end text addr
706  *
707  * checks if the text addr located between @start and @end
708  * overlaps with any of the jump label patch addresses. Code
709  * that wants to modify kernel text should first verify that
710  * it does not overlap with any of the jump label addresses.
711  * Caller must hold jump_label_mutex.
712  *
713  * returns 1 if there is an overlap, 0 otherwise
714  */
715 int jump_label_text_reserved(void *start, void *end)
716 {
717         int ret = __jump_label_text_reserved(__start___jump_table,
718                         __stop___jump_table, start, end);
719
720         if (ret)
721                 return ret;
722
723 #ifdef CONFIG_MODULES
724         ret = __jump_label_mod_text_reserved(start, end);
725 #endif
726         return ret;
727 }
728
729 static void jump_label_update(struct static_key *key)
730 {
731         struct jump_entry *stop = __stop___jump_table;
732         struct jump_entry *entry;
733 #ifdef CONFIG_MODULES
734         struct module *mod;
735
736         if (static_key_linked(key)) {
737                 __jump_label_mod_update(key);
738                 return;
739         }
740
741         preempt_disable();
742         mod = __module_address((unsigned long)key);
743         if (mod)
744                 stop = mod->jump_entries + mod->num_jump_entries;
745         preempt_enable();
746 #endif
747         entry = static_key_entries(key);
748         /* if there are no users, entry can be NULL */
749         if (entry)
750                 __jump_label_update(key, entry, stop);
751 }
752
753 #ifdef CONFIG_STATIC_KEYS_SELFTEST
754 static DEFINE_STATIC_KEY_TRUE(sk_true);
755 static DEFINE_STATIC_KEY_FALSE(sk_false);
756
757 static __init int jump_label_test(void)
758 {
759         int i;
760
761         for (i = 0; i < 2; i++) {
762                 WARN_ON(static_key_enabled(&sk_true.key) != true);
763                 WARN_ON(static_key_enabled(&sk_false.key) != false);
764
765                 WARN_ON(!static_branch_likely(&sk_true));
766                 WARN_ON(!static_branch_unlikely(&sk_true));
767                 WARN_ON(static_branch_likely(&sk_false));
768                 WARN_ON(static_branch_unlikely(&sk_false));
769
770                 static_branch_disable(&sk_true);
771                 static_branch_enable(&sk_false);
772
773                 WARN_ON(static_key_enabled(&sk_true.key) == true);
774                 WARN_ON(static_key_enabled(&sk_false.key) == false);
775
776                 WARN_ON(static_branch_likely(&sk_true));
777                 WARN_ON(static_branch_unlikely(&sk_true));
778                 WARN_ON(!static_branch_likely(&sk_false));
779                 WARN_ON(!static_branch_unlikely(&sk_false));
780
781                 static_branch_enable(&sk_true);
782                 static_branch_disable(&sk_false);
783         }
784
785         return 0;
786 }
787 early_initcall(jump_label_test);
788 #endif /* STATIC_KEYS_SELFTEST */
789
790 #endif /* HAVE_JUMP_LABEL */