new helper: compat_user_stack_pointer()
authorAl Viro <viro@zeniv.linux.org.uk>
Fri, 14 Dec 2012 18:49:35 +0000 (13:49 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Wed, 19 Dec 2012 23:07:40 +0000 (18:07 -0500)
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>
arch/arm64/include/asm/compat.h
arch/x86/include/asm/ptrace.h
include/linux/compat.h

index 37e610d..d9ec402 100644 (file)
@@ -209,10 +209,11 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
        return (u32)(unsigned long)uptr;
 }
 
+#define compat_user_stack_pointer() (current_pt_regs()->compat_sp)
+
 static inline void __user *arch_compat_alloc_user_space(long len)
 {
-       struct pt_regs *regs = task_pt_regs(current);
-       return (void __user *)regs->compat_sp - len;
+       return (void __user *)compat_user_stack_pointer() - len;
 }
 
 struct compat_ipc64_perm {
index 19f16eb..7e560b6 100644 (file)
@@ -203,6 +203,13 @@ static inline bool user_64bit_mode(struct pt_regs *regs)
        return regs->cs == __USER_CS || regs->cs == pv_info.extra_user_64bit_cs;
 #endif
 }
+
+#define current_user_stack_pointer()   this_cpu_read(old_rsp)
+/* ia32 vs. x32 difference */
+#define compat_user_stack_pointer()    \
+       (test_thread_flag(TIF_IA32)     \
+        ? current_pt_regs()->sp        \
+        : this_cpu_read(old_rsp))
 #endif
 
 #ifdef CONFIG_X86_32
index a7877fa..62bb76f 100644 (file)
@@ -65,6 +65,9 @@
 
 #endif /* CONFIG_HAVE_SYSCALL_WRAPPERS */
 
+#ifndef compat_user_stack_pointer
+#define compat_user_stack_pointer() current_user_stack_pointer()
+#endif
 #define compat_jiffies_to_clock_t(x)   \
                (((unsigned long)(x) * COMPAT_USER_HZ) / HZ)