提交 573ebfa6 编写于 作者: P Paul Mackerras 提交者: Benjamin Herrenschmidt

powerpc: Increase stack redzone for 64-bit userspace to 512 bytes

The new ELFv2 little-endian ABI increases the stack redzone -- the
area below the stack pointer that can be used for storing data --
from 288 bytes to 512 bytes.  This means that we need to allow more
space on the user stack when delivering a signal to a 64-bit process.

To make the code a bit clearer, we define new USER_REDZONE_SIZE and
KERNEL_REDZONE_SIZE symbols in ptrace.h.  For now, we leave the
kernel redzone size at 288 bytes, since increasing it to 512 bytes
would increase the size of interrupt stack frames correspondingly.

Gcc currently only makes use of 288 bytes of redzone even when
compiling for the new little-endian ABI, and the kernel cannot
currently be compiled with the new ABI anyway.

In the future, hopefully gcc will provide an option to control the
amount of redzone used, and then we could reduce it even more.

This also changes the code in arch_compat_alloc_user_space() to
preserve the expanded redzone.  It is not clear why this function would
ever be used on a 64-bit process, though.
Signed-off-by: NPaul Mackerras <paulus@samba.org>
CC: <stable@vger.kernel.org> [v3.13]
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 a95fc585
...@@ -200,10 +200,11 @@ static inline void __user *arch_compat_alloc_user_space(long len) ...@@ -200,10 +200,11 @@ static inline void __user *arch_compat_alloc_user_space(long len)
/* /*
* We can't access below the stack pointer in the 32bit ABI and * We can't access below the stack pointer in the 32bit ABI and
* can access 288 bytes in the 64bit ABI * can access 288 bytes in the 64bit big-endian ABI,
* or 512 bytes with the new ELFv2 little-endian ABI.
*/ */
if (!is_32bit_task()) if (!is_32bit_task())
usp -= 288; usp -= USER_REDZONE_SIZE;
return (void __user *) (usp - len); return (void __user *) (usp - len);
} }
......
...@@ -28,11 +28,23 @@ ...@@ -28,11 +28,23 @@
#ifdef __powerpc64__ #ifdef __powerpc64__
/*
* Size of redzone that userspace is allowed to use below the stack
* pointer. This is 288 in the 64-bit big-endian ELF ABI, and 512 in
* the new ELFv2 little-endian ABI, so we allow the larger amount.
*
* For kernel code we allow a 288-byte redzone, in order to conserve
* kernel stack space; gcc currently only uses 288 bytes, and will
* hopefully allow explicit control of the redzone size in future.
*/
#define USER_REDZONE_SIZE 512
#define KERNEL_REDZONE_SIZE 288
#define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */ #define STACK_FRAME_OVERHEAD 112 /* size of minimum stack frame */
#define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */ #define STACK_FRAME_LR_SAVE 2 /* Location of LR in stack frame */
#define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265) #define STACK_FRAME_REGS_MARKER ASM_CONST(0x7265677368657265)
#define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \ #define STACK_INT_FRAME_SIZE (sizeof(struct pt_regs) + \
STACK_FRAME_OVERHEAD + 288) STACK_FRAME_OVERHEAD + KERNEL_REDZONE_SIZE)
#define STACK_FRAME_MARKER 12 #define STACK_FRAME_MARKER 12
/* Size of dummy stack frame allocated when calling signal handler. */ /* Size of dummy stack frame allocated when calling signal handler. */
...@@ -41,6 +53,8 @@ ...@@ -41,6 +53,8 @@
#else /* __powerpc64__ */ #else /* __powerpc64__ */
#define USER_REDZONE_SIZE 0
#define KERNEL_REDZONE_SIZE 0
#define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */ #define STACK_FRAME_OVERHEAD 16 /* size of minimum stack frame */
#define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */ #define STACK_FRAME_LR_SAVE 1 /* Location of LR in stack frame */
#define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773) #define STACK_FRAME_REGS_MARKER ASM_CONST(0x72656773)
......
...@@ -65,8 +65,8 @@ struct rt_sigframe { ...@@ -65,8 +65,8 @@ struct rt_sigframe {
struct siginfo __user *pinfo; struct siginfo __user *pinfo;
void __user *puc; void __user *puc;
struct siginfo info; struct siginfo info;
/* 64 bit ABI allows for 288 bytes below sp before decrementing it. */ /* New 64 bit little-endian ABI allows redzone of 512 bytes below sp */
char abigap[288]; char abigap[USER_REDZONE_SIZE];
} __attribute__ ((aligned (16))); } __attribute__ ((aligned (16)));
static const char fmt32[] = KERN_INFO \ static const char fmt32[] = KERN_INFO \
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册