aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/livepatch/transition.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/livepatch/transition.c')
-rw-r--r--kernel/livepatch/transition.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index b004a1fb6032..56add6327736 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -82,6 +82,10 @@ static void klp_complete_transition(void)
82 unsigned int cpu; 82 unsigned int cpu;
83 bool immediate_func = false; 83 bool immediate_func = false;
84 84
85 pr_debug("'%s': completing %s transition\n",
86 klp_transition_patch->mod->name,
87 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
88
85 if (klp_target_state == KLP_UNPATCHED) { 89 if (klp_target_state == KLP_UNPATCHED) {
86 /* 90 /*
87 * All tasks have transitioned to KLP_UNPATCHED so we can now 91 * All tasks have transitioned to KLP_UNPATCHED so we can now
@@ -109,9 +113,6 @@ static void klp_complete_transition(void)
109 } 113 }
110 } 114 }
111 115
112 if (klp_target_state == KLP_UNPATCHED && !immediate_func)
113 module_put(klp_transition_patch->mod);
114
115 /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ 116 /* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */
116 if (klp_target_state == KLP_PATCHED) 117 if (klp_target_state == KLP_PATCHED)
117 klp_synchronize_transition(); 118 klp_synchronize_transition();
@@ -130,6 +131,27 @@ static void klp_complete_transition(void)
130 } 131 }
131 132
132done: 133done:
134 klp_for_each_object(klp_transition_patch, obj) {
135 if (!klp_is_object_loaded(obj))
136 continue;
137 if (klp_target_state == KLP_PATCHED)
138 klp_post_patch_callback(obj);
139 else if (klp_target_state == KLP_UNPATCHED)
140 klp_post_unpatch_callback(obj);
141 }
142
143 pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
144 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
145
146 /*
147 * See complementary comment in __klp_enable_patch() for why we
148 * keep the module reference for immediate patches.
149 */
150 if (!klp_transition_patch->immediate && !immediate_func &&
151 klp_target_state == KLP_UNPATCHED) {
152 module_put(klp_transition_patch->mod);
153 }
154
133 klp_target_state = KLP_UNDEFINED; 155 klp_target_state = KLP_UNDEFINED;
134 klp_transition_patch = NULL; 156 klp_transition_patch = NULL;
135} 157}
@@ -145,6 +167,9 @@ void klp_cancel_transition(void)
145 if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED)) 167 if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED))
146 return; 168 return;
147 169
170 pr_debug("'%s': canceling patching transition, going to unpatch\n",
171 klp_transition_patch->mod->name);
172
148 klp_target_state = KLP_UNPATCHED; 173 klp_target_state = KLP_UNPATCHED;
149 klp_complete_transition(); 174 klp_complete_transition();
150} 175}
@@ -408,9 +433,6 @@ void klp_try_complete_transition(void)
408 } 433 }
409 434
410success: 435success:
411 pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
412 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
413
414 /* we're done, now cleanup the data structures */ 436 /* we're done, now cleanup the data structures */
415 klp_complete_transition(); 437 klp_complete_transition();
416} 438}
@@ -426,7 +448,8 @@ void klp_start_transition(void)
426 448
427 WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED); 449 WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
428 450
429 pr_notice("'%s': %s...\n", klp_transition_patch->mod->name, 451 pr_notice("'%s': starting %s transition\n",
452 klp_transition_patch->mod->name,
430 klp_target_state == KLP_PATCHED ? "patching" : "unpatching"); 453 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
431 454
432 /* 455 /*
@@ -482,6 +505,9 @@ void klp_init_transition(struct klp_patch *patch, int state)
482 */ 505 */
483 klp_target_state = state; 506 klp_target_state = state;
484 507
508 pr_debug("'%s': initializing %s transition\n", patch->mod->name,
509 klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
510
485 /* 511 /*
486 * If the patch can be applied or reverted immediately, skip the 512 * If the patch can be applied or reverted immediately, skip the
487 * per-task transitions. 513 * per-task transitions.
@@ -547,6 +573,11 @@ void klp_reverse_transition(void)
547 unsigned int cpu; 573 unsigned int cpu;
548 struct task_struct *g, *task; 574 struct task_struct *g, *task;
549 575
576 pr_debug("'%s': reversing transition from %s\n",
577 klp_transition_patch->mod->name,
578 klp_target_state == KLP_PATCHED ? "patching to unpatching" :
579 "unpatching to patching");
580
550 klp_transition_patch->enabled = !klp_transition_patch->enabled; 581 klp_transition_patch->enabled = !klp_transition_patch->enabled;
551 582
552 klp_target_state = !klp_target_state; 583 klp_target_state = !klp_target_state;