|
2 | 2 | #ifndef __BPF_TRACING_H__ |
3 | 3 | #define __BPF_TRACING_H__ |
4 | 4 |
|
| 5 | +#include <bpf/bpf_helpers.h> |
| 6 | + |
5 | 7 | /* Scan the ARCH passed in from ARCH env variable (see Makefile) */ |
6 | 8 | #if defined(__TARGET_ARCH_x86) |
7 | 9 | #define bpf_target_x86 |
@@ -140,7 +142,7 @@ struct pt_regs___s390 { |
140 | 142 | #define __PT_RC_REG gprs[2] |
141 | 143 | #define __PT_SP_REG gprs[15] |
142 | 144 | #define __PT_IP_REG psw.addr |
143 | | -#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; }) |
| 145 | +#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x) |
144 | 146 | #define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___s390 *)(x), orig_gpr2) |
145 | 147 |
|
146 | 148 | #elif defined(bpf_target_arm) |
@@ -174,7 +176,7 @@ struct pt_regs___arm64 { |
174 | 176 | #define __PT_RC_REG regs[0] |
175 | 177 | #define __PT_SP_REG sp |
176 | 178 | #define __PT_IP_REG pc |
177 | | -#define PT_REGS_PARM1_SYSCALL(x) ({ _Pragma("GCC error \"use PT_REGS_PARM1_CORE_SYSCALL() instead\""); 0l; }) |
| 179 | +#define PT_REGS_PARM1_SYSCALL(x) PT_REGS_PARM1_CORE_SYSCALL(x) |
178 | 180 | #define PT_REGS_PARM1_CORE_SYSCALL(x) BPF_CORE_READ((const struct pt_regs___arm64 *)(x), orig_x0) |
179 | 181 |
|
180 | 182 | #elif defined(bpf_target_mips) |
@@ -493,39 +495,62 @@ typeof(name(0)) name(struct pt_regs *ctx) \ |
493 | 495 | } \ |
494 | 496 | static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args) |
495 | 497 |
|
| 498 | +/* If kernel has CONFIG_ARCH_HAS_SYSCALL_WRAPPER, read pt_regs directly */ |
496 | 499 | #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) |
| 500 | +#define ___bpf_syscall_args1(x) ___bpf_syscall_args0(), (void *)PT_REGS_PARM1_SYSCALL(regs) |
| 501 | +#define ___bpf_syscall_args2(x, args...) ___bpf_syscall_args1(args), (void *)PT_REGS_PARM2_SYSCALL(regs) |
| 502 | +#define ___bpf_syscall_args3(x, args...) ___bpf_syscall_args2(args), (void *)PT_REGS_PARM3_SYSCALL(regs) |
| 503 | +#define ___bpf_syscall_args4(x, args...) ___bpf_syscall_args3(args), (void *)PT_REGS_PARM4_SYSCALL(regs) |
| 504 | +#define ___bpf_syscall_args5(x, args...) ___bpf_syscall_args4(args), (void *)PT_REGS_PARM5_SYSCALL(regs) |
502 | 505 | #define ___bpf_syscall_args(args...) ___bpf_apply(___bpf_syscall_args, ___bpf_narg(args))(args) |
503 | 506 |
|
| 507 | +/* If kernel doesn't have CONFIG_ARCH_HAS_SYSCALL_WRAPPER, we have to BPF_CORE_READ from pt_regs */ |
| 508 | +#define ___bpf_syswrap_args0() ctx |
| 509 | +#define ___bpf_syswrap_args1(x) ___bpf_syswrap_args0(), (void *)PT_REGS_PARM1_CORE_SYSCALL(regs) |
| 510 | +#define ___bpf_syswrap_args2(x, args...) ___bpf_syswrap_args1(args), (void *)PT_REGS_PARM2_CORE_SYSCALL(regs) |
| 511 | +#define ___bpf_syswrap_args3(x, args...) ___bpf_syswrap_args2(args), (void *)PT_REGS_PARM3_CORE_SYSCALL(regs) |
| 512 | +#define ___bpf_syswrap_args4(x, args...) ___bpf_syswrap_args3(args), (void *)PT_REGS_PARM4_CORE_SYSCALL(regs) |
| 513 | +#define ___bpf_syswrap_args5(x, args...) ___bpf_syswrap_args4(args), (void *)PT_REGS_PARM5_CORE_SYSCALL(regs) |
| 514 | +#define ___bpf_syswrap_args(args...) ___bpf_apply(___bpf_syswrap_args, ___bpf_narg(args))(args) |
| 515 | + |
504 | 516 | /* |
505 | | - * BPF_KPROBE_SYSCALL is a variant of BPF_KPROBE, which is intended for |
| 517 | + * BPF_KSYSCALL is a variant of BPF_KPROBE, which is intended for |
506 | 518 | * tracing syscall functions, like __x64_sys_close. It hides the underlying |
507 | 519 | * platform-specific low-level way of getting syscall input arguments from |
508 | 520 | * struct pt_regs, and provides a familiar typed and named function arguments |
509 | 521 | * syntax and semantics of accessing syscall input parameters. |
510 | 522 | * |
511 | | - * Original struct pt_regs* context is preserved as 'ctx' argument. This might |
| 523 | + * Original struct pt_regs * context is preserved as 'ctx' argument. This might |
512 | 524 | * be necessary when using BPF helpers like bpf_perf_event_output(). |
513 | 525 | * |
514 | | - * This macro relies on BPF CO-RE support. |
| 526 | + * At the moment BPF_KSYSCALL does not handle all the calling convention |
| 527 | + * quirks for mmap(), clone() and compat syscalls transparrently. This may or |
| 528 | + * may not change in the future. User needs to take extra measures to handle |
| 529 | + * such quirks explicitly, if necessary. |
| 530 | + * |
| 531 | + * This macro relies on BPF CO-RE support and virtual __kconfig externs. |
515 | 532 | */ |
516 | | -#define BPF_KPROBE_SYSCALL(name, args...) \ |
| 533 | +#define BPF_KSYSCALL(name, args...) \ |
517 | 534 | name(struct pt_regs *ctx); \ |
| 535 | +extern _Bool LINUX_HAS_SYSCALL_WRAPPER __kconfig; \ |
518 | 536 | static __attribute__((always_inline)) typeof(name(0)) \ |
519 | 537 | ____##name(struct pt_regs *ctx, ##args); \ |
520 | 538 | typeof(name(0)) name(struct pt_regs *ctx) \ |
521 | 539 | { \ |
522 | | - struct pt_regs *regs = PT_REGS_SYSCALL_REGS(ctx); \ |
| 540 | + struct pt_regs *regs = LINUX_HAS_SYSCALL_WRAPPER \ |
| 541 | + ? (struct pt_regs *)PT_REGS_PARM1(ctx) \ |
| 542 | + : ctx; \ |
523 | 543 | _Pragma("GCC diagnostic push") \ |
524 | 544 | _Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \ |
525 | | - return ____##name(___bpf_syscall_args(args)); \ |
| 545 | + if (LINUX_HAS_SYSCALL_WRAPPER) \ |
| 546 | + return ____##name(___bpf_syswrap_args(args)); \ |
| 547 | + else \ |
| 548 | + return ____##name(___bpf_syscall_args(args)); \ |
526 | 549 | _Pragma("GCC diagnostic pop") \ |
527 | 550 | } \ |
528 | 551 | static __attribute__((always_inline)) typeof(name(0)) \ |
529 | 552 | ____##name(struct pt_regs *ctx, ##args) |
530 | 553 |
|
| 554 | +#define BPF_KPROBE_SYSCALL BPF_KSYSCALL |
| 555 | + |
531 | 556 | #endif |
0 commit comments