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.c41
1 files changed, 41 insertions, 0 deletions
diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c
index 56add6327736..edcfcb8ebb2d 100644
--- a/kernel/livepatch/transition.c
+++ b/kernel/livepatch/transition.c
@@ -608,3 +608,44 @@ void klp_copy_process(struct task_struct *child)
608 608
609 /* TIF_PATCH_PENDING gets copied in setup_thread_stack() */ 609 /* TIF_PATCH_PENDING gets copied in setup_thread_stack() */
610} 610}
611
612/*
613 * Sends a fake signal to all non-kthread tasks with TIF_PATCH_PENDING set.
614 * Kthreads with TIF_PATCH_PENDING set are woken up. Only admin can request this
615 * action currently.
616 */
617void klp_send_signals(void)
618{
619 struct task_struct *g, *task;
620
621 pr_notice("signaling remaining tasks\n");
622
623 read_lock(&tasklist_lock);
624 for_each_process_thread(g, task) {
625 if (!klp_patch_pending(task))
626 continue;
627
628 /*
629 * There is a small race here. We could see TIF_PATCH_PENDING
630 * set and decide to wake up a kthread or send a fake signal.
631 * Meanwhile the task could migrate itself and the action
632 * would be meaningless. It is not serious though.
633 */
634 if (task->flags & PF_KTHREAD) {
635 /*
636 * Wake up a kthread which sleeps interruptedly and
637 * still has not been migrated.
638 */
639 wake_up_state(task, TASK_INTERRUPTIBLE);
640 } else {
641 /*
642 * Send fake signal to all non-kthread tasks which are
643 * still not migrated.
644 */
645 spin_lock_irq(&task->sighand->siglock);
646 signal_wake_up(task, 0);
647 spin_unlock_irq(&task->sighand->siglock);
648 }
649 }
650 read_unlock(&tasklist_lock);
651}