diff options
Diffstat (limited to 'kernel/livepatch/transition.c')
-rw-r--r-- | kernel/livepatch/transition.c | 49 |
1 files changed, 5 insertions, 44 deletions
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index be5bfa533ee8..7c6631e693bc 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c | |||
@@ -82,7 +82,6 @@ static void klp_complete_transition(void) | |||
82 | struct klp_func *func; | 82 | struct klp_func *func; |
83 | struct task_struct *g, *task; | 83 | struct task_struct *g, *task; |
84 | unsigned int cpu; | 84 | unsigned int cpu; |
85 | bool immediate_func = false; | ||
86 | 85 | ||
87 | pr_debug("'%s': completing %s transition\n", | 86 | pr_debug("'%s': completing %s transition\n", |
88 | klp_transition_patch->mod->name, | 87 | klp_transition_patch->mod->name, |
@@ -104,16 +103,9 @@ static void klp_complete_transition(void) | |||
104 | klp_synchronize_transition(); | 103 | klp_synchronize_transition(); |
105 | } | 104 | } |
106 | 105 | ||
107 | if (klp_transition_patch->immediate) | 106 | klp_for_each_object(klp_transition_patch, obj) |
108 | goto done; | 107 | klp_for_each_func(obj, func) |
109 | |||
110 | klp_for_each_object(klp_transition_patch, obj) { | ||
111 | klp_for_each_func(obj, func) { | ||
112 | func->transition = false; | 108 | func->transition = false; |
113 | if (func->immediate) | ||
114 | immediate_func = true; | ||
115 | } | ||
116 | } | ||
117 | 109 | ||
118 | /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ | 110 | /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ |
119 | if (klp_target_state == KLP_PATCHED) | 111 | if (klp_target_state == KLP_PATCHED) |
@@ -132,7 +124,6 @@ static void klp_complete_transition(void) | |||
132 | task->patch_state = KLP_UNDEFINED; | 124 | task->patch_state = KLP_UNDEFINED; |
133 | } | 125 | } |
134 | 126 | ||
135 | done: | ||
136 | klp_for_each_object(klp_transition_patch, obj) { | 127 | klp_for_each_object(klp_transition_patch, obj) { |
137 | if (!klp_is_object_loaded(obj)) | 128 | if (!klp_is_object_loaded(obj)) |
138 | continue; | 129 | continue; |
@@ -146,16 +137,11 @@ done: | |||
146 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); | 137 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); |
147 | 138 | ||
148 | /* | 139 | /* |
149 | * See complementary comment in __klp_enable_patch() for why we | 140 | * klp_forced set implies unbounded increase of module's ref count if |
150 | * keep the module reference for immediate patches. | 141 | * the module is disabled/enabled in a loop. |
151 | * | ||
152 | * klp_forced or immediate_func set implies unbounded increase of | ||
153 | * module's ref count if the module is disabled/enabled in a loop. | ||
154 | */ | 142 | */ |
155 | if (!klp_forced && !klp_transition_patch->immediate && | 143 | if (!klp_forced && klp_target_state == KLP_UNPATCHED) |
156 | !immediate_func && klp_target_state == KLP_UNPATCHED) { | ||
157 | module_put(klp_transition_patch->mod); | 144 | module_put(klp_transition_patch->mod); |
158 | } | ||
159 | 145 | ||
160 | klp_target_state = KLP_UNDEFINED; | 146 | klp_target_state = KLP_UNDEFINED; |
161 | klp_transition_patch = NULL; | 147 | klp_transition_patch = NULL; |
@@ -223,9 +209,6 @@ static int klp_check_stack_func(struct klp_func *func, | |||
223 | struct klp_ops *ops; | 209 | struct klp_ops *ops; |
224 | int i; | 210 | int i; |
225 | 211 | ||
226 | if (func->immediate) | ||
227 | return 0; | ||
228 | |||
229 | for (i = 0; i < trace->nr_entries; i++) { | 212 | for (i = 0; i < trace->nr_entries; i++) { |
230 | address = trace->entries[i]; | 213 | address = trace->entries[i]; |
231 | 214 | ||
@@ -388,13 +371,6 @@ void klp_try_complete_transition(void) | |||
388 | WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED); | 371 | WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED); |
389 | 372 | ||
390 | /* | 373 | /* |
391 | * If the patch can be applied or reverted immediately, skip the | ||
392 | * per-task transitions. | ||
393 | */ | ||
394 | if (klp_transition_patch->immediate) | ||
395 | goto success; | ||
396 | |||
397 | /* | ||
398 | * Try to switch the tasks to the target patch state by walking their | 374 | * Try to switch the tasks to the target patch state by walking their |
399 | * stacks and looking for any to-be-patched or to-be-unpatched | 375 | * stacks and looking for any to-be-patched or to-be-unpatched |
400 | * functions. If such functions are found on a stack, or if the stack | 376 | * functions. If such functions are found on a stack, or if the stack |
@@ -437,7 +413,6 @@ void klp_try_complete_transition(void) | |||
437 | return; | 413 | return; |
438 | } | 414 | } |
439 | 415 | ||
440 | success: | ||
441 | /* we're done, now cleanup the data structures */ | 416 | /* we're done, now cleanup the data structures */ |
442 | klp_complete_transition(); | 417 | klp_complete_transition(); |
443 | } | 418 | } |
@@ -458,13 +433,6 @@ void klp_start_transition(void) | |||
458 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); | 433 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); |
459 | 434 | ||
460 | /* | 435 | /* |
461 | * If the patch can be applied or reverted immediately, skip the | ||
462 | * per-task transitions. | ||
463 | */ | ||
464 | if (klp_transition_patch->immediate) | ||
465 | return; | ||
466 | |||
467 | /* | ||
468 | * Mark all normal tasks as needing a patch state update. They'll | 436 | * Mark all normal tasks as needing a patch state update. They'll |
469 | * switch either in klp_try_complete_transition() or as they exit the | 437 | * switch either in klp_try_complete_transition() or as they exit the |
470 | * kernel. | 438 | * kernel. |
@@ -514,13 +482,6 @@ void klp_init_transition(struct klp_patch *patch, int state) | |||
514 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); | 482 | klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); |
515 | 483 | ||
516 | /* | 484 | /* |
517 | * If the patch can be applied or reverted immediately, skip the | ||
518 | * per-task transitions. | ||
519 | */ | ||
520 | if (patch->immediate) | ||
521 | return; | ||
522 | |||
523 | /* | ||
524 | * Initialize all tasks to the initial patch state to prepare them for | 485 | * Initialize all tasks to the initial patch state to prepare them for |
525 | * switching to the target state. | 486 | * switching to the target state. |
526 | */ | 487 | */ |