aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/compat.h
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-02-19 13:06:34 -0500
committerH. Peter Anvin <hpa@zytor.com>2012-02-20 15:52:05 -0500
commitd1a797f388d6d30fa502915d1b9937ed758b7137 (patch)
treeab16d4c32792dea0f0f841d7bce9f37ef962ad79 /arch/x86/include/asm/compat.h
parentc5a373942bbc41698724fc948c74f959f73407e5 (diff)
x32: Handle process creation
Allow an x32 process to be started. Originally-by: H. J. Lu <hjl.tools@gmail.com> Signed-off-by: H. Peter Anvin <hpa@zytor.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Diffstat (limited to 'arch/x86/include/asm/compat.h')
-rw-r--r--arch/x86/include/asm/compat.h26
1 files changed, 24 insertions, 2 deletions
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 7938b84e4506..e7f68b49c01a 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -6,6 +6,7 @@
6 */ 6 */
7#include <linux/types.h> 7#include <linux/types.h>
8#include <linux/sched.h> 8#include <linux/sched.h>
9#include <asm/processor.h>
9#include <asm/user32.h> 10#include <asm/user32.h>
10#include <asm/unistd.h> 11#include <asm/unistd.h>
11 12
@@ -187,7 +188,20 @@ struct compat_shmid64_ds {
187/* 188/*
188 * The type of struct elf_prstatus.pr_reg in compatible core dumps. 189 * The type of struct elf_prstatus.pr_reg in compatible core dumps.
189 */ 190 */
191#ifdef CONFIG_X86_X32_ABI
192typedef struct user_regs_struct compat_elf_gregset_t;
193
194#define PR_REG_SIZE(S) (test_thread_flag(TIF_IA32) ? 68 : 216)
195#define PRSTATUS_SIZE(S) (test_thread_flag(TIF_IA32) ? 144 : 296)
196#define SET_PR_FPVALID(S,V) \
197 do { *(int *) (((void *) &((S)->pr_reg)) + PR_REG_SIZE(0)) = (V); } \
198 while (0)
199
200#define COMPAT_USE_64BIT_TIME \
201 (!!(task_pt_regs(current)->orig_ax & __X32_SYSCALL_BIT))
202#else
190typedef struct user_regs_struct32 compat_elf_gregset_t; 203typedef struct user_regs_struct32 compat_elf_gregset_t;
204#endif
191 205
192/* 206/*
193 * A pointer passed in from user mode. This should not 207 * A pointer passed in from user mode. This should not
@@ -209,8 +223,16 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
209 223
210static inline void __user *arch_compat_alloc_user_space(long len) 224static inline void __user *arch_compat_alloc_user_space(long len)
211{ 225{
212 struct pt_regs *regs = task_pt_regs(current); 226 compat_uptr_t sp;
213 return (void __user *)regs->sp - len; 227
228 if (test_thread_flag(TIF_IA32)) {
229 sp = task_pt_regs(current)->sp;
230 } else {
231 /* -128 for the x32 ABI redzone */
232 sp = percpu_read(old_rsp) - 128;
233 }
234
235 return (void __user *)round_down(sp - len, 16);
214} 236}
215 237
216static inline bool is_compat_task(void) 238static inline bool is_compat_task(void)