uprobes/x86: Shift "insn_complete" from branch_setup_xol_ops() to uprobe_init_insn()
authorOleg Nesterov <oleg@redhat.com>
Sat, 19 Apr 2014 12:15:27 +0000 (14:15 +0200)
committerOleg Nesterov <oleg@redhat.com>
Wed, 30 Apr 2014 17:10:34 +0000 (19:10 +0200)
Change uprobe_init_insn() to make insn_complete() == T, this makes
other insn_get_*() calls unnecessary.

Signed-off-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Jim Keniston <jkenisto@us.ibm.com>
Acked-by: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
arch/x86/kernel/uprobes.c

index b3b25ddc04fbcaa6e5f8bd87261012ddb040d096..98d7db50f425f6c4a19bdbd117fac747dabc2840 100644 (file)
@@ -209,8 +209,11 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
        u32 volatile *good_insns;
 
        insn_init(insn, auprobe->insn, x86_64);
+       /* has the side-effect of processing the entire instruction */
+       insn_get_length(insn);
+       if (WARN_ON_ONCE(!insn_complete(insn)))
+               return -ENOEXEC;
 
-       insn_get_opcode(insn);
        if (is_prefix_bad(insn))
                return -ENOTSUPP;
 
@@ -283,8 +286,6 @@ handle_riprel_insn(struct arch_uprobe *auprobe, struct insn *insn)
         * is the immediate operand.
         */
        cursor = auprobe->insn + insn_offset_modrm(insn);
-       insn_get_length(insn);
-
        /*
         * Convert from rip-relative addressing to indirect addressing
         * via a scratch register.  Change the r/m field from 0x5 (%rip)
@@ -564,11 +565,6 @@ static int branch_setup_xol_ops(struct arch_uprobe *auprobe, struct insn *insn)
        u8 opc1 = OPCODE1(insn);
        int i;
 
-       /* has the side-effect of processing the entire instruction */
-       insn_get_length(insn);
-       if (WARN_ON_ONCE(!insn_complete(insn)))
-               return -ENOEXEC;
-
        switch (opc1) {
        case 0xeb:      /* jmp 8 */
        case 0xe9:      /* jmp 32 */
@@ -654,7 +650,6 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
                fix_ip = false;
                break;
        case 0xff:
-               insn_get_modrm(&insn);
                switch (MODRM_REG(&insn)) {
                case 2: case 3:                 /* call or lcall, indirect */
                        fix_call = true;