bpf: Set the number of exception entries properly for subprograms
Currently, if a bpf program has more than one subprograms, each program will be
jitted separately. For programs with bpf-to-bpf calls the
prog->aux->num_exentries is not setup properly. For example, with
bpf_iter_netlink.c modified to force one function to be not inlined and with
CONFIG_BPF_JIT_ALWAYS_ON the following error is seen:
$ ./test_progs -n 3/3
...
libbpf: failed to load program 'iter/netlink'
libbpf: failed to load object 'bpf_iter_netlink'
libbpf: failed to load BPF skeleton 'bpf_iter_netlink': -4007
test_netlink:FAIL:bpf_iter_netlink__open_and_load skeleton open_and_load failed
#3/3 netlink:FAIL
The dmesg shows the following errors:
ex gen bug
which is triggered by the following code in arch/x86/net/bpf_jit_comp.c:
if (excnt >= bpf_prog->aux->num_exentries) {
pr_err("ex gen bug\n");
return -EFAULT;
}
This patch fixes the issue by computing proper num_exentries for each
subprogram before calling JIT.
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
9c82a63cf3
commit
c4c0bdc0d2
@@ -9801,7 +9801,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
|||||||
int i, j, subprog_start, subprog_end = 0, len, subprog;
|
int i, j, subprog_start, subprog_end = 0, len, subprog;
|
||||||
struct bpf_insn *insn;
|
struct bpf_insn *insn;
|
||||||
void *old_bpf_func;
|
void *old_bpf_func;
|
||||||
int err;
|
int err, num_exentries;
|
||||||
|
|
||||||
if (env->subprog_cnt <= 1)
|
if (env->subprog_cnt <= 1)
|
||||||
return 0;
|
return 0;
|
||||||
@@ -9876,6 +9876,14 @@ static int jit_subprogs(struct bpf_verifier_env *env)
|
|||||||
func[i]->aux->nr_linfo = prog->aux->nr_linfo;
|
func[i]->aux->nr_linfo = prog->aux->nr_linfo;
|
||||||
func[i]->aux->jited_linfo = prog->aux->jited_linfo;
|
func[i]->aux->jited_linfo = prog->aux->jited_linfo;
|
||||||
func[i]->aux->linfo_idx = env->subprog_info[i].linfo_idx;
|
func[i]->aux->linfo_idx = env->subprog_info[i].linfo_idx;
|
||||||
|
num_exentries = 0;
|
||||||
|
insn = func[i]->insnsi;
|
||||||
|
for (j = 0; j < func[i]->len; j++, insn++) {
|
||||||
|
if (BPF_CLASS(insn->code) == BPF_LDX &&
|
||||||
|
BPF_MODE(insn->code) == BPF_PROBE_MEM)
|
||||||
|
num_exentries++;
|
||||||
|
}
|
||||||
|
func[i]->aux->num_exentries = num_exentries;
|
||||||
func[i] = bpf_int_jit_compile(func[i]);
|
func[i] = bpf_int_jit_compile(func[i]);
|
||||||
if (!func[i]->jited) {
|
if (!func[i]->jited) {
|
||||||
err = -ENOTSUPP;
|
err = -ENOTSUPP;
|
||||||
|
|||||||
Reference in New Issue
Block a user