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
}


Reply via email to