|
| 1 | +// SPDX-License-Identifier: GPL-2.0 |
| 2 | +/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */ |
| 3 | + |
| 4 | +#include <vmlinux.h> |
| 5 | +#include <bpf/bpf_tracing.h> |
| 6 | +#include "bpf_misc.h" |
| 7 | +#include "../bpf_testmod/bpf_testmod.h" |
| 8 | +#include "../bpf_testmod/bpf_testmod_kfunc.h" |
| 9 | + |
| 10 | +char _license[] SEC("license") = "GPL"; |
| 11 | + |
| 12 | +__success |
| 13 | +/* save __u64 *ctx to stack */ |
| 14 | +__xlated("0: *(u64 *)(r10 -8) = r1") |
| 15 | +/* main prog */ |
| 16 | +__xlated("1: r1 = *(u64 *)(r1 +0)") |
| 17 | +__xlated("2: r2 = *(u64 *)(r1 +0)") |
| 18 | +__xlated("3: r3 = 0") |
| 19 | +__xlated("4: r4 = 1") |
| 20 | +__xlated("5: if r2 == 0x0 goto pc+10") |
| 21 | +__xlated("6: r0 = 0") |
| 22 | +__xlated("7: *(u64 *)(r1 +0) = r3") |
| 23 | +/* epilogue */ |
| 24 | +__xlated("8: r1 = *(u64 *)(r10 -8)") |
| 25 | +__xlated("9: r1 = *(u64 *)(r1 +0)") |
| 26 | +__xlated("10: r6 = *(u64 *)(r1 +0)") |
| 27 | +__xlated("11: r6 += 10000") |
| 28 | +__xlated("12: *(u64 *)(r1 +0) = r6") |
| 29 | +__xlated("13: r0 = r6") |
| 30 | +__xlated("14: r0 *= 2") |
| 31 | +__xlated("15: exit") |
| 32 | +/* 2nd part of the main prog after the first exit */ |
| 33 | +__xlated("16: *(u64 *)(r1 +0) = r4") |
| 34 | +__xlated("17: r0 = 1") |
| 35 | +/* Clear the r1 to ensure it does not have |
| 36 | + * off-by-1 error and ensure it jumps back to the |
| 37 | + * beginning of epilogue which initializes |
| 38 | + * the r1 with the ctx ptr. |
| 39 | + */ |
| 40 | +__xlated("18: r1 = 0") |
| 41 | +__xlated("19: gotol pc-12") |
| 42 | +SEC("struct_ops/test_epilogue_exit") |
| 43 | +__naked int test_epilogue_exit(void) |
| 44 | +{ |
| 45 | + asm volatile ( |
| 46 | + "r1 = *(u64 *)(r1 +0);" |
| 47 | + "r2 = *(u64 *)(r1 +0);" |
| 48 | + "r3 = 0;" |
| 49 | + "r4 = 1;" |
| 50 | + "if r2 == 0 goto +3;" |
| 51 | + "r0 = 0;" |
| 52 | + "*(u64 *)(r1 + 0) = r3;" |
| 53 | + "exit;" |
| 54 | + "*(u64 *)(r1 + 0) = r4;" |
| 55 | + "r0 = 1;" |
| 56 | + "r1 = 0;" |
| 57 | + "exit;" |
| 58 | + ::: __clobber_all); |
| 59 | +} |
| 60 | + |
| 61 | +SEC(".struct_ops.link") |
| 62 | +struct bpf_testmod_st_ops epilogue_exit = { |
| 63 | + .test_epilogue = (void *)test_epilogue_exit, |
| 64 | +}; |
| 65 | + |
| 66 | +SEC("syscall") |
| 67 | +__retval(20000) |
| 68 | +int syscall_epilogue_exit0(void *ctx) |
| 69 | +{ |
| 70 | + struct st_ops_args args = { .a = 1 }; |
| 71 | + |
| 72 | + return bpf_kfunc_st_ops_test_epilogue(&args); |
| 73 | +} |
| 74 | + |
| 75 | +SEC("syscall") |
| 76 | +__retval(20002) |
| 77 | +int syscall_epilogue_exit1(void *ctx) |
| 78 | +{ |
| 79 | + struct st_ops_args args = {}; |
| 80 | + |
| 81 | + return bpf_kfunc_st_ops_test_epilogue(&args); |
| 82 | +} |
0 commit comments