diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-04-08 17:26:21 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-04-08 17:26:21 -0400 |
commit | 462b69b1e43ceccab68a47d65b1e46520cd0fdc0 (patch) | |
tree | 3c961fcb5889c5ab14ab36d8ef7421fc96c95959 /kernel/livepatch/core.c | |
parent | d8bf368d0631d4bc2612d8bf2e4e8e74e620d0cc (diff) | |
parent | f22e6e847115abc3a0e2ad7bb18d243d42275af1 (diff) |
Merge branch 'linus' into irq/core to get the GIC updates which
conflict with pending GIC changes.
Conflicts:
drivers/usb/isp1760/isp1760-core.c
Diffstat (limited to 'kernel/livepatch/core.c')
-rw-r--r-- | kernel/livepatch/core.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 782172f073c5..3f9f1d6b4c2e 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
@@ -89,16 +89,28 @@ static bool klp_is_object_loaded(struct klp_object *obj) | |||
89 | /* sets obj->mod if object is not vmlinux and module is found */ | 89 | /* sets obj->mod if object is not vmlinux and module is found */ |
90 | static void klp_find_object_module(struct klp_object *obj) | 90 | static void klp_find_object_module(struct klp_object *obj) |
91 | { | 91 | { |
92 | struct module *mod; | ||
93 | |||
92 | if (!klp_is_module(obj)) | 94 | if (!klp_is_module(obj)) |
93 | return; | 95 | return; |
94 | 96 | ||
95 | mutex_lock(&module_mutex); | 97 | mutex_lock(&module_mutex); |
96 | /* | 98 | /* |
97 | * We don't need to take a reference on the module here because we have | 99 | * We do not want to block removal of patched modules and therefore |
98 | * the klp_mutex, which is also taken by the module notifier. This | 100 | * we do not take a reference here. The patches are removed by |
99 | * prevents any module from unloading until we release the klp_mutex. | 101 | * a going module handler instead. |
102 | */ | ||
103 | mod = find_module(obj->name); | ||
104 | /* | ||
105 | * Do not mess work of the module coming and going notifiers. | ||
106 | * Note that the patch might still be needed before the going handler | ||
107 | * is called. Module functions can be called even in the GOING state | ||
108 | * until mod->exit() finishes. This is especially important for | ||
109 | * patches that modify semantic of the functions. | ||
100 | */ | 110 | */ |
101 | obj->mod = find_module(obj->name); | 111 | if (mod && mod->klp_alive) |
112 | obj->mod = mod; | ||
113 | |||
102 | mutex_unlock(&module_mutex); | 114 | mutex_unlock(&module_mutex); |
103 | } | 115 | } |
104 | 116 | ||
@@ -248,11 +260,12 @@ static int klp_find_external_symbol(struct module *pmod, const char *name, | |||
248 | /* first, check if it's an exported symbol */ | 260 | /* first, check if it's an exported symbol */ |
249 | preempt_disable(); | 261 | preempt_disable(); |
250 | sym = find_symbol(name, NULL, NULL, true, true); | 262 | sym = find_symbol(name, NULL, NULL, true, true); |
251 | preempt_enable(); | ||
252 | if (sym) { | 263 | if (sym) { |
253 | *addr = sym->value; | 264 | *addr = sym->value; |
265 | preempt_enable(); | ||
254 | return 0; | 266 | return 0; |
255 | } | 267 | } |
268 | preempt_enable(); | ||
256 | 269 | ||
257 | /* otherwise check if it's in another .o within the patch module */ | 270 | /* otherwise check if it's in another .o within the patch module */ |
258 | return klp_find_object_symbol(pmod->name, name, addr); | 271 | return klp_find_object_symbol(pmod->name, name, addr); |
@@ -766,6 +779,7 @@ static int klp_init_object(struct klp_patch *patch, struct klp_object *obj) | |||
766 | return -EINVAL; | 779 | return -EINVAL; |
767 | 780 | ||
768 | obj->state = KLP_DISABLED; | 781 | obj->state = KLP_DISABLED; |
782 | obj->mod = NULL; | ||
769 | 783 | ||
770 | klp_find_object_module(obj); | 784 | klp_find_object_module(obj); |
771 | 785 | ||
@@ -960,6 +974,15 @@ static int klp_module_notify(struct notifier_block *nb, unsigned long action, | |||
960 | 974 | ||
961 | mutex_lock(&klp_mutex); | 975 | mutex_lock(&klp_mutex); |
962 | 976 | ||
977 | /* | ||
978 | * Each module has to know that the notifier has been called. | ||
979 | * We never know what module will get patched by a new patch. | ||
980 | */ | ||
981 | if (action == MODULE_STATE_COMING) | ||
982 | mod->klp_alive = true; | ||
983 | else /* MODULE_STATE_GOING */ | ||
984 | mod->klp_alive = false; | ||
985 | |||
963 | list_for_each_entry(patch, &klp_patches, list) { | 986 | list_for_each_entry(patch, &klp_patches, list) { |
964 | for (obj = patch->objs; obj->funcs; obj++) { | 987 | for (obj = patch->objs; obj->funcs; obj++) { |
965 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) | 988 | if (!klp_is_module(obj) || strcmp(obj->name, mod->name)) |