scs: Move scs_overflow_check() out of architecture code
authorWill Deacon <will@kernel.org>
Fri, 15 May 2020 13:56:05 +0000 (14:56 +0100)
committerWill Deacon <will@kernel.org>
Mon, 18 May 2020 16:47:40 +0000 (17:47 +0100)
There is nothing architecture-specific about scs_overflow_check() as
it's just a trivial wrapper around scs_corrupted().

For parity with task_stack_end_corrupted(), rename scs_corrupted() to
task_scs_end_corrupted() and call it from schedule_debug() when
CONFIG_SCHED_STACK_END_CHECK_is enabled, which better reflects its
purpose as a debug feature to catch inadvertent overflow of the SCS.
Finally, remove the unused scs_overflow_check() function entirely.

This has absolutely no impact on architectures that do not support SCS
(currently arm64 only).

Tested-by: Sami Tolvanen <samitolvanen@google.com>
Reviewed-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/scs.h
arch/arm64/kernel/process.c
arch/arm64/kernel/scs.c
include/linux/scs.h
kernel/sched/core.c
kernel/scs.c

index d46efdd2060ac9e707bf740700f10a926897abfc..eaa2cd92e4c10122f27e731a77f2a1b15e656ae6 100644 (file)
        .endm
 #endif /* CONFIG_SHADOW_CALL_STACK */
 
-#else /* __ASSEMBLY__ */
-
-#include <linux/scs.h>
-
-#ifdef CONFIG_SHADOW_CALL_STACK
-
-static inline void scs_overflow_check(struct task_struct *tsk)
-{
-       if (unlikely(scs_corrupted(tsk)))
-               panic("corrupted shadow stack detected inside scheduler\n");
-}
-
-#else /* CONFIG_SHADOW_CALL_STACK */
-
-static inline void scs_overflow_check(struct task_struct *tsk) {}
-
-#endif /* CONFIG_SHADOW_CALL_STACK */
-
 #endif /* __ASSEMBLY __ */
 
 #endif /* _ASM_SCS_H */
index a35d3318492c31e97856b3625b436aab84fb1f5c..56be4cbf771f604a849f958382aec9acdf4e837f 100644 (file)
@@ -52,7 +52,6 @@
 #include <asm/mmu_context.h>
 #include <asm/processor.h>
 #include <asm/pointer_auth.h>
-#include <asm/scs.h>
 #include <asm/stacktrace.h>
 
 #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK)
@@ -516,7 +515,6 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev,
        entry_task_switch(next);
        uao_thread_switch(next);
        ssbs_thread_switch(next);
-       scs_overflow_check(next);
 
        /*
         * Complete any pending TLB or cache maintenance on this CPU in case
index adc97f826faba1f644289482d19990432a03aff0..955875dff9e17683c61d7bf16dcd3150a1911a9b 100644 (file)
@@ -6,7 +6,7 @@
  */
 
 #include <linux/percpu.h>
-#include <asm/scs.h>
+#include <linux/scs.h>
 
 /* Allocate a static per-CPU shadow stack */
 #define DEFINE_SCS(name)                                               \
index 0eb2485ef832222f14e94590931d10765d286168..2fd3df50e93ee931d94b243920818ea61d2feb18 100644 (file)
@@ -47,7 +47,7 @@ static inline unsigned long *__scs_magic(void *s)
        return (unsigned long *)(s + SCS_SIZE) - 1;
 }
 
-static inline bool scs_corrupted(struct task_struct *tsk)
+static inline bool task_scs_end_corrupted(struct task_struct *tsk)
 {
        unsigned long *magic = __scs_magic(task_scs(tsk));
        unsigned long sz = task_scs_sp(tsk) - task_scs(tsk);
@@ -60,8 +60,8 @@ static inline bool scs_corrupted(struct task_struct *tsk)
 static inline void scs_init(void) {}
 static inline void scs_task_reset(struct task_struct *tsk) {}
 static inline int scs_prepare(struct task_struct *tsk, int node) { return 0; }
-static inline bool scs_corrupted(struct task_struct *tsk) { return false; }
 static inline void scs_release(struct task_struct *tsk) {}
+static inline bool task_scs_end_corrupted(struct task_struct *tsk) { return false; }
 
 #endif /* CONFIG_SHADOW_CALL_STACK */
 
index 934e03cfaec7559e18eec57b336d2930334fefce..a1d815a11b9037966f876540645f00d29dfeca25 100644 (file)
@@ -3878,6 +3878,9 @@ static inline void schedule_debug(struct task_struct *prev, bool preempt)
 #ifdef CONFIG_SCHED_STACK_END_CHECK
        if (task_stack_end_corrupted(prev))
                panic("corrupted stack end detected inside scheduler\n");
+
+       if (task_scs_end_corrupted(prev))
+               panic("corrupted shadow stack detected inside scheduler\n");
 #endif
 
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
index aea841cd75863e9f21d499f8276fd3404a600f83..faf0ecd7b8935c8e81bb90d450a3d4081d8c3d68 100644 (file)
@@ -98,7 +98,8 @@ void scs_release(struct task_struct *tsk)
        if (!s)
                return;
 
-       WARN(scs_corrupted(tsk), "corrupted shadow stack detected when freeing task\n");
+       WARN(task_scs_end_corrupted(tsk),
+            "corrupted shadow stack detected when freeing task\n");
        scs_check_usage(tsk);
        scs_free(s);
 }