Re: [PATCH v2 4/4] x86/static_call: Add inline static call implementation for x86-64

Peter Zijlstra
2018-11-27T08:51:10Z

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
}