Merge branch 'linus' into perf/core
[linux-2.6.git] / arch / x86 / kernel / kprobes.c
index 675879b..1bfb6cf 100644 (file)
@@ -126,16 +126,22 @@ static void __kprobes synthesize_reljump(void *from, void *to)
 }
 
 /*
- * Check for the REX prefix which can only exist on X86_64
- * X86_32 always returns 0
+ * Skip the prefixes of the instruction.
  */
-static int __kprobes is_REX_prefix(kprobe_opcode_t *insn)
+static kprobe_opcode_t *__kprobes skip_prefixes(kprobe_opcode_t *insn)
 {
+       insn_attr_t attr;
+
+       attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+       while (inat_is_legacy_prefix(attr)) {
+               insn++;
+               attr = inat_get_opcode_attribute((insn_byte_t)*insn);
+       }
 #ifdef CONFIG_X86_64
-       if ((*insn & 0xf0) == 0x40)
-               return 1;
+       if (inat_is_rex_prefix(attr))
+               insn++;
 #endif
-       return 0;
+       return insn;
 }
 
 /*
@@ -272,6 +278,9 @@ static int __kprobes can_probe(unsigned long paddr)
  */
 static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
 {
+       /* Skip prefixes */
+       insn = skip_prefixes(insn);
+
        switch (*insn) {
        case 0xfa:              /* cli */
        case 0xfb:              /* sti */
@@ -280,13 +289,6 @@ static int __kprobes is_IF_modifier(kprobe_opcode_t *insn)
                return 1;
        }
 
-       /*
-        * on X86_64, 0x40-0x4f are REX prefixes so we need to look
-        * at the next byte instead.. but of course not recurse infinitely
-        */
-       if (is_REX_prefix(insn))
-               return is_IF_modifier(++insn);
-
        return 0;
 }
 
@@ -803,9 +805,8 @@ static void __kprobes resume_execution(struct kprobe *p,
        unsigned long orig_ip = (unsigned long)p->addr;
        kprobe_opcode_t *insn = p->ainsn.insn;
 
-       /*skip the REX prefix*/
-       if (is_REX_prefix(insn))
-               insn++;
+       /* Skip prefixes */
+       insn = skip_prefixes(insn);
 
        regs->flags &= ~X86_EFLAGS_TF;
        switch (*insn) {