Adding support to emulate nop5 as the original uprobe instruction.

Signed-off-by: Jiri Olsa <jo...@kernel.org>
---
 arch/x86/kernel/uprobes.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/arch/x86/kernel/uprobes.c b/arch/x86/kernel/uprobes.c
index 5ee2cce4c63e..1661e0ab2a3d 100644
--- a/arch/x86/kernel/uprobes.c
+++ b/arch/x86/kernel/uprobes.c
@@ -308,6 +308,11 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, 
struct insn *insn, bool
        return -ENOTSUPP;
 }
 
+static int is_nop5_insn(uprobe_opcode_t *insn)
+{
+       return !memcmp(insn, x86_nops[5], 5);
+}
+
 #ifdef CONFIG_X86_64
 
 asm (
@@ -865,6 +870,11 @@ void arch_uprobe_clear_state(struct mm_struct *mm)
        hlist_for_each_entry_safe(tramp, n, &state->head_tramps, node)
                destroy_uprobe_trampoline(tramp);
 }
+
+static bool emulate_nop5_insn(struct arch_uprobe *auprobe)
+{
+       return is_nop5_insn((uprobe_opcode_t *) &auprobe->insn);
+}
 #else /* 32-bit: */
 /*
  * No RIP-relative addressing on 32-bit
@@ -878,6 +888,10 @@ static void riprel_pre_xol(struct arch_uprobe *auprobe, 
struct pt_regs *regs)
 static void riprel_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs)
 {
 }
+static bool emulate_nop5_insn(struct arch_uprobe *auprobe)
+{
+       return false;
+}
 #endif /* CONFIG_X86_64 */
 
 struct uprobe_xol_ops {
@@ -1109,6 +1123,8 @@ static int branch_setup_xol_ops(struct arch_uprobe 
*auprobe, struct insn *insn)
                break;
 
        case 0x0f:
+               if (emulate_nop5_insn(auprobe))
+                       goto setup;
                if (insn->opcode.nbytes != 2)
                        return -ENOSYS;
                /*
-- 
2.49.0


Reply via email to