summaryrefslogtreecommitdiffstats
path: root/kernel/livepatch/transition.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/livepatch/transition.c')
-rw-r--r--kernel/livepatch/transition.c49
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
135done:
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
440success:
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 */