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 | } |
