On Tue, Nov 27, 2018 at 09:43:30AM +0100, Peter Zijlstra wrote: > Now; if I'm not mistaken, the below @site is in fact @regs->ip - 1, no? > > We already patched site with INT3, which is what we just trapped on. So > we could in fact write something like: > > static void static_call_bp_handler(struct pt_regs *regs, void *data) > { > struct static_call_bp_data *scd = data; > > switch (data->type) { > case CALL_INSN: /* emulate CALL instruction */ > regs->sp -= sizeof(unsigned long); > *(unsigned long *)regs->sp = regs->ip + CALL_INSN_SIZE - 1; > regs->ip = data->func; > break; > > case JMP_INSN: /* emulate JMP instruction */ > regs->ip = data->func; > break; > } > }
> handler_data = (struct static_call_bp_data){ > .type = IS_ENABLED(CONFIG_HAVE_STATIC_CALL_INLINE) ? CALL_INSN > : JMP_INSN, > .func = func, > }; Heck; check this: static void static_call_bp_handler(struct pt_regs *regs, void *data) { #ifdef CONFIG_HAVE_STATIC_CALL_INLINE /* emulate CALL instruction */ regs->sp -= sizeof(unsigned long); *(unsigned long *)regs->sp = regs->ip + CALL_INSN_SIZE - 1; regs->ip = data; #else /* !CONFIG_HAVE_STATIC_CALL_INLINE */ /* emulate JMP instruction */ regs->ip = data; #endif }