diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-14 13:49:35 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-12-19 18:07:40 -0500 |
commit | 9b064fc3f95a8e44e929fdf4d6037334ea03d15b (patch) | |
tree | dd1a2a6075667841f88b1ea8b62f4df2e18c3c68 | |
parent | 5c49574ffd7ac07eae8c3b065d19e6ebc7e4760f (diff) |
new helper: compat_user_stack_pointer()
Compat counterpart of current_user_stack_pointer(); for most of the biarch
architectures those two are identical, but e.g. arm64 and arm use different
registers for stack pointer...
Note that amd64 variants of current_user_stack_pointer/compat_user_stack_pointer
do *not* rely on pt_regs having been through FIXUP_TOP_OF_STACK.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | arch/arm64/include/asm/compat.h | 5 | ||||
-rw-r--r-- | arch/x86/include/asm/ptrace.h | 7 | ||||
-rw-r--r-- | include/linux/compat.h | 3 |
3 files changed, 13 insertions, 2 deletions
diff --git a/arch/arm64/include/asm/compat.h b/arch/arm64/include/asm/compat.h index 37e610dc084e..d9ec40217a27 100644 --- a/arch/arm64/include/asm/compat.h +++ b/arch/arm64/include/asm/compat.h | |||
@@ -209,10 +209,11 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr) | |||
209 | return (u32)(unsigned long)uptr; | 209 | return (u32)(unsigned long)uptr; |
210 | } | 210 | } |
211 | 211 | ||
212 | #define compat_user_stack_pointer() (current_pt_regs()->compat_sp) | ||
213 | |||
212 | static inline void __user *arch_compat_alloc_user_space(long len) | 214 | static inline void __user *arch_compat_alloc_user_space(long len) |
213 | { | 215 | { |
214 | struct pt_regs *regs = task_pt_regs(current); | 216 | return (void __user *)compat_user_stack_pointer() - len; |
215 | return (void __user *)regs->compat_sp - len; | ||
216 | } | 217 | } |
217 | 218 | ||
218 | struct compat_ipc64_perm { | 219 | struct compat_ipc64_perm { |
diff --git a/arch/x86/include/asm/ptrace.h b/arch/x86/include/asm/ptrace.h index 19f16ebaf4fa..7e560b6daf5d 100644 --- a/arch/x86/include/asm/ptrace.h +++ b/arch/x86/include/asm/ptrace.h | |||
@@ -203,6 +203,13 @@ static inline bool user_64bit_mode(struct pt_regs *regs) | |||
203 | return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; | 203 | return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs; |
204 | #endif | 204 | #endif |
205 | } | 205 | } |
206 | |||
207 | #define current_user_stack_pointer() this_cpu_read(old_rsp) | ||
208 | /* ia32 vs. x32 difference */ | ||
209 | #define compat_user_stack_pointer() \ | ||
210 | (test_thread_flag(TIF_IA32) \ | ||
211 | ? current_pt_regs()->sp \ | ||
212 | : this_cpu_read(old_rsp)) | ||
206 | #endif | 213 | #endif |
207 | 214 | ||
208 | #ifdef CONFIG_X86_32 | 215 | #ifdef CONFIG_X86_32 |
diff --git a/include/linux/compat.h b/include/linux/compat.h index a7877fa809fd..62bb76f91baf 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -65,6 +65,9 @@ | |||
65 | 65 | ||
66 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ | 66 | #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */ |
67 | 67 | ||
68 | #ifndef compat_user_stack_pointer | ||
69 | #define compat_user_stack_pointer() current_user_stack_pointer() | ||
70 | #endif | ||
68 | #define compat_jiffies_to_clock_t(x) \ | 71 | #define compat_jiffies_to_clock_t(x) \ |
69 | (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) | 72 | (((unsigned long)(x) * COMPAT_USER_HZ) / HZ) |
70 | 73 | ||