Messages in this thread | | | Date | Mon, 13 Mar 2023 18:58:36 -0700 | From | Josh Poimboeuf <> | Subject | Re: [RFC][PATCH 1/5] static_call: Make NULL static calls consistent |
| |
On Mon, Mar 13, 2023 at 10:48:58AM -0700, Sami Tolvanen wrote: > On Sun, Mar 12, 2023 at 8:17 AM Peter Zijlstra <peterz@infradead.org> wrote: > > > > On Fri, Mar 10, 2023 at 05:20:04PM -0800, Josh Poimboeuf wrote: > > > 2) Create yet another "tier" of static call implementations, for > > > arches which can have the unfortunate combo of CFI_CLANG + > > > !HAVE_STATIC_CALL. CONFIG_ALMOST_DONT_HAVE_STATIC_CALL? > > > > > > The arch can define ARCH_DEFINE_STATIC_CALL_NOP() which uses inline > > > asm to create a CFI-compliant NOP/BUG/whatever version of the > > > function (insert lots of hand-waving). Is the kcfi hash available > > > to inline asm at build time? > > > > Yes, clang creates magic symbol for everything it sees a declaration > > for. This symbols can be referenced from asm, linking will make it all > > work. > > > > And yes, C sucks, you can't actually create a function definition from a > > type :/ Otherwise this could be trivially fixable. > > Wouldn't creating a separate inline assembly nop function that > references the CFI hash of another function with the correct type > potentially solve this issue like Josh suggested?
Right, I was thinking something like this, where the nop function gets generated by DEFINE_STATIC_CALL().
Completely untested of course...
#define STATIC_CALL_NOP_PREFIX __SCN__ #define STATIC_CALL_NOP(name) __PASTE(STATIC_CALL_NOP_PREFIX, name) #define STATIC_CALL_NOP_STR(name) __stringify(STATIC_CALL_NOP(name))
#define ARCH_DEFINE_STATIC_CALL_NOP(name, func) \ asm(".align 4 \n" \ ".word __kcfi_typeid_" STATIC_CALL_NOP_STR(name) " \n" \ ".globl " STATIC_CALL_NOP_STR(name) " \n" \ STATIC_CALL_NOP_STR(name) ": \n" \ "bti c \n" \ "mov x0, xzr \n" \ "ret \n" \ ".type " STATIC_CALL_NOP_STR(name) ", @function \n" \ ".size " STATIC_CALL_NOP_STR(name) ", . - " STATIC_CALL_NOP_STR(name) " \n")
#define DECLARE_STATIC_CALL(name, func) \ extern struct static_call_key STATIC_CALL_KEY(name); \ extern typeof(func) STATIC_CALL_TRAMP(name) \ extern typeof(func) STATIC_CALL_NOP(name)
#define DEFINE_STATIC_CALL(name, _func, _func_init) \ DECLARE_STATIC_CALL(name, _func); \ ARCH_DEFINE_STATIC_CALL_NOP(name); \ struct static_call_key STATIC_CALL_KEY(name) = { \ .func = _func_init, \ } -- Josh
| |