Re: [PATCH v4 09/17] perf/core: Use static_call to optimize perf_guest_info_callbacks

From: Sami Tolvanen
Date: Fri Feb 04 2022 - 12:36:07 EST


On Wed, Feb 2, 2022 at 10:43 AM Sean Christopherson <seanjc@xxxxxxxxxx> wrote:
> > +DEFINE_STATIC_CALL_RET0(__perf_guest_state, *perf_guest_cbs->state);
> > +DEFINE_STATIC_CALL_RET0(__perf_guest_get_ip, *perf_guest_cbs->get_ip);
> > +DEFINE_STATIC_CALL_RET0(__perf_guest_handle_intel_pt_intr, *perf_guest_cbs->handle_intel_pt_intr);
>
> Using __static_call_return0() makes clang's CFI sad on arm64 due to the resulting
> function prototype mistmatch, which IIUC, is verified by clang's __cfi_check()
> for indirect calls, i.e. architectures without CONFIG_HAVE_STATIC_CALL.
>
> We could fudge around the issue by using stubs, massaging prototypes, etc..., but
> that means doing that for every arch-agnostic user of __static_call_return0().
>
> Any clever ideas? Can we do something like generate a unique function for every
> DEFINE_STATIC_CALL_RET0 for CONFIG_HAVE_STATIC_CALL=n, e.g. using typeof() to
> get the prototype?

I'm not sure there's a clever fix for this. On architectures without
HAVE_STATIC_CALL, this is an indirect call to a function with a
mismatching type, which CFI is intended to catch.

The obvious way to solve the problem would be to use a stub function
with the correct type, which I agree, isn't going to scale. You can
alternatively check if .func points to __static_call_return0 and not
make the indirect call if it does. If neither of these options are
feasible, you can disable CFI checking in the functions that have
these static calls using the __nocfi attribute.

Kees, any thoughts?

Sami