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

bpf_tracing.h (20600B)


      1/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
      2#ifndef __BPF_TRACING_H__
      3#define __BPF_TRACING_H__
      4
      5/* Scan the ARCH passed in from ARCH env variable (see Makefile) */
      6#if defined(__TARGET_ARCH_x86)
      7	#define bpf_target_x86
      8	#define bpf_target_defined
      9#elif defined(__TARGET_ARCH_s390)
     10	#define bpf_target_s390
     11	#define bpf_target_defined
     12#elif defined(__TARGET_ARCH_arm)
     13	#define bpf_target_arm
     14	#define bpf_target_defined
     15#elif defined(__TARGET_ARCH_arm64)
     16	#define bpf_target_arm64
     17	#define bpf_target_defined
     18#elif defined(__TARGET_ARCH_mips)
     19	#define bpf_target_mips
     20	#define bpf_target_defined
     21#elif defined(__TARGET_ARCH_powerpc)
     22	#define bpf_target_powerpc
     23	#define bpf_target_defined
     24#elif defined(__TARGET_ARCH_sparc)
     25	#define bpf_target_sparc
     26	#define bpf_target_defined
     27#elif defined(__TARGET_ARCH_riscv)
     28	#define bpf_target_riscv
     29	#define bpf_target_defined
     30#elif defined(__TARGET_ARCH_arc)
     31	#define bpf_target_arc
     32	#define bpf_target_defined
     33#else
     34
     35/* Fall back to what the compiler says */
     36#if defined(__x86_64__)
     37	#define bpf_target_x86
     38	#define bpf_target_defined
     39#elif defined(__s390__)
     40	#define bpf_target_s390
     41	#define bpf_target_defined
     42#elif defined(__arm__)
     43	#define bpf_target_arm
     44	#define bpf_target_defined
     45#elif defined(__aarch64__)
     46	#define bpf_target_arm64
     47	#define bpf_target_defined
     48#elif defined(__mips__)
     49	#define bpf_target_mips
     50	#define bpf_target_defined
     51#elif defined(__powerpc__)
     52	#define bpf_target_powerpc
     53	#define bpf_target_defined
     54#elif defined(__sparc__)
     55	#define bpf_target_sparc
     56	#define bpf_target_defined
     57#elif defined(__riscv) && __riscv_xlen == 64
     58	#define bpf_target_riscv
     59	#define bpf_target_defined
     60#elif defined(__arc__)
     61	#define bpf_target_arc
     62	#define bpf_target_defined
     63#endif /* no compiler target */
     64
     65#endif
     66
     67#ifndef __BPF_TARGET_MISSING
     68#define __BPF_TARGET_MISSING "GCC error \"Must specify a BPF target arch via __TARGET_ARCH_xxx\""
     69#endif
     70
     71#if defined(bpf_target_x86)
     72
     73#if defined(__KERNEL__) || defined(__VMLINUX_H__)
     74
     75#define __PT_PARM1_REG di
     76#define __PT_PARM2_REG si
     77#define __PT_PARM3_REG dx
     78#define __PT_PARM4_REG cx
     79#define __PT_PARM5_REG r8
     80#define __PT_RET_REG sp
     81#define __PT_FP_REG bp
     82#define __PT_RC_REG ax
     83#define __PT_SP_REG sp
     84#define __PT_IP_REG ip
     85/* syscall uses r10 for PARM4 */
     86#define PT_REGS_PARM4_SYSCALL(x) ((x)->r10)
     87#define PT_REGS_PARM4_CORE_SYSCALL(x) BPF_CORE_READ(x, r10)
     88
     89#else
     90
     91#ifdef __i386__
     92
     93#define __PT_PARM1_REG eax
     94#define __PT_PARM2_REG edx
     95#define __PT_PARM3_REG ecx
     96/* i386 kernel is built with -mregparm=3 */
     97#define __PT_PARM4_REG __unsupported__
     98#define __PT_PARM5_REG __unsupported__
     99#define __PT_RET_REG esp
    100#define __PT_FP_REG ebp
    101#define __PT_RC_REG eax
    102#define __PT_SP_REG esp
    103#define __PT_IP_REG eip
    104
    105#else /* __i386__ */
    106
    107#define __PT_PARM1_REG rdi
    108#define __PT_PARM2_REG rsi
    109#define __PT_PARM3_REG rdx
    110#define __PT_PARM4_REG rcx
    111#define __PT_PARM5_REG r8
    112#define __PT_RET_REG rsp
    113#define __PT_FP_REG rbp
    114#define __PT_RC_REG rax
    115#define __PT_SP_REG rsp
    116#define __PT_IP_REG rip
    117/* syscall uses r10 for PARM4 */
    118#define PT_REGS_PARM4_SYSCALL(x) ((x)->r10)
    119#define PT_REGS_PARM4_CORE_SYSCALL(x) BPF_CORE_READ(x, r10)
    120
    121#endif /* __i386__ */
    122
    123#endif /* __KERNEL__ || __VMLINUX_H__ */
    124
    125#elif defined(bpf_target_s390)
    126
    127struct pt_regs___s390 {
    128	unsigned long orig_gpr2;
    129};
    130
    131/* s390 provides user_pt_regs instead of struct pt_regs to userspace */
    132#define __PT_REGS_CAST(x) ((const user_pt_regs *)(x))
    133#define __PT_PARM1_REG gprs[2]
    134#define __PT_PARM2_REG gprs[3]
    135#define __PT_PARM3_REG gprs[4]
    136#define __PT_PARM4_REG gprs[5]
    137#define __PT_PARM5_REG gprs[6]
    138#define __PT_RET_REG grps[14]
    139#define __PT_FP_REG gprs[11]	/* Works only with CONFIG_FRAME_POINTER */
    140#define __PT_RC_REG gprs[2]
    141#define __PT_SP_REG gprs[15]
    142#define __PT_IP_REG psw.addr
    143#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; })
    144#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___s390 *)(x), orig_gpr2)
    145
    146#elif defined(bpf_target_arm)
    147
    148#define __PT_PARM1_REG uregs[0]
    149#define __PT_PARM2_REG uregs[1]
    150#define __PT_PARM3_REG uregs[2]
    151#define __PT_PARM4_REG uregs[3]
    152#define __PT_PARM5_REG uregs[4]
    153#define __PT_RET_REG uregs[14]
    154#define __PT_FP_REG uregs[11]	/* Works only with CONFIG_FRAME_POINTER */
    155#define __PT_RC_REG uregs[0]
    156#define __PT_SP_REG uregs[13]
    157#define __PT_IP_REG uregs[12]
    158
    159#elif defined(bpf_target_arm64)
    160
    161struct pt_regs___arm64 {
    162	unsigned long orig_x0;
    163};
    164
    165/* arm64 provides struct user_pt_regs instead of struct pt_regs to userspace */
    166#define __PT_REGS_CAST(x) ((const struct user_pt_regs *)(x))
    167#define __PT_PARM1_REG regs[0]
    168#define __PT_PARM2_REG regs[1]
    169#define __PT_PARM3_REG regs[2]
    170#define __PT_PARM4_REG regs[3]
    171#define __PT_PARM5_REG regs[4]
    172#define __PT_RET_REG regs[30]
    173#define __PT_FP_REG regs[29]	/* Works only with CONFIG_FRAME_POINTER */
    174#define __PT_RC_REG regs[0]
    175#define __PT_SP_REG sp
    176#define __PT_IP_REG pc
    177#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; })
    178#define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___arm64 *)(x), orig_x0)
    179
    180#elif defined(bpf_target_mips)
    181
    182#define __PT_PARM1_REG regs[4]
    183#define __PT_PARM2_REG regs[5]
    184#define __PT_PARM3_REG regs[6]
    185#define __PT_PARM4_REG regs[7]
    186#define __PT_PARM5_REG regs[8]
    187#define __PT_RET_REG regs[31]
    188#define __PT_FP_REG regs[30]	/* Works only with CONFIG_FRAME_POINTER */
    189#define __PT_RC_REG regs[2]
    190#define __PT_SP_REG regs[29]
    191#define __PT_IP_REG cp0_epc
    192
    193#elif defined(bpf_target_powerpc)
    194
    195#define __PT_PARM1_REG gpr[3]
    196#define __PT_PARM2_REG gpr[4]
    197#define __PT_PARM3_REG gpr[5]
    198#define __PT_PARM4_REG gpr[6]
    199#define __PT_PARM5_REG gpr[7]
    200#define __PT_RET_REG regs[31]
    201#define __PT_FP_REG __unsupported__
    202#define __PT_RC_REG gpr[3]
    203#define __PT_SP_REG sp
    204#define __PT_IP_REG nip
    205/* powerpc does not select ARCH_HAS_SYSCALL_WRAPPER. */
    206#define PT_REGS_SYSCALL_REGS(ctx) ctx
    207
    208#elif defined(bpf_target_sparc)
    209
    210#define __PT_PARM1_REG u_regs[UREG_I0]
    211#define __PT_PARM2_REG u_regs[UREG_I1]
    212#define __PT_PARM3_REG u_regs[UREG_I2]
    213#define __PT_PARM4_REG u_regs[UREG_I3]
    214#define __PT_PARM5_REG u_regs[UREG_I4]
    215#define __PT_RET_REG u_regs[UREG_I7]
    216#define __PT_FP_REG __unsupported__
    217#define __PT_RC_REG u_regs[UREG_I0]
    218#define __PT_SP_REG u_regs[UREG_FP]
    219/* Should this also be a bpf_target check for the sparc case? */
    220#if defined(__arch64__)
    221#define __PT_IP_REG tpc
    222#else
    223#define __PT_IP_REG pc
    224#endif
    225
    226#elif defined(bpf_target_riscv)
    227
    228#define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x))
    229#define __PT_PARM1_REG a0
    230#define __PT_PARM2_REG a1
    231#define __PT_PARM3_REG a2
    232#define __PT_PARM4_REG a3
    233#define __PT_PARM5_REG a4
    234#define __PT_RET_REG ra
    235#define __PT_FP_REG s0
    236#define __PT_RC_REG a5
    237#define __PT_SP_REG sp
    238#define __PT_IP_REG pc
    239/* riscv does not select ARCH_HAS_SYSCALL_WRAPPER. */
    240#define PT_REGS_SYSCALL_REGS(ctx) ctx
    241
    242#elif defined(bpf_target_arc)
    243
    244/* arc provides struct user_pt_regs instead of struct pt_regs to userspace */
    245#define __PT_REGS_CAST(x) ((const struct user_regs_struct *)(x))
    246#define __PT_PARM1_REG scratch.r0
    247#define __PT_PARM2_REG scratch.r1
    248#define __PT_PARM3_REG scratch.r2
    249#define __PT_PARM4_REG scratch.r3
    250#define __PT_PARM5_REG scratch.r4
    251#define __PT_RET_REG scratch.blink
    252#define __PT_FP_REG __unsupported__
    253#define __PT_RC_REG scratch.r0
    254#define __PT_SP_REG scratch.sp
    255#define __PT_IP_REG scratch.ret
    256/* arc does not select ARCH_HAS_SYSCALL_WRAPPER. */
    257#define PT_REGS_SYSCALL_REGS(ctx) ctx
    258
    259#endif
    260
    261#if defined(bpf_target_defined)
    262
    263struct pt_regs;
    264
    265/* allow some architecutres to override `struct pt_regs` */
    266#ifndef __PT_REGS_CAST
    267#define __PT_REGS_CAST(x) (x)
    268#endif
    269
    270#define PT_REGS_PARM1(x) (__PT_REGS_CAST(x)->__PT_PARM1_REG)
    271#define PT_REGS_PARM2(x) (__PT_REGS_CAST(x)->__PT_PARM2_REG)
    272#define PT_REGS_PARM3(x) (__PT_REGS_CAST(x)->__PT_PARM3_REG)
    273#define PT_REGS_PARM4(x) (__PT_REGS_CAST(x)->__PT_PARM4_REG)
    274#define PT_REGS_PARM5(x) (__PT_REGS_CAST(x)->__PT_PARM5_REG)
    275#define PT_REGS_RET(x) (__PT_REGS_CAST(x)->__PT_RET_REG)
    276#define PT_REGS_FP(x) (__PT_REGS_CAST(x)->__PT_FP_REG)
    277#define PT_REGS_RC(x) (__PT_REGS_CAST(x)->__PT_RC_REG)
    278#define PT_REGS_SP(x) (__PT_REGS_CAST(x)->__PT_SP_REG)
    279#define PT_REGS_IP(x) (__PT_REGS_CAST(x)->__PT_IP_REG)
    280
    281#define PT_REGS_PARM1_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM1_REG)
    282#define PT_REGS_PARM2_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM2_REG)
    283#define PT_REGS_PARM3_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM3_REG)
    284#define PT_REGS_PARM4_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM4_REG)
    285#define PT_REGS_PARM5_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_PARM5_REG)
    286#define PT_REGS_RET_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RET_REG)
    287#define PT_REGS_FP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_FP_REG)
    288#define PT_REGS_RC_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_RC_REG)
    289#define PT_REGS_SP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_SP_REG)
    290#define PT_REGS_IP_CORE(x) BPF_CORE_READ(__PT_REGS_CAST(x), __PT_IP_REG)
    291
    292#if defined(bpf_target_powerpc)
    293
    294#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = (ctx)->link; })
    295#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
    296
    297#elif defined(bpf_target_sparc)
    298
    299#define BPF_KPROBE_READ_RET_IP(ip, ctx)		({ (ip) = PT_REGS_RET(ctx); })
    300#define BPF_KRETPROBE_READ_RET_IP		BPF_KPROBE_READ_RET_IP
    301
    302#else
    303
    304#define BPF_KPROBE_READ_RET_IP(ip, ctx)					    \
    305	({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)PT_REGS_RET(ctx)); })
    306#define BPF_KRETPROBE_READ_RET_IP(ip, ctx)				    \
    307	({ bpf_probe_read_kernel(&(ip), sizeof(ip), (void *)(PT_REGS_FP(ctx) + sizeof(ip))); })
    308
    309#endif
    310
    311#ifndef PT_REGS_PARM1_SYSCALL
    312#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1(x)
    313#endif
    314#define PT_REGS_PARM2_SYSCALL(x) PT_REGS_PARM2(x)
    315#define PT_REGS_PARM3_SYSCALL(x) PT_REGS_PARM3(x)
    316#ifndef PT_REGS_PARM4_SYSCALL
    317#define PT_REGS_PARM4_SYSCALL(x) PT_REGS_PARM4(x)
    318#endif
    319#define PT_REGS_PARM5_SYSCALL(x) PT_REGS_PARM5(x)
    320
    321#ifndef PT_REGS_PARM1_CORE_SYSCALL
    322#define PT_REGS_PARM1_CORE_SYSCALL(x) PT_REGS_PARM1_CORE(x)
    323#endif
    324#define PT_REGS_PARM2_CORE_SYSCALL(x) PT_REGS_PARM2_CORE(x)
    325#define PT_REGS_PARM3_CORE_SYSCALL(x) PT_REGS_PARM3_CORE(x)
    326#ifndef PT_REGS_PARM4_CORE_SYSCALL
    327#define PT_REGS_PARM4_CORE_SYSCALL(x) PT_REGS_PARM4_CORE(x)
    328#endif
    329#define PT_REGS_PARM5_CORE_SYSCALL(x) PT_REGS_PARM5_CORE(x)
    330
    331#else /* defined(bpf_target_defined) */
    332
    333#define PT_REGS_PARM1(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    334#define PT_REGS_PARM2(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    335#define PT_REGS_PARM3(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    336#define PT_REGS_PARM4(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    337#define PT_REGS_PARM5(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    338#define PT_REGS_RET(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    339#define PT_REGS_FP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    340#define PT_REGS_RC(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    341#define PT_REGS_SP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    342#define PT_REGS_IP(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    343
    344#define PT_REGS_PARM1_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    345#define PT_REGS_PARM2_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    346#define PT_REGS_PARM3_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    347#define PT_REGS_PARM4_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    348#define PT_REGS_PARM5_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    349#define PT_REGS_RET_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    350#define PT_REGS_FP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    351#define PT_REGS_RC_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    352#define PT_REGS_SP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    353#define PT_REGS_IP_CORE(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    354
    355#define BPF_KPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    356#define BPF_KRETPROBE_READ_RET_IP(ip, ctx) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    357
    358#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    359#define PT_REGS_PARM2_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    360#define PT_REGS_PARM3_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    361#define PT_REGS_PARM4_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    362#define PT_REGS_PARM5_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    363
    364#define PT_REGS_PARM1_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    365#define PT_REGS_PARM2_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    366#define PT_REGS_PARM3_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    367#define PT_REGS_PARM4_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    368#define PT_REGS_PARM5_CORE_SYSCALL(x) ({ _Pragma(__BPF_TARGET_MISSING); 0l; })
    369
    370#endif /* defined(bpf_target_defined) */
    371
    372/*
    373 * When invoked from a syscall handler kprobe, returns a pointer to a
    374 * struct pt_regs containing syscall arguments and suitable for passing to
    375 * PT_REGS_PARMn_SYSCALL() and PT_REGS_PARMn_CORE_SYSCALL().
    376 */
    377#ifndef PT_REGS_SYSCALL_REGS
    378/* By default, assume that the arch selects ARCH_HAS_SYSCALL_WRAPPER. */
    379#define PT_REGS_SYSCALL_REGS(ctx) ((struct pt_regs *)PT_REGS_PARM1(ctx))
    380#endif
    381
    382#ifndef ___bpf_concat
    383#define ___bpf_concat(a, b) a ## b
    384#endif
    385#ifndef ___bpf_apply
    386#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
    387#endif
    388#ifndef ___bpf_nth
    389#define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N
    390#endif
    391#ifndef ___bpf_narg
    392#define ___bpf_narg(...) ___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
    393#endif
    394
    395#define ___bpf_ctx_cast0()            ctx
    396#define ___bpf_ctx_cast1(x)           ___bpf_ctx_cast0(), (void *)ctx[0]
    397#define ___bpf_ctx_cast2(x, args...)  ___bpf_ctx_cast1(args), (void *)ctx[1]
    398#define ___bpf_ctx_cast3(x, args...)  ___bpf_ctx_cast2(args), (void *)ctx[2]
    399#define ___bpf_ctx_cast4(x, args...)  ___bpf_ctx_cast3(args), (void *)ctx[3]
    400#define ___bpf_ctx_cast5(x, args...)  ___bpf_ctx_cast4(args), (void *)ctx[4]
    401#define ___bpf_ctx_cast6(x, args...)  ___bpf_ctx_cast5(args), (void *)ctx[5]
    402#define ___bpf_ctx_cast7(x, args...)  ___bpf_ctx_cast6(args), (void *)ctx[6]
    403#define ___bpf_ctx_cast8(x, args...)  ___bpf_ctx_cast7(args), (void *)ctx[7]
    404#define ___bpf_ctx_cast9(x, args...)  ___bpf_ctx_cast8(args), (void *)ctx[8]
    405#define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9]
    406#define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10]
    407#define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11]
    408#define ___bpf_ctx_cast(args...)      ___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args)
    409
    410/*
    411 * BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and
    412 * similar kinds of BPF programs, that accept input arguments as a single
    413 * pointer to untyped u64 array, where each u64 can actually be a typed
    414 * pointer or integer of different size. Instead of requring user to write
    415 * manual casts and work with array elements by index, BPF_PROG macro
    416 * allows user to declare a list of named and typed input arguments in the
    417 * same syntax as for normal C function. All the casting is hidden and
    418 * performed transparently, while user code can just assume working with
    419 * function arguments of specified type and name.
    420 *
    421 * Original raw context argument is preserved as well as 'ctx' argument.
    422 * This is useful when using BPF helpers that expect original context
    423 * as one of the parameters (e.g., for bpf_perf_event_output()).
    424 */
    425#define BPF_PROG(name, args...)						    \
    426name(unsigned long long *ctx);						    \
    427static __attribute__((always_inline)) typeof(name(0))			    \
    428____##name(unsigned long long *ctx, ##args);				    \
    429typeof(name(0)) name(unsigned long long *ctx)				    \
    430{									    \
    431	_Pragma("GCC diagnostic push")					    \
    432	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
    433	return ____##name(___bpf_ctx_cast(args));			    \
    434	_Pragma("GCC diagnostic pop")					    \
    435}									    \
    436static __attribute__((always_inline)) typeof(name(0))			    \
    437____##name(unsigned long long *ctx, ##args)
    438
    439struct pt_regs;
    440
    441#define ___bpf_kprobe_args0()           ctx
    442#define ___bpf_kprobe_args1(x)          ___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
    443#define ___bpf_kprobe_args2(x, args...) ___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx)
    444#define ___bpf_kprobe_args3(x, args...) ___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx)
    445#define ___bpf_kprobe_args4(x, args...) ___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx)
    446#define ___bpf_kprobe_args5(x, args...) ___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx)
    447#define ___bpf_kprobe_args(args...)     ___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
    448
    449/*
    450 * BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for
    451 * tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific
    452 * low-level way of getting kprobe input arguments from struct pt_regs, and
    453 * provides a familiar typed and named function arguments syntax and
    454 * semantics of accessing kprobe input paremeters.
    455 *
    456 * Original struct pt_regs* context is preserved as 'ctx' argument. This might
    457 * be necessary when using BPF helpers like bpf_perf_event_output().
    458 */
    459#define BPF_KPROBE(name, args...)					    \
    460name(struct pt_regs *ctx);						    \
    461static __attribute__((always_inline)) typeof(name(0))			    \
    462____##name(struct pt_regs *ctx, ##args);				    \
    463typeof(name(0)) name(struct pt_regs *ctx)				    \
    464{									    \
    465	_Pragma("GCC diagnostic push")					    \
    466	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
    467	return ____##name(___bpf_kprobe_args(args));			    \
    468	_Pragma("GCC diagnostic pop")					    \
    469}									    \
    470static __attribute__((always_inline)) typeof(name(0))			    \
    471____##name(struct pt_regs *ctx, ##args)
    472
    473#define ___bpf_kretprobe_args0()       ctx
    474#define ___bpf_kretprobe_args1(x)      ___bpf_kretprobe_args0(), (void *)PT_REGS_RC(ctx)
    475#define ___bpf_kretprobe_args(args...) ___bpf_apply(___bpf_kretprobe_args, ___bpf_narg(args))(args)
    476
    477/*
    478 * BPF_KRETPROBE is similar to BPF_KPROBE, except, it only provides optional
    479 * return value (in addition to `struct pt_regs *ctx`), but no input
    480 * arguments, because they will be clobbered by the time probed function
    481 * returns.
    482 */
    483#define BPF_KRETPROBE(name, args...)					    \
    484name(struct pt_regs *ctx);						    \
    485static __attribute__((always_inline)) typeof(name(0))			    \
    486____##name(struct pt_regs *ctx, ##args);				    \
    487typeof(name(0)) name(struct pt_regs *ctx)				    \
    488{									    \
    489	_Pragma("GCC diagnostic push")					    \
    490	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
    491	return ____##name(___bpf_kretprobe_args(args));			    \
    492	_Pragma("GCC diagnostic pop")					    \
    493}									    \
    494static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
    495
    496#define ___bpf_syscall_args0()           ctx
    497#define ___bpf_syscall_args1(x)          ___bpf_syscall_args0(), (void *)PT_REGS_PARM1_CORE_SYSCALL(regs)
    498#define ___bpf_syscall_args2(x, args...) ___bpf_syscall_args1(args), (void *)PT_REGS_PARM2_CORE_SYSCALL(regs)
    499#define ___bpf_syscall_args3(x, args...) ___bpf_syscall_args2(args), (void *)PT_REGS_PARM3_CORE_SYSCALL(regs)
    500#define ___bpf_syscall_args4(x, args...) ___bpf_syscall_args3(args), (void *)PT_REGS_PARM4_CORE_SYSCALL(regs)
    501#define ___bpf_syscall_args5(x, args...) ___bpf_syscall_args4(args), (void *)PT_REGS_PARM5_CORE_SYSCALL(regs)
    502#define ___bpf_syscall_args(args...)     ___bpf_apply(___bpf_syscall_args, ___bpf_narg(args))(args)
    503
    504/*
    505 * BPF_KPROBE_SYSCALL is a variant of BPF_KPROBE, which is intended for
    506 * tracing syscall functions, like __x64_sys_close. It hides the underlying
    507 * platform-specific low-level way of getting syscall input arguments from
    508 * struct pt_regs, and provides a familiar typed and named function arguments
    509 * syntax and semantics of accessing syscall input parameters.
    510 *
    511 * Original struct pt_regs* context is preserved as 'ctx' argument. This might
    512 * be necessary when using BPF helpers like bpf_perf_event_output().
    513 *
    514 * This macro relies on BPF CO-RE support.
    515 */
    516#define BPF_KPROBE_SYSCALL(name, args...)				    \
    517name(struct pt_regs *ctx);						    \
    518static __attribute__((always_inline)) typeof(name(0))			    \
    519____##name(struct pt_regs *ctx, ##args);				    \
    520typeof(name(0)) name(struct pt_regs *ctx)				    \
    521{									    \
    522	struct pt_regs *regs = PT_REGS_SYSCALL_REGS(ctx);		    \
    523	_Pragma("GCC diagnostic push")					    \
    524	_Pragma("GCC diagnostic ignored \"-Wint-conversion\"")		    \
    525	return ____##name(___bpf_syscall_args(args));			    \
    526	_Pragma("GCC diagnostic pop")					    \
    527}									    \
    528static __attribute__((always_inline)) typeof(name(0))			    \
    529____##name(struct pt_regs *ctx, ##args)
    530
    531#endif