Commit 63289e7d authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc: align stack to 2 * THREAD_SIZE with VMAP_STACK

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: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/60e9ae86b7d2cdcf21468787076d345663648f46.1576916812.git.christophe.leroy@c-s.fr
parent 02847487
...@@ -22,6 +22,19 @@ ...@@ -22,6 +22,19 @@
#define THREAD_SIZE (1 << THREAD_SHIFT) #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__ #ifndef __ASSEMBLY__
#include <linux/cache.h> #include <linux/cache.h>
#include <asm/processor.h> #include <asm/processor.h>
......
...@@ -140,7 +140,7 @@ arch_initcall(ppc_init); ...@@ -140,7 +140,7 @@ arch_initcall(ppc_init);
static void *__init alloc_stack(void) static void *__init alloc_stack(void)
{ {
void *ptr = memblock_alloc(THREAD_SIZE, THREAD_SIZE); void *ptr = memblock_alloc(THREAD_SIZE, THREAD_ALIGN);
if (!ptr) if (!ptr)
panic("cannot allocate %d bytes for stack at %pS\n", panic("cannot allocate %d bytes for stack at %pS\n",
......
...@@ -633,7 +633,7 @@ static void *__init alloc_stack(unsigned long limit, int cpu) ...@@ -633,7 +633,7 @@ static void *__init alloc_stack(unsigned long limit, int cpu)
BUILD_BUG_ON(STACK_INT_FRAME_SIZE % 16); 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, MEMBLOCK_LOW_LIMIT, limit,
early_cpu_to_node(cpu)); early_cpu_to_node(cpu));
if (!ptr) if (!ptr)
......
...@@ -323,7 +323,7 @@ SECTIONS ...@@ -323,7 +323,7 @@ SECTIONS
#endif #endif
/* The initial task and kernel stack */ /* 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) { .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
PAGE_ALIGNED_DATA(PAGE_SIZE) PAGE_ALIGNED_DATA(PAGE_SIZE)
......
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