Skip to content

Commit 2146f7f

Browse files
author
Alexei Starovoitov
committed
Merge branch 'allocate-bpf-trampoline-on-bpf_prog_pack'
Song Liu says: ==================== Allocate bpf trampoline on bpf_prog_pack This set enables allocating bpf trampoline from bpf_prog_pack on x86. The majority of this work, however, is the refactoring of trampoline code. This is needed because we need to handle 4 archs and 2 users (trampoline and struct_ops). 1/7 through 6/7 refactors trampoline code. A few helpers are added. 7/7 finally let bpf trampoline on x86 use bpf_prog_pack. Changes in v7: 1. Use kvmalloc for rw_image in x86/arch_prepare_bpf_trampoline. (Alexei) 2. Add comment to explain why we cannot use kvmalloc in x86/arch_bpf_trampoline_size. (Alexei) Changes in v6: 1. Rebase. 2. Add Acked-by and Tested-by from Jiri Olsa and Björn Töpel. Changes in v5: 1. Adjust size of trampoline ksym. (Jiri) 2. Use "unsigned int size" arg in image management helpers.(Daniel) Changes in v4: 1. Dropped 1/8 in v3, which is already merged in bpf-next. 2. Add Reviewed-by from Björn Töpel. Changes in v3: 1. Fix bug in s390. (Thanks to Ilya Leoshkevich). 2. Fix build error in riscv. (kernel test robot). Changes in v2: 1. Add missing changes in net/bpf/bpf_dummy_struct_ops.c. 2. Reduce one dry run in arch_prepare_bpf_trampoline. (Xu Kuohai) 3. Other small fixes. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
2 parents 7065eef + 3ba026f commit 2146f7f

File tree

11 files changed

+305
-132
lines changed

11 files changed

+305
-132
lines changed

arch/arm64/net/bpf_jit_comp.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1828,7 +1828,7 @@ static void restore_args(struct jit_ctx *ctx, int args_off, int nregs)
18281828
*
18291829
*/
18301830
static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
1831-
struct bpf_tramp_links *tlinks, void *orig_call,
1831+
struct bpf_tramp_links *tlinks, void *func_addr,
18321832
int nregs, u32 flags)
18331833
{
18341834
int i;
@@ -1926,7 +1926,7 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
19261926

19271927
if (flags & BPF_TRAMP_F_IP_ARG) {
19281928
/* save ip address of the traced function */
1929-
emit_addr_mov_i64(A64_R(10), (const u64)orig_call, ctx);
1929+
emit_addr_mov_i64(A64_R(10), (const u64)func_addr, ctx);
19301930
emit(A64_STR64I(A64_R(10), A64_SP, ip_off), ctx);
19311931
}
19321932

@@ -2026,18 +2026,10 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im,
20262026
return ctx->idx;
20272027
}
20282028

2029-
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
2030-
void *image_end, const struct btf_func_model *m,
2031-
u32 flags, struct bpf_tramp_links *tlinks,
2032-
void *orig_call)
2029+
static int btf_func_model_nregs(const struct btf_func_model *m)
20332030
{
2034-
int i, ret;
20352031
int nregs = m->nr_args;
2036-
int max_insns = ((long)image_end - (long)image) / AARCH64_INSN_SIZE;
2037-
struct jit_ctx ctx = {
2038-
.image = NULL,
2039-
.idx = 0,
2040-
};
2032+
int i;
20412033

20422034
/* extra registers needed for struct argument */
20432035
for (i = 0; i < MAX_BPF_FUNC_ARGS; i++) {
@@ -2046,22 +2038,49 @@ int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
20462038
nregs += (m->arg_size[i] + 7) / 8 - 1;
20472039
}
20482040

2041+
return nregs;
2042+
}
2043+
2044+
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
2045+
struct bpf_tramp_links *tlinks, void *func_addr)
2046+
{
2047+
struct jit_ctx ctx = {
2048+
.image = NULL,
2049+
.idx = 0,
2050+
};
2051+
struct bpf_tramp_image im;
2052+
int nregs, ret;
2053+
2054+
nregs = btf_func_model_nregs(m);
20492055
/* the first 8 registers are used for arguments */
20502056
if (nregs > 8)
20512057
return -ENOTSUPP;
20522058

2053-
ret = prepare_trampoline(&ctx, im, tlinks, orig_call, nregs, flags);
2059+
ret = prepare_trampoline(&ctx, &im, tlinks, func_addr, nregs, flags);
20542060
if (ret < 0)
20552061
return ret;
20562062

2057-
if (ret > max_insns)
2058-
return -EFBIG;
2063+
return ret < 0 ? ret : ret * AARCH64_INSN_SIZE;
2064+
}
20592065

2060-
ctx.image = image;
2061-
ctx.idx = 0;
2066+
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
2067+
void *image_end, const struct btf_func_model *m,
2068+
u32 flags, struct bpf_tramp_links *tlinks,
2069+
void *func_addr)
2070+
{
2071+
int ret, nregs;
2072+
struct jit_ctx ctx = {
2073+
.image = image,
2074+
.idx = 0,
2075+
};
2076+
2077+
nregs = btf_func_model_nregs(m);
2078+
/* the first 8 registers are used for arguments */
2079+
if (nregs > 8)
2080+
return -ENOTSUPP;
20622081

20632082
jit_fill_hole(image, (unsigned int)(image_end - image));
2064-
ret = prepare_trampoline(&ctx, im, tlinks, orig_call, nregs, flags);
2083+
ret = prepare_trampoline(&ctx, im, tlinks, func_addr, nregs, flags);
20652084

20662085
if (ret > 0 && validate_code(&ctx) < 0)
20672086
ret = -EINVAL;

arch/riscv/net/bpf_jit_comp64.c

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1029,23 +1029,28 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
10291029
return ret;
10301030
}
10311031

1032-
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
1033-
void *image_end, const struct btf_func_model *m,
1034-
u32 flags, struct bpf_tramp_links *tlinks,
1035-
void *func_addr)
1032+
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
1033+
struct bpf_tramp_links *tlinks, void *func_addr)
10361034
{
1037-
int ret;
1035+
struct bpf_tramp_image im;
10381036
struct rv_jit_context ctx;
1037+
int ret;
10391038

10401039
ctx.ninsns = 0;
10411040
ctx.insns = NULL;
10421041
ctx.ro_insns = NULL;
1043-
ret = __arch_prepare_bpf_trampoline(im, m, tlinks, func_addr, flags, &ctx);
1044-
if (ret < 0)
1045-
return ret;
1042+
ret = __arch_prepare_bpf_trampoline(&im, m, tlinks, func_addr, flags, &ctx);
10461043

1047-
if (ninsns_rvoff(ret) > (long)image_end - (long)image)
1048-
return -EFBIG;
1044+
return ret < 0 ? ret : ninsns_rvoff(ctx.ninsns);
1045+
}
1046+
1047+
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
1048+
void *image_end, const struct btf_func_model *m,
1049+
u32 flags, struct bpf_tramp_links *tlinks,
1050+
void *func_addr)
1051+
{
1052+
int ret;
1053+
struct rv_jit_context ctx;
10491054

10501055
ctx.ninsns = 0;
10511056
/*

arch/s390/net/bpf_jit_comp.c

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2637,37 +2637,49 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,
26372637
return 0;
26382638
}
26392639

2640+
int arch_bpf_trampoline_size(const struct btf_func_model *m, u32 flags,
2641+
struct bpf_tramp_links *tlinks, void *orig_call)
2642+
{
2643+
struct bpf_tramp_image im;
2644+
struct bpf_tramp_jit tjit;
2645+
int ret;
2646+
2647+
memset(&tjit, 0, sizeof(tjit));
2648+
2649+
ret = __arch_prepare_bpf_trampoline(&im, &tjit, m, flags,
2650+
tlinks, orig_call);
2651+
2652+
return ret < 0 ? ret : tjit.common.prg;
2653+
}
2654+
26402655
int arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, void *image,
26412656
void *image_end, const struct btf_func_model *m,
26422657
u32 flags, struct bpf_tramp_links *tlinks,
26432658
void *func_addr)
26442659
{
26452660
struct bpf_tramp_jit tjit;
26462661
int ret;
2647-
int i;
26482662

2649-
for (i = 0; i < 2; i++) {
2650-
if (i == 0) {
2651-
/* Compute offsets, check whether the code fits. */
2652-
memset(&tjit, 0, sizeof(tjit));
2653-
} else {
2654-
/* Generate the code. */
2655-
tjit.common.prg = 0;
2656-
tjit.common.prg_buf = image;
2657-
}
2658-
ret = __arch_prepare_bpf_trampoline(im, &tjit, m, flags,
2659-
tlinks, func_addr);
2660-
if (ret < 0)
2661-
return ret;
2662-
if (tjit.common.prg > (char *)image_end - (char *)image)
2663-
/*
2664-
* Use the same error code as for exceeding
2665-
* BPF_MAX_TRAMP_LINKS.
2666-
*/
2667-
return -E2BIG;
2668-
}
2663+
/* Compute offsets, check whether the code fits. */
2664+
memset(&tjit, 0, sizeof(tjit));
2665+
ret = __arch_prepare_bpf_trampoline(im, &tjit, m, flags,
2666+
tlinks, func_addr);
2667+
2668+
if (ret < 0)
2669+
return ret;
2670+
if (tjit.common.prg > (char *)image_end - (char *)image)
2671+
/*
2672+
* Use the same error code as for exceeding
2673+
* BPF_MAX_TRAMP_LINKS.
2674+
*/
2675+
return -E2BIG;
2676+
2677+
tjit.common.prg = 0;
2678+
tjit.common.prg_buf = image;
2679+
ret = __arch_prepare_bpf_trampoline(im, &tjit, m, flags,
2680+
tlinks, func_addr);
26692681

2670-
return tjit.common.prg;
2682+
return ret < 0 ? ret : tjit.common.prg;
26712683
}
26722684

26732685
bool bpf_jit_supports_subprog_tailcalls(void)

0 commit comments

Comments
 (0)