mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
Livepatching changes for 6.10
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEESH4wyp42V4tXvYsjUqAMR0iAlPIFAmZEoUMACgkQUqAMR0iA lPIVLQ/+KpblzXPdOC32A5q8/l+stX3pacly2vm+2+Px9TDhH8cZzOuH1Z8422Xz MlILtDQACvqkTIPgKvgVQaaQmggFUeEruv86dHVXrPVTnuHXCz9xu2aljxZQFMd1 Q4ocF0ibWqb+PLKybyDyKEaLdhyDo7wa5I28pkGqCIWbVXMS6YVZ7Ji4QOzg3ahI q+CX9Dk8HqF+fmhVSJm3CbiQiFO3cgbFoO/WZpvpALZuBmzSuxcpGKgyPvi5Z0wh VsWEgL4Juo5YhiHI/G1rxhqGx5At0a0X1xpoYwyE4MegWmOJqG/HTNl6Y/Wn9TRf Tg5DByMTw+EvX2Z57eumC1yfitsuNjpnERL4rXBtgODBtSbC4va+Rd1pA/Y2ezfj estg76XietkmIYVuvJz8VAWXp+F+Ui7WV3grZm++QhO9p4z/HtZQlUqwB5RSRuel 7MdJlTKvT469CGLPcJJ+QA1ULxj93Pb/r+e9mmFX194YoUgMHFWAPtuHViM3e7F+ ORPBYPBGwUzJftP4nWyU+P2ApTMS7yMWksBNy+IF2SKSczklFf8DwCp5hXPYeqAn Mcm9vty205nQaaF+l2xSGLV8nscw3wKwNmrqn8ORHrHQdnMhT8LyPmsAre84bu/h m5reqn6ASEt5iKL0gWUPzLJGEf9Q1wG+s4n1wb5HVD1eCUCmbzs= =RBMT -----END PGP SIGNATURE----- Merge tag 'livepatching-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching Pull livepatching update from Petr Mladek: - Use more informative names for the livepatch transition states * tag 'livepatching-for-6.10' of git://git.kernel.org/pub/scm/linux/kernel/git/livepatching/livepatching: livepatch: Rename KLP_* to KLP_TRANSITION_*
This commit is contained in:
commit
8c06da67d0
@ -18,9 +18,9 @@
|
||||
#if IS_ENABLED(CONFIG_LIVEPATCH)
|
||||
|
||||
/* task patch states */
|
||||
#define KLP_UNDEFINED -1
|
||||
#define KLP_UNPATCHED 0
|
||||
#define KLP_PATCHED 1
|
||||
#define KLP_TRANSITION_IDLE -1
|
||||
#define KLP_TRANSITION_UNPATCHED 0
|
||||
#define KLP_TRANSITION_PATCHED 1
|
||||
|
||||
/**
|
||||
* struct klp_func - function structure for live patching
|
||||
|
@ -199,7 +199,7 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = {
|
||||
.trace_recursion = 0,
|
||||
#endif
|
||||
#ifdef CONFIG_LIVEPATCH
|
||||
.patch_state = KLP_UNDEFINED,
|
||||
.patch_state = KLP_TRANSITION_IDLE,
|
||||
#endif
|
||||
#ifdef CONFIG_SECURITY
|
||||
.security = NULL,
|
||||
|
@ -973,7 +973,7 @@ static int __klp_disable_patch(struct klp_patch *patch)
|
||||
if (klp_transition_patch)
|
||||
return -EBUSY;
|
||||
|
||||
klp_init_transition(patch, KLP_UNPATCHED);
|
||||
klp_init_transition(patch, KLP_TRANSITION_UNPATCHED);
|
||||
|
||||
klp_for_each_object(patch, obj)
|
||||
if (obj->patched)
|
||||
@ -1008,7 +1008,7 @@ static int __klp_enable_patch(struct klp_patch *patch)
|
||||
|
||||
pr_notice("enabling patch '%s'\n", patch->mod->name);
|
||||
|
||||
klp_init_transition(patch, KLP_PATCHED);
|
||||
klp_init_transition(patch, KLP_TRANSITION_PATCHED);
|
||||
|
||||
/*
|
||||
* Enforce the order of the func->transition writes in
|
||||
|
@ -95,9 +95,9 @@ static void notrace klp_ftrace_handler(unsigned long ip,
|
||||
|
||||
patch_state = current->patch_state;
|
||||
|
||||
WARN_ON_ONCE(patch_state == KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(patch_state == KLP_TRANSITION_IDLE);
|
||||
|
||||
if (patch_state == KLP_UNPATCHED) {
|
||||
if (patch_state == KLP_TRANSITION_UNPATCHED) {
|
||||
/*
|
||||
* Use the previously patched version of the function.
|
||||
* If no previous patches exist, continue with the
|
||||
|
@ -23,7 +23,7 @@ static DEFINE_PER_CPU(unsigned long[MAX_STACK_ENTRIES], klp_stack_entries);
|
||||
|
||||
struct klp_patch *klp_transition_patch;
|
||||
|
||||
static int klp_target_state = KLP_UNDEFINED;
|
||||
static int klp_target_state = KLP_TRANSITION_IDLE;
|
||||
|
||||
static unsigned int klp_signals_cnt;
|
||||
|
||||
@ -96,16 +96,16 @@ static void klp_complete_transition(void)
|
||||
|
||||
pr_debug("'%s': completing %s transition\n",
|
||||
klp_transition_patch->mod->name,
|
||||
klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
|
||||
klp_target_state == KLP_TRANSITION_PATCHED ? "patching" : "unpatching");
|
||||
|
||||
if (klp_transition_patch->replace && klp_target_state == KLP_PATCHED) {
|
||||
if (klp_transition_patch->replace && klp_target_state == KLP_TRANSITION_PATCHED) {
|
||||
klp_unpatch_replaced_patches(klp_transition_patch);
|
||||
klp_discard_nops(klp_transition_patch);
|
||||
}
|
||||
|
||||
if (klp_target_state == KLP_UNPATCHED) {
|
||||
if (klp_target_state == KLP_TRANSITION_UNPATCHED) {
|
||||
/*
|
||||
* All tasks have transitioned to KLP_UNPATCHED so we can now
|
||||
* All tasks have transitioned to KLP_TRANSITION_UNPATCHED so we can now
|
||||
* remove the new functions from the func_stack.
|
||||
*/
|
||||
klp_unpatch_objects(klp_transition_patch);
|
||||
@ -123,36 +123,36 @@ static void klp_complete_transition(void)
|
||||
klp_for_each_func(obj, func)
|
||||
func->transition = false;
|
||||
|
||||
/* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */
|
||||
if (klp_target_state == KLP_PATCHED)
|
||||
/* Prevent klp_ftrace_handler() from seeing KLP_TRANSITION_IDLE state */
|
||||
if (klp_target_state == KLP_TRANSITION_PATCHED)
|
||||
klp_synchronize_transition();
|
||||
|
||||
read_lock(&tasklist_lock);
|
||||
for_each_process_thread(g, task) {
|
||||
WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING));
|
||||
task->patch_state = KLP_UNDEFINED;
|
||||
task->patch_state = KLP_TRANSITION_IDLE;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
task = idle_task(cpu);
|
||||
WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING));
|
||||
task->patch_state = KLP_UNDEFINED;
|
||||
task->patch_state = KLP_TRANSITION_IDLE;
|
||||
}
|
||||
|
||||
klp_for_each_object(klp_transition_patch, obj) {
|
||||
if (!klp_is_object_loaded(obj))
|
||||
continue;
|
||||
if (klp_target_state == KLP_PATCHED)
|
||||
if (klp_target_state == KLP_TRANSITION_PATCHED)
|
||||
klp_post_patch_callback(obj);
|
||||
else if (klp_target_state == KLP_UNPATCHED)
|
||||
else if (klp_target_state == KLP_TRANSITION_UNPATCHED)
|
||||
klp_post_unpatch_callback(obj);
|
||||
}
|
||||
|
||||
pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name,
|
||||
klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
|
||||
klp_target_state == KLP_TRANSITION_PATCHED ? "patching" : "unpatching");
|
||||
|
||||
klp_target_state = KLP_UNDEFINED;
|
||||
klp_target_state = KLP_TRANSITION_IDLE;
|
||||
klp_transition_patch = NULL;
|
||||
}
|
||||
|
||||
@ -164,13 +164,13 @@ static void klp_complete_transition(void)
|
||||
*/
|
||||
void klp_cancel_transition(void)
|
||||
{
|
||||
if (WARN_ON_ONCE(klp_target_state != KLP_PATCHED))
|
||||
if (WARN_ON_ONCE(klp_target_state != KLP_TRANSITION_PATCHED))
|
||||
return;
|
||||
|
||||
pr_debug("'%s': canceling patching transition, going to unpatch\n",
|
||||
klp_transition_patch->mod->name);
|
||||
|
||||
klp_target_state = KLP_UNPATCHED;
|
||||
klp_target_state = KLP_TRANSITION_UNPATCHED;
|
||||
klp_complete_transition();
|
||||
}
|
||||
|
||||
@ -218,7 +218,7 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries,
|
||||
struct klp_ops *ops;
|
||||
int i;
|
||||
|
||||
if (klp_target_state == KLP_UNPATCHED) {
|
||||
if (klp_target_state == KLP_TRANSITION_UNPATCHED) {
|
||||
/*
|
||||
* Check for the to-be-unpatched function
|
||||
* (the func itself).
|
||||
@ -455,7 +455,7 @@ void klp_try_complete_transition(void)
|
||||
struct klp_patch *patch;
|
||||
bool complete = true;
|
||||
|
||||
WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(klp_target_state == KLP_TRANSITION_IDLE);
|
||||
|
||||
/*
|
||||
* Try to switch the tasks to the target patch state by walking their
|
||||
@ -532,11 +532,11 @@ void klp_start_transition(void)
|
||||
struct task_struct *g, *task;
|
||||
unsigned int cpu;
|
||||
|
||||
WARN_ON_ONCE(klp_target_state == KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(klp_target_state == KLP_TRANSITION_IDLE);
|
||||
|
||||
pr_notice("'%s': starting %s transition\n",
|
||||
klp_transition_patch->mod->name,
|
||||
klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
|
||||
klp_target_state == KLP_TRANSITION_PATCHED ? "patching" : "unpatching");
|
||||
|
||||
/*
|
||||
* Mark all normal tasks as needing a patch state update. They'll
|
||||
@ -578,7 +578,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
|
||||
struct klp_func *func;
|
||||
int initial_state = !state;
|
||||
|
||||
WARN_ON_ONCE(klp_target_state != KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(klp_target_state != KLP_TRANSITION_IDLE);
|
||||
|
||||
klp_transition_patch = patch;
|
||||
|
||||
@ -589,7 +589,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
|
||||
klp_target_state = state;
|
||||
|
||||
pr_debug("'%s': initializing %s transition\n", patch->mod->name,
|
||||
klp_target_state == KLP_PATCHED ? "patching" : "unpatching");
|
||||
klp_target_state == KLP_TRANSITION_PATCHED ? "patching" : "unpatching");
|
||||
|
||||
/*
|
||||
* Initialize all tasks to the initial patch state to prepare them for
|
||||
@ -597,7 +597,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
|
||||
*/
|
||||
read_lock(&tasklist_lock);
|
||||
for_each_process_thread(g, task) {
|
||||
WARN_ON_ONCE(task->patch_state != KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(task->patch_state != KLP_TRANSITION_IDLE);
|
||||
task->patch_state = initial_state;
|
||||
}
|
||||
read_unlock(&tasklist_lock);
|
||||
@ -607,19 +607,19 @@ void klp_init_transition(struct klp_patch *patch, int state)
|
||||
*/
|
||||
for_each_possible_cpu(cpu) {
|
||||
task = idle_task(cpu);
|
||||
WARN_ON_ONCE(task->patch_state != KLP_UNDEFINED);
|
||||
WARN_ON_ONCE(task->patch_state != KLP_TRANSITION_IDLE);
|
||||
task->patch_state = initial_state;
|
||||
}
|
||||
|
||||
/*
|
||||
* Enforce the order of the task->patch_state initializations and the
|
||||
* func->transition updates to ensure that klp_ftrace_handler() doesn't
|
||||
* see a func in transition with a task->patch_state of KLP_UNDEFINED.
|
||||
* see a func in transition with a task->patch_state of KLP_TRANSITION_IDLE.
|
||||
*
|
||||
* Also enforce the order of the klp_target_state write and future
|
||||
* TIF_PATCH_PENDING writes to ensure klp_update_patch_state() and
|
||||
* __klp_sched_try_switch() don't set a task->patch_state to
|
||||
* KLP_UNDEFINED.
|
||||
* KLP_TRANSITION_IDLE.
|
||||
*/
|
||||
smp_wmb();
|
||||
|
||||
@ -652,7 +652,7 @@ void klp_reverse_transition(void)
|
||||
|
||||
pr_debug("'%s': reversing transition from %s\n",
|
||||
klp_transition_patch->mod->name,
|
||||
klp_target_state == KLP_PATCHED ? "patching to unpatching" :
|
||||
klp_target_state == KLP_TRANSITION_PATCHED ? "patching to unpatching" :
|
||||
"unpatching to patching");
|
||||
|
||||
/*
|
||||
@ -741,7 +741,7 @@ void klp_force_transition(void)
|
||||
klp_update_patch_state(idle_task(cpu));
|
||||
|
||||
/* Set forced flag for patches being removed. */
|
||||
if (klp_target_state == KLP_UNPATCHED)
|
||||
if (klp_target_state == KLP_TRANSITION_UNPATCHED)
|
||||
klp_transition_patch->forced = true;
|
||||
else if (klp_transition_patch->replace) {
|
||||
klp_for_each_patch(patch) {
|
||||
|
Loading…
Reference in New Issue
Block a user