lkml.org 
[lkml]   [2020]   [Jul]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 005/179] bpf: Set the number of exception entries properly for subprograms
    Date
    From: Yonghong Song <yhs@fb.com>

    [ Upstream commit c4c0bdc0d2d084ed847c7066bdf59fe2cd25aa17 ]

    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>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    kernel/bpf/verifier.c | 10 +++++++++-
    1 file changed, 9 insertions(+), 1 deletion(-)

    diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
    index 739d9ba3ba6b7..eebdd5307713b 100644
    --- a/kernel/bpf/verifier.c
    +++ b/kernel/bpf/verifier.c
    @@ -9613,7 +9613,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
    int i, j, subprog_start, subprog_end = 0, len, subprog;
    struct bpf_insn *insn;
    void *old_bpf_func;
    - int err;
    + int err, num_exentries;

    if (env->subprog_cnt <= 1)
    return 0;
    @@ -9688,6 +9688,14 @@ static int jit_subprogs(struct bpf_verifier_env *env)
    func[i]->aux->nr_linfo = prog->aux->nr_linfo;
    func[i]->aux->jited_linfo = prog->aux->jited_linfo;
    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]);
    if (!func[i]->jited) {
    err = -ENOTSUPP;
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-07-27 16:20    [W:4.070 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site