[PATCH 11/23] sched/scs: Initialize shadow stack on idle thread bringup, not shutdown

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Starting with commit 63acd42c0d49 ("sched/scs: Reset the shadow stack when
idle_task_exit"), the idle thread's shadow stack was reset from the idle
task's context during CPU hot-unplug.  This was fragile: between resetting
the shadow stack and actually stopping the idle task, the shadow stack
did not match the actual call stack.

Clean this up by resetting the idle task's SCS in bringup_cpu().

init_idle() still does scs_task_reset() -- see the comments there.  I
leave this to an SCS maintainer to untangle further.

Cc: Woody Lin <woodylin@xxxxxxxxxx>
Cc: Valentin Schneider <valentin.schneider@xxxxxxx>
Cc: Sami Tolvanen <samitolvanen@xxxxxxxxxx>
Signed-off-by: Andy Lutomirski <luto@xxxxxxxxxx>
---
 kernel/cpu.c        | 3 +++
 kernel/sched/core.c | 9 ++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/cpu.c b/kernel/cpu.c
index 192e43a87407..be16816bb87c 100644
--- a/kernel/cpu.c
+++ b/kernel/cpu.c
@@ -33,6 +33,7 @@
 #include <linux/slab.h>
 #include <linux/percpu-rwsem.h>
 #include <linux/cpuset.h>
+#include <linux/scs.h>
 
 #include <trace/events/power.h>
 #define CREATE_TRACE_POINTS
@@ -587,6 +588,8 @@ static int bringup_cpu(unsigned int cpu)
 	struct task_struct *idle = idle_thread_get(cpu);
 	int ret;
 
+	scs_task_reset(idle);
+
 	/*
 	 * Some architectures have to walk the irq descriptors to
 	 * setup the vector space for the cpu which comes online.
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 917068b0a145..acd52a7d1349 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8621,7 +8621,15 @@ void __init init_idle(struct task_struct *idle, int cpu)
 	idle->flags |= PF_IDLE | PF_KTHREAD | PF_NO_SETAFFINITY;
 	kthread_set_per_cpu(idle, cpu);
 
+	/*
+	 * NB: This is called from sched_init() on the *current* idle thread.
+	 * This seems fragile if not actively incorrect.
+	 *
+	 * Initializing SCS for about-to-be-brought-up CPU idle threads
+	 * is in bringup_cpu(), but that does not cover the boot CPU.
+	 */
 	scs_task_reset(idle);
+
 	kasan_unpoison_task_stack(idle);
 
 #ifdef CONFIG_SMP
@@ -8779,7 +8787,6 @@ void idle_task_exit(void)
 		finish_arch_post_lock_switch();
 	}
 
-	scs_task_reset(current);
 	/* finish_cpu(), as ran on the BP, will clean up the active_mm state */
 }
 
-- 
2.33.1





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux