diff options
-rw-r--r-- | kernel/jump_label.c | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index 7be868bf25c6..be9e105345eb 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -168,7 +168,8 @@ void jump_label_update(unsigned long key, enum jump_label_type type) | |||
168 | count = e_module->nr_entries; | 168 | count = e_module->nr_entries; |
169 | iter = e_module->table; | 169 | iter = e_module->table; |
170 | while (count--) { | 170 | while (count--) { |
171 | if (kernel_text_address(iter->code)) | 171 | if (iter->key && |
172 | kernel_text_address(iter->code)) | ||
172 | arch_jump_label_transform(iter, type); | 173 | arch_jump_label_transform(iter, type); |
173 | iter++; | 174 | iter++; |
174 | } | 175 | } |
@@ -366,6 +367,39 @@ static void remove_jump_label_module(struct module *mod) | |||
366 | } | 367 | } |
367 | } | 368 | } |
368 | 369 | ||
370 | static void remove_jump_label_module_init(struct module *mod) | ||
371 | { | ||
372 | struct hlist_head *head; | ||
373 | struct hlist_node *node, *node_next, *module_node, *module_node_next; | ||
374 | struct jump_label_entry *e; | ||
375 | struct jump_label_module_entry *e_module; | ||
376 | struct jump_entry *iter; | ||
377 | int i, count; | ||
378 | |||
379 | /* if the module doesn't have jump label entries, just return */ | ||
380 | if (!mod->num_jump_entries) | ||
381 | return; | ||
382 | |||
383 | for (i = 0; i < JUMP_LABEL_TABLE_SIZE; i++) { | ||
384 | head = &jump_label_table[i]; | ||
385 | hlist_for_each_entry_safe(e, node, node_next, head, hlist) { | ||
386 | hlist_for_each_entry_safe(e_module, module_node, | ||
387 | module_node_next, | ||
388 | &(e->modules), hlist) { | ||
389 | if (e_module->mod != mod) | ||
390 | continue; | ||
391 | count = e_module->nr_entries; | ||
392 | iter = e_module->table; | ||
393 | while (count--) { | ||
394 | if (within_module_init(iter->code, mod)) | ||
395 | iter->key = 0; | ||
396 | iter++; | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | } | ||
401 | } | ||
402 | |||
369 | static int | 403 | static int |
370 | jump_label_module_notify(struct notifier_block *self, unsigned long val, | 404 | jump_label_module_notify(struct notifier_block *self, unsigned long val, |
371 | void *data) | 405 | void *data) |
@@ -386,6 +420,11 @@ jump_label_module_notify(struct notifier_block *self, unsigned long val, | |||
386 | remove_jump_label_module(mod); | 420 | remove_jump_label_module(mod); |
387 | mutex_unlock(&jump_label_mutex); | 421 | mutex_unlock(&jump_label_mutex); |
388 | break; | 422 | break; |
423 | case MODULE_STATE_LIVE: | ||
424 | mutex_lock(&jump_label_mutex); | ||
425 | remove_jump_label_module_init(mod); | ||
426 | mutex_unlock(&jump_label_mutex); | ||
427 | break; | ||
389 | } | 428 | } |
390 | return ret; | 429 | return ret; |
391 | } | 430 | } |