powerpc: align stack to 2 * THREAD_SIZE with VMAP_STACK
authorChristophe Leroy <christophe.leroy@c-s.fr>
Sat, 21 Dec 2019 08:32:28 +0000 (08:32 +0000)
committerMichael Ellerman <mpe@ellerman.id.au>
Sun, 26 Jan 2020 11:15:09 +0000 (22:15 +1100)
In order to ease stack overflow detection, align
stack to 2 * THREAD_SIZE when using VMAP_STACK.
This allows overflow detection using a single bit check.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/60e9ae86b7d2cdcf21468787076d345663648f46.1576916812.git.christophe.leroy@c-s.fr
arch/powerpc/include/asm/thread_info.h
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/vmlinux.lds.S

index 488d5c4..a227074 100644 (file)
 
 #define THREAD_SIZE            (1 << THREAD_SHIFT)
 
+/*
+ * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by
+ * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry
+ * assembly.
+ */
+#ifdef CONFIG_VMAP_STACK
+#define THREAD_ALIGN_SHIFT     (THREAD_SHIFT + 1)
+#else
+#define THREAD_ALIGN_SHIFT     THREAD_SHIFT
+#endif
+
+#define THREAD_ALIGN           (1 << THREAD_ALIGN_SHIFT)
+
 #ifndef __ASSEMBLY__
 #include <linux/cache.h>
 #include <asm/processor.h>
index dcffe92..f014c4f 100644 (file)
@@ -140,7 +140,7 @@ arch_initcall(ppc_init);
 
 static void *__init alloc_stack(void)
 {
-       void *ptr = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+       void *ptr = memblock_alloc(THREAD_SIZE, THREAD_ALIGN);
 
        if (!ptr)
                panic("cannot allocate %d bytes for stack at %pS\n",
index 6104917..e05e6dd 100644 (file)
@@ -633,7 +633,7 @@ static void *__init alloc_stack(unsigned long limit, int cpu)
 
        BUILD_BUG_ON(STACK_INT_FRAME_SIZE % 16);
 
-       ptr = memblock_alloc_try_nid(THREAD_SIZE, THREAD_SIZE,
+       ptr = memblock_alloc_try_nid(THREAD_SIZE, THREAD_ALIGN,
                                     MEMBLOCK_LOW_LIMIT, limit,
                                     early_cpu_to_node(cpu));
        if (!ptr)
index 8834220..b4c89a1 100644 (file)
@@ -323,7 +323,7 @@ SECTIONS
 #endif
 
        /* The initial task and kernel stack */
-       INIT_TASK_DATA_SECTION(THREAD_SIZE)
+       INIT_TASK_DATA_SECTION(THREAD_ALIGN)
 
        .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
                PAGE_ALIGNED_DATA(PAGE_SIZE)