Commit 19f68ed6 authored by Aijun Sun's avatar Aijun Sun Committed by Daniel Borkmann

bpf, arm64: Allocate program buffer using kvcalloc instead of kcalloc

It is not necessary to allocate contiguous physical memory for BPF
program buffer using kcalloc. When the BPF program is large more than
memory page size, kcalloc allocates multiple memory pages from buddy
system. If the device can not provide sufficient memory, for example
in low-end android devices [0], memory allocation for BPF program is
likely to fail.

Test cases in lib/test_bpf.c all pass on ARM64 QEMU.

[0]
  AndroidTestSuit: page allocation failure: order:4,
  mode:0x40dc0(GFP_KERNEL|__GFP_COMP|__GFP_ZERO), nodemask=(null),cpuset=foreground,mems_allowed=0
  Call trace:
   dump_stack+0xa4/0x114
   warn_alloc+0xf8/0x14c
   __alloc_pages_slowpath+0xac8/0xb14
   __alloc_pages_nodemask+0x194/0x3d0
   kmalloc_order_trace+0x44/0x1e8
   __kmalloc+0x29c/0x66c
   bpf_int_jit_compile+0x17c/0x568
   bpf_prog_select_runtime+0x4c/0x1b0
   bpf_prepare_filter+0x5fc/0x6bc
   bpf_prog_create_from_user+0x118/0x1c0
   seccomp_set_mode_filter+0x1c4/0x7cc
   __do_sys_prctl+0x380/0x1424
   __arm64_sys_prctl+0x20/0x2c
   el0_svc_common+0xc8/0x22c
   el0_svc_handler+0x1c/0x28
   el0_svc+0x8/0x100
Signed-off-by: default avatarAijun Sun <aijun.sun@unisoc.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20220804025442.22524-1-aijun.sun@unisoc.com
parent ffd5cfca
...@@ -1496,7 +1496,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -1496,7 +1496,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
memset(&ctx, 0, sizeof(ctx)); memset(&ctx, 0, sizeof(ctx));
ctx.prog = prog; ctx.prog = prog;
ctx.offset = kcalloc(prog->len + 1, sizeof(int), GFP_KERNEL); ctx.offset = kvcalloc(prog->len + 1, sizeof(int), GFP_KERNEL);
if (ctx.offset == NULL) { if (ctx.offset == NULL) {
prog = orig_prog; prog = orig_prog;
goto out_off; goto out_off;
...@@ -1601,7 +1601,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) ...@@ -1601,7 +1601,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
ctx.offset[i] *= AARCH64_INSN_SIZE; ctx.offset[i] *= AARCH64_INSN_SIZE;
bpf_prog_fill_jited_linfo(prog, ctx.offset + 1); bpf_prog_fill_jited_linfo(prog, ctx.offset + 1);
out_off: out_off:
kfree(ctx.offset); kvfree(ctx.offset);
kfree(jit_data); kfree(jit_data);
prog->aux->jit_data = NULL; prog->aux->jit_data = NULL;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment