Commit 166f11d1 authored by Ilya Leoshkevich's avatar Ilya Leoshkevich Committed by Daniel Borkmann

s390/bpf: Use kvcalloc for addrs array

A BPF program may consist of 1m instructions, which means JIT
instruction-address mapping can be as large as 4m. s390 has
FORCE_MAX_ZONEORDER=9 (for memory hotplug reasons), which means maximum
kmalloc size is 1m. This makes it impossible to JIT programs with more
than 256k instructions.

Fix by using kvcalloc, which falls back to vmalloc for larger
allocations. An alternative would be to use a radix tree, but that is
not supported by bpf_prog_fill_jited_linfo.
Signed-off-by: default avatarIlya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20191107141838.92202-1-iii@linux.ibm.com
parent 7e22077d
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <linux/filter.h> #include <linux/filter.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/bpf.h> #include <linux/bpf.h>
#include <linux/mm.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/dis.h> #include <asm/dis.h>
#include <asm/facility.h> #include <asm/facility.h>
...@@ -1369,7 +1370,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) ...@@ -1369,7 +1370,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
} }
memset(&jit, 0, sizeof(jit)); memset(&jit, 0, sizeof(jit));
jit.addrs = kcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL); jit.addrs = kvcalloc(fp->len + 1, sizeof(*jit.addrs), GFP_KERNEL);
if (jit.addrs == NULL) { if (jit.addrs == NULL) {
fp = orig_fp; fp = orig_fp;
goto out; goto out;
...@@ -1422,7 +1423,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp) ...@@ -1422,7 +1423,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *fp)
if (!fp->is_func || extra_pass) { if (!fp->is_func || extra_pass) {
bpf_prog_fill_jited_linfo(fp, jit.addrs + 1); bpf_prog_fill_jited_linfo(fp, jit.addrs + 1);
free_addrs: free_addrs:
kfree(jit.addrs); kvfree(jit.addrs);
kfree(jit_data); kfree(jit_data);
fp->aux->jit_data = NULL; fp->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