Commit 8c06da67 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'livepatching-for-6.10' of...

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_*
parents a19264d0 d927752f
...@@ -18,9 +18,9 @@ ...@@ -18,9 +18,9 @@
#if IS_ENABLED(CONFIG_LIVEPATCH) #if IS_ENABLED(CONFIG_LIVEPATCH)
/* task patch states */ /* task patch states */
#define KLP_UNDEFINED -1 #define KLP_TRANSITION_IDLE -1
#define KLP_UNPATCHED 0 #define KLP_TRANSITION_UNPATCHED 0
#define KLP_PATCHED 1 #define KLP_TRANSITION_PATCHED 1
/** /**
* struct klp_func - function structure for live patching * struct klp_func - function structure for live patching
......
...@@ -199,7 +199,7 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = { ...@@ -199,7 +199,7 @@ struct task_struct init_task __aligned(L1_CACHE_BYTES) = {
.trace_recursion = 0, .trace_recursion = 0,
#endif #endif
#ifdef CONFIG_LIVEPATCH #ifdef CONFIG_LIVEPATCH
.patch_state = KLP_UNDEFINED, .patch_state = KLP_TRANSITION_IDLE,
#endif #endif
#ifdef CONFIG_SECURITY #ifdef CONFIG_SECURITY
.security = NULL, .security = NULL,
......
...@@ -973,7 +973,7 @@ static int __klp_disable_patch(struct klp_patch *patch) ...@@ -973,7 +973,7 @@ static int __klp_disable_patch(struct klp_patch *patch)
if (klp_transition_patch) if (klp_transition_patch)
return -EBUSY; return -EBUSY;
klp_init_transition(patch, KLP_UNPATCHED); klp_init_transition(patch, KLP_TRANSITION_UNPATCHED);
klp_for_each_object(patch, obj) klp_for_each_object(patch, obj)
if (obj->patched) if (obj->patched)
...@@ -1008,7 +1008,7 @@ static int __klp_enable_patch(struct klp_patch *patch) ...@@ -1008,7 +1008,7 @@ static int __klp_enable_patch(struct klp_patch *patch)
pr_notice("enabling patch '%s'\n", patch->mod->name); 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 * Enforce the order of the func->transition writes in
......
...@@ -95,9 +95,9 @@ static void notrace klp_ftrace_handler(unsigned long ip, ...@@ -95,9 +95,9 @@ static void notrace klp_ftrace_handler(unsigned long ip,
patch_state = current->patch_state; 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. * Use the previously patched version of the function.
* If no previous patches exist, continue with the * If no previous patches exist, continue with the
......
...@@ -23,7 +23,7 @@ static DEFINE_PER_CPU(unsigned long[MAX_STACK_ENTRIES], klp_stack_entries); ...@@ -23,7 +23,7 @@ static DEFINE_PER_CPU(unsigned long[MAX_STACK_ENTRIES], klp_stack_entries);
struct klp_patch *klp_transition_patch; 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; static unsigned int klp_signals_cnt;
...@@ -96,16 +96,16 @@ static void klp_complete_transition(void) ...@@ -96,16 +96,16 @@ static void klp_complete_transition(void)
pr_debug("'%s': completing %s transition\n", pr_debug("'%s': completing %s transition\n",
klp_transition_patch->mod->name, 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_unpatch_replaced_patches(klp_transition_patch);
klp_discard_nops(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. * remove the new functions from the func_stack.
*/ */
klp_unpatch_objects(klp_transition_patch); klp_unpatch_objects(klp_transition_patch);
...@@ -123,36 +123,36 @@ static void klp_complete_transition(void) ...@@ -123,36 +123,36 @@ static void klp_complete_transition(void)
klp_for_each_func(obj, func) klp_for_each_func(obj, func)
func->transition = false; func->transition = false;
/* Prevent klp_ftrace_handler() from seeing KLP_UNDEFINED state */ /* Prevent klp_ftrace_handler() from seeing KLP_TRANSITION_IDLE state */
if (klp_target_state == KLP_PATCHED) if (klp_target_state == KLP_TRANSITION_PATCHED)
klp_synchronize_transition(); klp_synchronize_transition();
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_process_thread(g, task) { for_each_process_thread(g, task) {
WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING)); 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); read_unlock(&tasklist_lock);
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
task = idle_task(cpu); task = idle_task(cpu);
WARN_ON_ONCE(test_tsk_thread_flag(task, TIF_PATCH_PENDING)); 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) { klp_for_each_object(klp_transition_patch, obj) {
if (!klp_is_object_loaded(obj)) if (!klp_is_object_loaded(obj))
continue; continue;
if (klp_target_state == KLP_PATCHED) if (klp_target_state == KLP_TRANSITION_PATCHED)
klp_post_patch_callback(obj); 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); klp_post_unpatch_callback(obj);
} }
pr_notice("'%s': %s complete\n", klp_transition_patch->mod->name, 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; klp_transition_patch = NULL;
} }
...@@ -164,13 +164,13 @@ static void klp_complete_transition(void) ...@@ -164,13 +164,13 @@ static void klp_complete_transition(void)
*/ */
void klp_cancel_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; return;
pr_debug("'%s': canceling patching transition, going to unpatch\n", pr_debug("'%s': canceling patching transition, going to unpatch\n",
klp_transition_patch->mod->name); klp_transition_patch->mod->name);
klp_target_state = KLP_UNPATCHED; klp_target_state = KLP_TRANSITION_UNPATCHED;
klp_complete_transition(); klp_complete_transition();
} }
...@@ -218,7 +218,7 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries, ...@@ -218,7 +218,7 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries,
struct klp_ops *ops; struct klp_ops *ops;
int i; int i;
if (klp_target_state == KLP_UNPATCHED) { if (klp_target_state == KLP_TRANSITION_UNPATCHED) {
/* /*
* Check for the to-be-unpatched function * Check for the to-be-unpatched function
* (the func itself). * (the func itself).
...@@ -455,7 +455,7 @@ void klp_try_complete_transition(void) ...@@ -455,7 +455,7 @@ void klp_try_complete_transition(void)
struct klp_patch *patch; struct klp_patch *patch;
bool complete = true; 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 * Try to switch the tasks to the target patch state by walking their
...@@ -532,11 +532,11 @@ void klp_start_transition(void) ...@@ -532,11 +532,11 @@ void klp_start_transition(void)
struct task_struct *g, *task; struct task_struct *g, *task;
unsigned int cpu; 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", pr_notice("'%s': starting %s transition\n",
klp_transition_patch->mod->name, 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 * 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) ...@@ -578,7 +578,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
struct klp_func *func; struct klp_func *func;
int initial_state = !state; 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; klp_transition_patch = patch;
...@@ -589,7 +589,7 @@ void klp_init_transition(struct klp_patch *patch, int state) ...@@ -589,7 +589,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
klp_target_state = state; klp_target_state = state;
pr_debug("'%s': initializing %s transition\n", patch->mod->name, 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 * 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) ...@@ -597,7 +597,7 @@ void klp_init_transition(struct klp_patch *patch, int state)
*/ */
read_lock(&tasklist_lock); read_lock(&tasklist_lock);
for_each_process_thread(g, task) { 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; task->patch_state = initial_state;
} }
read_unlock(&tasklist_lock); read_unlock(&tasklist_lock);
...@@ -607,19 +607,19 @@ void klp_init_transition(struct klp_patch *patch, int state) ...@@ -607,19 +607,19 @@ void klp_init_transition(struct klp_patch *patch, int state)
*/ */
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
task = idle_task(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; task->patch_state = initial_state;
} }
/* /*
* Enforce the order of the task->patch_state initializations and the * Enforce the order of the task->patch_state initializations and the
* func->transition updates to ensure that klp_ftrace_handler() doesn't * 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 * Also enforce the order of the klp_target_state write and future
* TIF_PATCH_PENDING writes to ensure klp_update_patch_state() and * TIF_PATCH_PENDING writes to ensure klp_update_patch_state() and
* __klp_sched_try_switch() don't set a task->patch_state to * __klp_sched_try_switch() don't set a task->patch_state to
* KLP_UNDEFINED. * KLP_TRANSITION_IDLE.
*/ */
smp_wmb(); smp_wmb();
...@@ -652,7 +652,7 @@ void klp_reverse_transition(void) ...@@ -652,7 +652,7 @@ void klp_reverse_transition(void)
pr_debug("'%s': reversing transition from %s\n", pr_debug("'%s': reversing transition from %s\n",
klp_transition_patch->mod->name, 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"); "unpatching to patching");
/* /*
...@@ -741,7 +741,7 @@ void klp_force_transition(void) ...@@ -741,7 +741,7 @@ void klp_force_transition(void)
klp_update_patch_state(idle_task(cpu)); klp_update_patch_state(idle_task(cpu));
/* Set forced flag for patches being removed. */ /* 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; klp_transition_patch->forced = true;
else if (klp_transition_patch->replace) { else if (klp_transition_patch->replace) {
klp_for_each_patch(patch) { klp_for_each_patch(patch) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment