cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

indirect_call_wrapper.h (2280B)


      1/* SPDX-License-Identifier: GPL-2.0 */
      2#ifndef _LINUX_INDIRECT_CALL_WRAPPER_H
      3#define _LINUX_INDIRECT_CALL_WRAPPER_H
      4
      5#ifdef CONFIG_RETPOLINE
      6
      7/*
      8 * INDIRECT_CALL_$NR - wrapper for indirect calls with $NR known builtin
      9 *  @f: function pointer
     10 *  @f$NR: builtin functions names, up to $NR of them
     11 *  @__VA_ARGS__: arguments for @f
     12 *
     13 * Avoid retpoline overhead for known builtin, checking @f vs each of them and
     14 * eventually invoking directly the builtin function. The functions are check
     15 * in the given order. Fallback to the indirect call.
     16 */
     17#define INDIRECT_CALL_1(f, f1, ...)					\
     18	({								\
     19		likely(f == f1) ? f1(__VA_ARGS__) : f(__VA_ARGS__);	\
     20	})
     21#define INDIRECT_CALL_2(f, f2, f1, ...)					\
     22	({								\
     23		likely(f == f2) ? f2(__VA_ARGS__) :			\
     24				  INDIRECT_CALL_1(f, f1, __VA_ARGS__);	\
     25	})
     26#define INDIRECT_CALL_3(f, f3, f2, f1, ...)					\
     27	({									\
     28		likely(f == f3) ? f3(__VA_ARGS__) :				\
     29				  INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__);	\
     30	})
     31#define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...)					\
     32	({									\
     33		likely(f == f4) ? f4(__VA_ARGS__) :				\
     34				  INDIRECT_CALL_3(f, f3, f2, f1, __VA_ARGS__);	\
     35	})
     36
     37#define INDIRECT_CALLABLE_DECLARE(f)	f
     38#define INDIRECT_CALLABLE_SCOPE
     39#define EXPORT_INDIRECT_CALLABLE(f)	EXPORT_SYMBOL(f)
     40
     41#else
     42#define INDIRECT_CALL_1(f, f1, ...) f(__VA_ARGS__)
     43#define INDIRECT_CALL_2(f, f2, f1, ...) f(__VA_ARGS__)
     44#define INDIRECT_CALL_3(f, f3, f2, f1, ...) f(__VA_ARGS__)
     45#define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...) f(__VA_ARGS__)
     46#define INDIRECT_CALLABLE_DECLARE(f)
     47#define INDIRECT_CALLABLE_SCOPE		static
     48#define EXPORT_INDIRECT_CALLABLE(f)
     49#endif
     50
     51/*
     52 * We can use INDIRECT_CALL_$NR for ipv6 related functions only if ipv6 is
     53 * builtin, this macro simplify dealing with indirect calls with only ipv4/ipv6
     54 * alternatives
     55 */
     56#if IS_BUILTIN(CONFIG_IPV6)
     57#define INDIRECT_CALL_INET(f, f2, f1, ...) \
     58	INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__)
     59#elif IS_ENABLED(CONFIG_INET)
     60#define INDIRECT_CALL_INET(f, f2, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
     61#else
     62#define INDIRECT_CALL_INET(f, f2, f1, ...) f(__VA_ARGS__)
     63#endif
     64
     65#if IS_ENABLED(CONFIG_INET)
     66#define INDIRECT_CALL_INET_1(f, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
     67#else
     68#define INDIRECT_CALL_INET_1(f, f1, ...) f(__VA_ARGS__)
     69#endif
     70
     71#endif