aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-12-14 13:49:35 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2012-12-19 18:07:40 -0500
commit9b064fc3f95a8e44e929fdf4d6037334ea03d15b (patch)
treedd1a2a6075667841f88b1ea8b62f4df2e18c3c68
parent5c49574ffd7ac07eae8c3b065d19e6ebc7e4760f (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.h5
-rw-r--r--arch/x86/include/asm/ptrace.h7
-rw-r--r--include/linux/compat.h3
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
212static inline void __user *arch_compat_alloc_user_space(long len) 214static 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
218struct compat_ipc64_perm { 219struct 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