uprobes/x86: Introduce push_ret_address()
authorOleg Nesterov <oleg@redhat.com>
Thu, 24 Apr 2014 17:21:38 +0000 (19:21 +0200)
committerOleg Nesterov <oleg@redhat.com>
Wed, 30 Apr 2014 17:10:38 +0000 (19:10 +0200)
Extract the "push return address" code from branch_emulate_op() into
the new simple helper, push_ret_address(). It will have more users.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
arch/x86/kernel/uprobes.c

index a8e1d7e470013c262fb6605da0964c58bbdb14e1..df75913acfc097675f1977a7d243c15ec8305a3b 100644 (file)
@@ -407,6 +407,17 @@ static int default_pre_xol_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
        return 0;
 }
 
+static int push_ret_address(struct pt_regs *regs, unsigned long ip)
+{
+       unsigned long new_sp = regs->sp - sizeof_long();
+
+       if (copy_to_user((void __user *)new_sp, &ip, sizeof_long()))
+               return -EFAULT;
+
+       regs->sp = new_sp;
+       return 0;
+}
+
 /*
  * Adjust the return address pushed by a call insn executed out of line.
  */
@@ -517,7 +528,6 @@ static bool branch_emulate_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
        unsigned long offs = (long)auprobe->branch.offs;
 
        if (branch_is_call(auprobe)) {
-               unsigned long new_sp = regs->sp - sizeof_long();
                /*
                 * If it fails we execute this (mangled, see the comment in
                 * branch_clear_offset) insn out-of-line. In the likely case
@@ -527,9 +537,8 @@ static bool branch_emulate_op(struct arch_uprobe *auprobe, struct pt_regs *regs)
                 *
                 * But there is corner case, see the comment in ->post_xol().
                 */
-               if (copy_to_user((void __user *)new_sp, &new_ip, sizeof_long()))
+               if (push_ret_address(regs, new_ip))
                        return false;
-               regs->sp = new_sp;
        } else if (!check_jmp_cond(auprobe, regs)) {
                offs = 0;
        }