Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _LINUX_INDIRECT_CALL_WRAPPER_H
0003 #define _LINUX_INDIRECT_CALL_WRAPPER_H
0004 
0005 #ifdef CONFIG_RETPOLINE
0006 
0007 /*
0008  * INDIRECT_CALL_$NR - wrapper for indirect calls with $NR known builtin
0009  *  @f: function pointer
0010  *  @f$NR: builtin functions names, up to $NR of them
0011  *  @__VA_ARGS__: arguments for @f
0012  *
0013  * Avoid retpoline overhead for known builtin, checking @f vs each of them and
0014  * eventually invoking directly the builtin function. The functions are check
0015  * in the given order. Fallback to the indirect call.
0016  */
0017 #define INDIRECT_CALL_1(f, f1, ...)                 \
0018     ({                              \
0019         likely(f == f1) ? f1(__VA_ARGS__) : f(__VA_ARGS__); \
0020     })
0021 #define INDIRECT_CALL_2(f, f2, f1, ...)                 \
0022     ({                              \
0023         likely(f == f2) ? f2(__VA_ARGS__) :         \
0024                   INDIRECT_CALL_1(f, f1, __VA_ARGS__);  \
0025     })
0026 #define INDIRECT_CALL_3(f, f3, f2, f1, ...)                 \
0027     ({                                  \
0028         likely(f == f3) ? f3(__VA_ARGS__) :             \
0029                   INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__);  \
0030     })
0031 #define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...)                 \
0032     ({                                  \
0033         likely(f == f4) ? f4(__VA_ARGS__) :             \
0034                   INDIRECT_CALL_3(f, f3, f2, f1, __VA_ARGS__);  \
0035     })
0036 
0037 #define INDIRECT_CALLABLE_DECLARE(f)    f
0038 #define INDIRECT_CALLABLE_SCOPE
0039 #define EXPORT_INDIRECT_CALLABLE(f) EXPORT_SYMBOL(f)
0040 
0041 #else
0042 #define INDIRECT_CALL_1(f, f1, ...) f(__VA_ARGS__)
0043 #define INDIRECT_CALL_2(f, f2, f1, ...) f(__VA_ARGS__)
0044 #define INDIRECT_CALL_3(f, f3, f2, f1, ...) f(__VA_ARGS__)
0045 #define INDIRECT_CALL_4(f, f4, f3, f2, f1, ...) f(__VA_ARGS__)
0046 #define INDIRECT_CALLABLE_DECLARE(f)
0047 #define INDIRECT_CALLABLE_SCOPE     static
0048 #define EXPORT_INDIRECT_CALLABLE(f)
0049 #endif
0050 
0051 /*
0052  * We can use INDIRECT_CALL_$NR for ipv6 related functions only if ipv6 is
0053  * builtin, this macro simplify dealing with indirect calls with only ipv4/ipv6
0054  * alternatives
0055  */
0056 #if IS_BUILTIN(CONFIG_IPV6)
0057 #define INDIRECT_CALL_INET(f, f2, f1, ...) \
0058     INDIRECT_CALL_2(f, f2, f1, __VA_ARGS__)
0059 #elif IS_ENABLED(CONFIG_INET)
0060 #define INDIRECT_CALL_INET(f, f2, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
0061 #else
0062 #define INDIRECT_CALL_INET(f, f2, f1, ...) f(__VA_ARGS__)
0063 #endif
0064 
0065 #if IS_ENABLED(CONFIG_INET)
0066 #define INDIRECT_CALL_INET_1(f, f1, ...) INDIRECT_CALL_1(f, f1, __VA_ARGS__)
0067 #else
0068 #define INDIRECT_CALL_INET_1(f, f1, ...) f(__VA_ARGS__)
0069 #endif
0070 
0071 #endif