diff options
Diffstat (limited to 'kernel/jump_label.c')
-rw-r--r-- | kernel/jump_label.c | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index a8ce45097f3d..bbdfe2a462a0 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -104,6 +104,18 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start, | |||
104 | return 0; | 104 | return 0; |
105 | } | 105 | } |
106 | 106 | ||
107 | /* | ||
108 | * Update code which is definitely not currently executing. | ||
109 | * Architectures which need heavyweight synchronization to modify | ||
110 | * running code can override this to make the non-live update case | ||
111 | * cheaper. | ||
112 | */ | ||
113 | void __weak arch_jump_label_transform_static(struct jump_entry *entry, | ||
114 | enum jump_label_type type) | ||
115 | { | ||
116 | arch_jump_label_transform(entry, type); | ||
117 | } | ||
118 | |||
107 | static void __jump_label_update(struct jump_label_key *key, | 119 | static void __jump_label_update(struct jump_label_key *key, |
108 | struct jump_entry *entry, | 120 | struct jump_entry *entry, |
109 | struct jump_entry *stop, int enable) | 121 | struct jump_entry *stop, int enable) |
@@ -121,14 +133,7 @@ static void __jump_label_update(struct jump_label_key *key, | |||
121 | } | 133 | } |
122 | } | 134 | } |
123 | 135 | ||
124 | /* | 136 | void __init jump_label_init(void) |
125 | * Not all archs need this. | ||
126 | */ | ||
127 | void __weak arch_jump_label_text_poke_early(jump_label_t addr) | ||
128 | { | ||
129 | } | ||
130 | |||
131 | static __init int jump_label_init(void) | ||
132 | { | 137 | { |
133 | struct jump_entry *iter_start = __start___jump_table; | 138 | struct jump_entry *iter_start = __start___jump_table; |
134 | struct jump_entry *iter_stop = __stop___jump_table; | 139 | struct jump_entry *iter_stop = __stop___jump_table; |
@@ -139,22 +144,22 @@ static __init int jump_label_init(void) | |||
139 | jump_label_sort_entries(iter_start, iter_stop); | 144 | jump_label_sort_entries(iter_start, iter_stop); |
140 | 145 | ||
141 | for (iter = iter_start; iter < iter_stop; iter++) { | 146 | for (iter = iter_start; iter < iter_stop; iter++) { |
142 | arch_jump_label_text_poke_early(iter->code); | 147 | struct jump_label_key *iterk; |
143 | if (iter->key == (jump_label_t)(unsigned long)key) | 148 | |
149 | iterk = (struct jump_label_key *)(unsigned long)iter->key; | ||
150 | arch_jump_label_transform_static(iter, jump_label_enabled(iterk) ? | ||
151 | JUMP_LABEL_ENABLE : JUMP_LABEL_DISABLE); | ||
152 | if (iterk == key) | ||
144 | continue; | 153 | continue; |
145 | 154 | ||
146 | key = (struct jump_label_key *)(unsigned long)iter->key; | 155 | key = iterk; |
147 | atomic_set(&key->enabled, 0); | ||
148 | key->entries = iter; | 156 | key->entries = iter; |
149 | #ifdef CONFIG_MODULES | 157 | #ifdef CONFIG_MODULES |
150 | key->next = NULL; | 158 | key->next = NULL; |
151 | #endif | 159 | #endif |
152 | } | 160 | } |
153 | jump_label_unlock(); | 161 | jump_label_unlock(); |
154 | |||
155 | return 0; | ||
156 | } | 162 | } |
157 | early_initcall(jump_label_init); | ||
158 | 163 | ||
159 | #ifdef CONFIG_MODULES | 164 | #ifdef CONFIG_MODULES |
160 | 165 | ||
@@ -212,7 +217,7 @@ void jump_label_apply_nops(struct module *mod) | |||
212 | return; | 217 | return; |
213 | 218 | ||
214 | for (iter = iter_start; iter < iter_stop; iter++) | 219 | for (iter = iter_start; iter < iter_stop; iter++) |
215 | arch_jump_label_text_poke_early(iter->code); | 220 | arch_jump_label_transform_static(iter, JUMP_LABEL_DISABLE); |
216 | } | 221 | } |
217 | 222 | ||
218 | static int jump_label_add_module(struct module *mod) | 223 | static int jump_label_add_module(struct module *mod) |