diff options
| author | Jiri Kosina <jkosina@suse.cz> | 2018-01-31 10:33:52 -0500 |
|---|---|---|
| committer | Jiri Kosina <jkosina@suse.cz> | 2018-01-31 10:36:38 -0500 |
| commit | d05b695c25bf0d704c74e0e1375de893531b9424 (patch) | |
| tree | 793ac54576aa7f8316579aa0123a3879273193cd /kernel/livepatch | |
| parent | 8869016d3a58cbe7c31c70f4f008a92122b271c7 (diff) | |
| parent | d0807da78e11d46f18399cbf8c4028c731346766 (diff) | |
Merge branch 'for-4.16/remove-immediate' into for-linus
Pull 'immediate' feature removal from Miroslav Benes.
Diffstat (limited to 'kernel/livepatch')
| -rw-r--r-- | kernel/livepatch/core.c | 12 | ||||
| -rw-r--r-- | kernel/livepatch/transition.c | 49 |
2 files changed, 6 insertions, 55 deletions
diff --git a/kernel/livepatch/core.c b/kernel/livepatch/core.c index 8fd8e8f126da..3a4656fb7047 100644 --- a/kernel/livepatch/core.c +++ b/kernel/livepatch/core.c | |||
| @@ -366,11 +366,6 @@ static int __klp_enable_patch(struct klp_patch *patch) | |||
| 366 | /* | 366 | /* |
| 367 | * A reference is taken on the patch module to prevent it from being | 367 | * A reference is taken on the patch module to prevent it from being |
| 368 | * unloaded. | 368 | * unloaded. |
| 369 | * | ||
| 370 | * Note: For immediate (no consistency model) patches we don't allow | ||
| 371 | * patch modules to unload since there is no safe/sane method to | ||
| 372 | * determine if a thread is still running in the patched code contained | ||
| 373 | * in the patch module once the ftrace registration is successful. | ||
| 374 | */ | 369 | */ |
| 375 | if (!try_module_get(patch->mod)) | 370 | if (!try_module_get(patch->mod)) |
| 376 | return -ENODEV; | 371 | return -ENODEV; |
| @@ -894,12 +889,7 @@ int klp_register_patch(struct klp_patch *patch) | |||
| 894 | if (!klp_initialized()) | 889 | if (!klp_initialized()) |
| 895 | return -ENODEV; | 890 | return -ENODEV; |
| 896 | 891 | ||
| 897 | /* | 892 | if (!klp_have_reliable_stack()) { |
| 898 | * Architectures without reliable stack traces have to set | ||
| 899 | * patch->immediate because there's currently no way to patch kthreads | ||
| 900 | * with the consistency model. | ||
| 901 | */ | ||
| 902 | if (!klp_have_reliable_stack() && !patch->immediate) { | ||
| 903 | pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); | 893 | pr_err("This architecture doesn't have support for the livepatch consistency model.\n"); |
| 904 | return -ENOSYS; | 894 | return -ENOSYS; |
| 905 | } | 895 | } |
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 | */ |
