Messages in this thread Patch in this message | | | Date | Tue, 2 Mar 2021 09:54:43 +0100 | From | Peter Zijlstra <> | Subject | Re: [RFC PATCH 1/1] x86/kprobes: Use int3 instead of debug trap for single-step |
| |
On Tue, Mar 02, 2021 at 09:41:32AM +0100, Peter Zijlstra wrote:
> Aside of a few nits:
something like so..
--- a/arch/x86/kernel/kprobes/core.c +++ b/arch/x86/kernel/kprobes/core.c @@ -457,13 +457,20 @@ static void kprobe_emulate_call(struct k } NOKPROBE_SYMBOL(kprobe_emulate_call); -static void kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs) +static __always_inline +void __kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs, bool cond) { unsigned long ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; - ip += p->ainsn.rel32; + if (cond) + ip += p->ainsn.rel32; int3_emulate_jmp(regs, ip); } + +static void kprobe_emulate_jmp(struct kprobe *p, struct pt_regs *regs) +{ + __kprobe_emulate_jmp(p, regs, true); +} NOKPROBE_SYMBOL(kprobe_emulate_jmp); static const unsigned long jcc_mask[6] = { @@ -488,10 +495,7 @@ static void kprobe_emulate_jcc(struct kp if (p->ainsn.jcc.type >= 0xe) match = match && (regs->flags & X86_EFLAGS_ZF); } - if ((match && !invert) || (!match && invert)) - kprobe_emulate_jmp(p, regs); - else - regs->ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; + __kprobe_emulate_jmp(p, regs, (match && !invert) || (!match && invert)); } NOKPROBE_SYMBOL(kprobe_emulate_jcc); @@ -524,10 +528,7 @@ static void kprobe_emulate_loop(struct k else if (p->ainsn.loop.type == 1) /* LOOPE */ match = match && (regs->flags & X86_EFLAGS_ZF); - if (match) - kprobe_emulate_jmp(p, regs); - else - regs->ip = regs->ip - INT3_INSN_SIZE + p->ainsn.size; + __kprobe_emulate_jmp(p, regs, match); } NOKPROBE_SYMBOL(kprobe_emulate_loop); @@ -613,6 +614,12 @@ static int prepare_emulation(struct kpro else p->ainsn.rel32 = *(s32 *)&insn->immediate.value; break; + case 0x70 ... 0x7f: + /* 1 byte conditional jump */ + p->ainsn.emulate_op = kprobe_emulate_jcc; + p->ainsn.jcc.type = opcode & 0xf; + p->ainsn.rel32 = *(char *)insn->immediate.bytes; + break; case 0x0f: opcode = insn->opcode.bytes[1]; if ((opcode & 0xf0) == 0x80) { @@ -667,12 +674,7 @@ static int prepare_emulation(struct kpro #endif break; default: - if ((opcode & 0xf0) == 0x70) { - /* 1 byte conditional jump */ - p->ainsn.emulate_op = kprobe_emulate_jcc; - p->ainsn.jcc.type = opcode & 0xf; - p->ainsn.rel32 = *(char *)insn->immediate.bytes; - } + break; } p->ainsn.size = insn->length;
| |