All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yang Jihong <yangjihong1@huawei.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Song Liu <song@kernel.org>, Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Shubham Bansal <illusionist.neo@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Mykola Lysenko <mykolal@fb.com>, Shuah Khan <shuah@kernel.org>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	<colin.i.king@gmail.com>, Artem Savkov <asavkov@redhat.com>,
	Delyan Kratunov <delyank@fb.com>, bpf <bpf@vger.kernel.org>,
	linux-arm-kernel <linux-arm-kernel@lists.infradead.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Network Development <netdev@vger.kernel.org>,
	"open list:KERNEL SELFTEST FRAMEWORK" 
	<linux-kselftest@vger.kernel.org>
Subject: Re: [PATCH bpf-next v3 1/4] bpf: Adapt 32-bit return value kfunc for 32-bit ARM when zext extension
Date: Mon, 5 Dec 2022 09:19:40 +0800	[thread overview]
Message-ID: <4a2b8cd5-78c4-360a-6eb0-33fcf689d26a@huawei.com> (raw)
In-Reply-To: <CAADnVQJXr6XxpG2E-AkO7__qg-sujrhyO+JWWa1iwYmAO4S0Pw@mail.gmail.com>



On 2022/12/4 0:40, Alexei Starovoitov wrote:
> On Fri, Dec 2, 2022 at 6:58 PM Yang Jihong <yangjihong1@huawei.com> wrote:
>>
>>
>>
>> On 2022/11/29 0:41, Alexei Starovoitov wrote:
>>> On Mon, Nov 28, 2022 at 4:40 AM Yang Jihong <yangjihong1@huawei.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2022/11/28 9:57, Alexei Starovoitov wrote:
>>>>> On Sat, Nov 26, 2022 at 05:45:27PM +0800, Yang Jihong wrote:
>>>>>> For ARM32 architecture, if data width of kfunc return value is 32 bits,
>>>>>> need to do explicit zero extension for high 32-bit, insn_def_regno should
>>>>>> return dst_reg for BPF_JMP type of BPF_PSEUDO_KFUNC_CALL. Otherwise,
>>>>>> opt_subreg_zext_lo32_rnd_hi32 returns -EFAULT, resulting in BPF failure.
>>>>>>
>>>>>> Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
>>>>>> ---
>>>>>>     kernel/bpf/verifier.c | 44 ++++++++++++++++++++++++++++++++++++++++---
>>>>>>     1 file changed, 41 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>>>> index 264b3dc714cc..193ea927aa69 100644
>>>>>> --- a/kernel/bpf/verifier.c
>>>>>> +++ b/kernel/bpf/verifier.c
>>>>>> @@ -1927,6 +1927,21 @@ find_kfunc_desc(const struct bpf_prog *prog, u32 func_id, u16 offset)
>>>>>>                       sizeof(tab->descs[0]), kfunc_desc_cmp_by_id_off);
>>>>>>     }
>>>>>>
>>>>>> +static int kfunc_desc_cmp_by_imm(const void *a, const void *b);
>>>>>> +
>>>>>> +static const struct bpf_kfunc_desc *
>>>>>> +find_kfunc_desc_by_imm(const struct bpf_prog *prog, s32 imm)
>>>>>> +{
>>>>>> +    struct bpf_kfunc_desc desc = {
>>>>>> +            .imm = imm,
>>>>>> +    };
>>>>>> +    struct bpf_kfunc_desc_tab *tab;
>>>>>> +
>>>>>> +    tab = prog->aux->kfunc_tab;
>>>>>> +    return bsearch(&desc, tab->descs, tab->nr_descs,
>>>>>> +                   sizeof(tab->descs[0]), kfunc_desc_cmp_by_imm);
>>>>>> +}
>>>>>> +
>>>>>>     static struct btf *__find_kfunc_desc_btf(struct bpf_verifier_env *env,
>>>>>>                                         s16 offset)
>>>>>>     {
>>>>>> @@ -2342,6 +2357,13 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
>>>>>>                         */
>>>>>>                        if (insn->src_reg == BPF_PSEUDO_CALL)
>>>>>>                                return false;
>>>>>> +
>>>>>> +                    /* Kfunc call will reach here because of insn_has_def32,
>>>>>> +                     * conservatively return TRUE.
>>>>>> +                     */
>>>>>> +                    if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL)
>>>>>> +                            return true;
>>>>>> +
>>>>>>                        /* Helper call will reach here because of arg type
>>>>>>                         * check, conservatively return TRUE.
>>>>>>                         */
>>>>>> @@ -2405,10 +2427,26 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
>>>>>>     }
>>>>>>
>>>>>>     /* Return the regno defined by the insn, or -1. */
>>>>>> -static int insn_def_regno(const struct bpf_insn *insn)
>>>>>> +static int insn_def_regno(struct bpf_verifier_env *env, const struct bpf_insn *insn)
>>>>>>     {
>>>>>>        switch (BPF_CLASS(insn->code)) {
>>>>>>        case BPF_JMP:
>>>>>> +            if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
>>>>>> +                    const struct bpf_kfunc_desc *desc;
>>>>>> +
>>>>>> +                    /* The value of desc cannot be NULL */
>>>>>> +                    desc = find_kfunc_desc_by_imm(env->prog, insn->imm);
>>>>>> +
>>>>>> +                    /* A kfunc can return void.
>>>>>> +                     * The btf type of the kfunc's return value needs
>>>>>> +                     * to be checked against "void" first
>>>>>> +                     */
>>>>>> +                    if (desc->func_model.ret_size == 0)
>>>>>> +                            return -1;
>>>>>> +                    else
>>>>>> +                            return insn->dst_reg;
>>>>>> +            }
>>>>>> +            fallthrough;
>>>>>
>>>>> I cannot make any sense of this patch.
>>>>> insn->dst_reg above is 0.
>>>>> The kfunc call doesn't define a register from insn_def_regno() pov.
>>>>>
>>>>> Are you hacking insn_def_regno() to return 0 so that
>>>>> if (WARN_ON(load_reg == -1)) {
>>>>>      verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
>>>>>      return -EFAULT;
>>>>> }
>>>>> in opt_subreg_zext_lo32_rnd_hi32() doesn't trigger ?
>>>>>
>>>>> But this verifier message should have been a hint that you need
>>>>> to analyze why zext_dst is set on this kfunc call.
>>>>> Maybe it shouldn't ?
>>>>> Did you analyze the logic of mark_btf_func_reg_size() ?
>>>> make r0 zext is not caused by mark_btf_func_reg_size.
>>>>
>>>> This problem occurs when running the kfunc_call_test_ref_btf_id test
>>>> case in the 32-bit ARM environment.
>>>
>>> Why is it not failing on x86-32 ?
>> Use the latest mainline kernel code to test on the x86_32 machine. The
>> test also fails:
>>
>>     # ./test_progs -t kfunc_call/kfunc_call_test_ref_btf_id
>>     Failed to load bpf_testmod.ko into the kernel: -8
>>     WARNING! Selftests relying on bpf_testmod.ko will be skipped.
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': BPF program load failed:
>> Bad address
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': -- BEGIN PROG LOAD LOG --
>>     processed 25 insns (limit 1000000) max_states_per_insn 0 total_states
>> 2 peak_states 2 mark_read 1
>>     -- END PROG LOAD LOG --
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': failed to load: -14
>>     libbpf: failed to load object 'kfunc_call_test'
>>     libbpf: failed to load BPF skeleton 'kfunc_call_test': -14
>>     verify_success:FAIL:skel unexpected error: -14
>>
>> Therefore, this problem also exists on x86_32:
>> "verifier bug. zext_dst is set, but no reg is defined"
> 
> The kernel returns -14 == EFAULT.
> That's a completely different issue.
It's the same problem. The opt_subreg_zext_lo32_rnd_hi32 function fails 
to check here and returns -EFAULT

opt_subreg_zext_lo32_rnd_hi32 {
   ...
    if (WARN_ON(load_reg == -1)) { 

            verbose(env, "verifier bug. zext_dst is set, but no reg is 
defined\n");
            return -EFAULT; 

    }
   ...
} 

> .
> 

WARNING: multiple messages have this Message-ID (diff)
From: Yang Jihong <yangjihong1@huawei.com>
To: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Andrii Nakryiko <andrii@kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Song Liu <song@kernel.org>, Yonghong Song <yhs@fb.com>,
	John Fastabend <john.fastabend@gmail.com>,
	KP Singh <kpsingh@kernel.org>,
	Stanislav Fomichev <sdf@google.com>, Hao Luo <haoluo@google.com>,
	Jiri Olsa <jolsa@kernel.org>,
	Shubham Bansal <illusionist.neo@gmail.com>,
	Russell King <linux@armlinux.org.uk>,
	"David S. Miller" <davem@davemloft.net>,
	Eric Dumazet <edumazet@google.com>,
	Jakub Kicinski <kuba@kernel.org>, Paolo Abeni <pabeni@redhat.com>,
	Mykola Lysenko <mykolal@fb.com>, Shuah Khan <shuah@kernel.org>,
	Benjamin Tissoires <benjamin.tissoires@redhat.com>,
	Kumar Kartikeya Dwivedi <memxor@gmail.com>,
	<colin.i.king@gmail.com>, Artem Savkov <asavkov@redhat.com>,
	Delyan Kratunov <delyank@fb.com>, bpf <bpf@vger.kernel.org>,
	linux-arm-kernel <linux-arm-kernel@lists.infradead.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Network Development <netdev@vger.kernel.org>,
	"open list:KERNEL SELFTEST FRAMEWORK"
	<linux-kselftest@vger.kernel.org>
Subject: Re: [PATCH bpf-next v3 1/4] bpf: Adapt 32-bit return value kfunc for 32-bit ARM when zext extension
Date: Mon, 5 Dec 2022 09:19:40 +0800	[thread overview]
Message-ID: <4a2b8cd5-78c4-360a-6eb0-33fcf689d26a@huawei.com> (raw)
In-Reply-To: <CAADnVQJXr6XxpG2E-AkO7__qg-sujrhyO+JWWa1iwYmAO4S0Pw@mail.gmail.com>



On 2022/12/4 0:40, Alexei Starovoitov wrote:
> On Fri, Dec 2, 2022 at 6:58 PM Yang Jihong <yangjihong1@huawei.com> wrote:
>>
>>
>>
>> On 2022/11/29 0:41, Alexei Starovoitov wrote:
>>> On Mon, Nov 28, 2022 at 4:40 AM Yang Jihong <yangjihong1@huawei.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2022/11/28 9:57, Alexei Starovoitov wrote:
>>>>> On Sat, Nov 26, 2022 at 05:45:27PM +0800, Yang Jihong wrote:
>>>>>> For ARM32 architecture, if data width of kfunc return value is 32 bits,
>>>>>> need to do explicit zero extension for high 32-bit, insn_def_regno should
>>>>>> return dst_reg for BPF_JMP type of BPF_PSEUDO_KFUNC_CALL. Otherwise,
>>>>>> opt_subreg_zext_lo32_rnd_hi32 returns -EFAULT, resulting in BPF failure.
>>>>>>
>>>>>> Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
>>>>>> ---
>>>>>>     kernel/bpf/verifier.c | 44 ++++++++++++++++++++++++++++++++++++++++---
>>>>>>     1 file changed, 41 insertions(+), 3 deletions(-)
>>>>>>
>>>>>> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
>>>>>> index 264b3dc714cc..193ea927aa69 100644
>>>>>> --- a/kernel/bpf/verifier.c
>>>>>> +++ b/kernel/bpf/verifier.c
>>>>>> @@ -1927,6 +1927,21 @@ find_kfunc_desc(const struct bpf_prog *prog, u32 func_id, u16 offset)
>>>>>>                       sizeof(tab->descs[0]), kfunc_desc_cmp_by_id_off);
>>>>>>     }
>>>>>>
>>>>>> +static int kfunc_desc_cmp_by_imm(const void *a, const void *b);
>>>>>> +
>>>>>> +static const struct bpf_kfunc_desc *
>>>>>> +find_kfunc_desc_by_imm(const struct bpf_prog *prog, s32 imm)
>>>>>> +{
>>>>>> +    struct bpf_kfunc_desc desc = {
>>>>>> +            .imm = imm,
>>>>>> +    };
>>>>>> +    struct bpf_kfunc_desc_tab *tab;
>>>>>> +
>>>>>> +    tab = prog->aux->kfunc_tab;
>>>>>> +    return bsearch(&desc, tab->descs, tab->nr_descs,
>>>>>> +                   sizeof(tab->descs[0]), kfunc_desc_cmp_by_imm);
>>>>>> +}
>>>>>> +
>>>>>>     static struct btf *__find_kfunc_desc_btf(struct bpf_verifier_env *env,
>>>>>>                                         s16 offset)
>>>>>>     {
>>>>>> @@ -2342,6 +2357,13 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
>>>>>>                         */
>>>>>>                        if (insn->src_reg == BPF_PSEUDO_CALL)
>>>>>>                                return false;
>>>>>> +
>>>>>> +                    /* Kfunc call will reach here because of insn_has_def32,
>>>>>> +                     * conservatively return TRUE.
>>>>>> +                     */
>>>>>> +                    if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL)
>>>>>> +                            return true;
>>>>>> +
>>>>>>                        /* Helper call will reach here because of arg type
>>>>>>                         * check, conservatively return TRUE.
>>>>>>                         */
>>>>>> @@ -2405,10 +2427,26 @@ static bool is_reg64(struct bpf_verifier_env *env, struct bpf_insn *insn,
>>>>>>     }
>>>>>>
>>>>>>     /* Return the regno defined by the insn, or -1. */
>>>>>> -static int insn_def_regno(const struct bpf_insn *insn)
>>>>>> +static int insn_def_regno(struct bpf_verifier_env *env, const struct bpf_insn *insn)
>>>>>>     {
>>>>>>        switch (BPF_CLASS(insn->code)) {
>>>>>>        case BPF_JMP:
>>>>>> +            if (insn->src_reg == BPF_PSEUDO_KFUNC_CALL) {
>>>>>> +                    const struct bpf_kfunc_desc *desc;
>>>>>> +
>>>>>> +                    /* The value of desc cannot be NULL */
>>>>>> +                    desc = find_kfunc_desc_by_imm(env->prog, insn->imm);
>>>>>> +
>>>>>> +                    /* A kfunc can return void.
>>>>>> +                     * The btf type of the kfunc's return value needs
>>>>>> +                     * to be checked against "void" first
>>>>>> +                     */
>>>>>> +                    if (desc->func_model.ret_size == 0)
>>>>>> +                            return -1;
>>>>>> +                    else
>>>>>> +                            return insn->dst_reg;
>>>>>> +            }
>>>>>> +            fallthrough;
>>>>>
>>>>> I cannot make any sense of this patch.
>>>>> insn->dst_reg above is 0.
>>>>> The kfunc call doesn't define a register from insn_def_regno() pov.
>>>>>
>>>>> Are you hacking insn_def_regno() to return 0 so that
>>>>> if (WARN_ON(load_reg == -1)) {
>>>>>      verbose(env, "verifier bug. zext_dst is set, but no reg is defined\n");
>>>>>      return -EFAULT;
>>>>> }
>>>>> in opt_subreg_zext_lo32_rnd_hi32() doesn't trigger ?
>>>>>
>>>>> But this verifier message should have been a hint that you need
>>>>> to analyze why zext_dst is set on this kfunc call.
>>>>> Maybe it shouldn't ?
>>>>> Did you analyze the logic of mark_btf_func_reg_size() ?
>>>> make r0 zext is not caused by mark_btf_func_reg_size.
>>>>
>>>> This problem occurs when running the kfunc_call_test_ref_btf_id test
>>>> case in the 32-bit ARM environment.
>>>
>>> Why is it not failing on x86-32 ?
>> Use the latest mainline kernel code to test on the x86_32 machine. The
>> test also fails:
>>
>>     # ./test_progs -t kfunc_call/kfunc_call_test_ref_btf_id
>>     Failed to load bpf_testmod.ko into the kernel: -8
>>     WARNING! Selftests relying on bpf_testmod.ko will be skipped.
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': BPF program load failed:
>> Bad address
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': -- BEGIN PROG LOAD LOG --
>>     processed 25 insns (limit 1000000) max_states_per_insn 0 total_states
>> 2 peak_states 2 mark_read 1
>>     -- END PROG LOAD LOG --
>>     libbpf: prog 'kfunc_call_test_ref_btf_id': failed to load: -14
>>     libbpf: failed to load object 'kfunc_call_test'
>>     libbpf: failed to load BPF skeleton 'kfunc_call_test': -14
>>     verify_success:FAIL:skel unexpected error: -14
>>
>> Therefore, this problem also exists on x86_32:
>> "verifier bug. zext_dst is set, but no reg is defined"
> 
> The kernel returns -14 == EFAULT.
> That's a completely different issue.
It's the same problem. The opt_subreg_zext_lo32_rnd_hi32 function fails 
to check here and returns -EFAULT

opt_subreg_zext_lo32_rnd_hi32 {
   ...
    if (WARN_ON(load_reg == -1)) { 

            verbose(env, "verifier bug. zext_dst is set, but no reg is 
defined\n");
            return -EFAULT; 

    }
   ...
} 

> .
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2022-12-05  1:19 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-26  9:45 [PATCH bpf-next v3 0/4] bpf: Support kernel function call in 32-bit ARM Yang Jihong
2022-11-26  9:45 ` Yang Jihong
2022-11-26  9:45 ` [PATCH bpf-next v3 1/4] bpf: Adapt 32-bit return value kfunc for 32-bit ARM when zext extension Yang Jihong
2022-11-26  9:45   ` Yang Jihong
2022-11-28  1:57   ` Alexei Starovoitov
2022-11-28  1:57     ` Alexei Starovoitov
2022-11-28 12:40     ` Yang Jihong
2022-11-28 12:40       ` Yang Jihong
2022-11-28 16:41       ` Alexei Starovoitov
2022-11-28 16:41         ` Alexei Starovoitov
2022-12-03  2:58         ` Yang Jihong
2022-12-03  2:58           ` Yang Jihong
2022-12-03 16:40           ` Alexei Starovoitov
2022-12-03 16:40             ` Alexei Starovoitov
2022-12-05  1:19             ` Yang Jihong [this message]
2022-12-05  1:19               ` Yang Jihong
2022-12-07  8:49               ` Yang Jihong
2022-12-07  8:49                 ` Yang Jihong
2022-12-02  4:11   ` kernel test robot
2022-11-26  9:45 ` [PATCH bpf-next v3 2/4] bpf: Add kernel function call support in 32-bit ARM for EABI Yang Jihong
2022-11-26  9:45   ` Yang Jihong
2022-11-26  9:45 ` [PATCH bpf-next v3 3/4] bpf:selftests: Add kfunc_call test for mixing 32-bit and 64-bit parameters Yang Jihong
2022-11-26  9:45   ` Yang Jihong
2022-11-26  9:45 ` [PATCH bpf-next v3 4/4] bpf: Fix comment error in fixup_kfunc_call function Yang Jihong
2022-11-26  9:45   ` Yang Jihong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4a2b8cd5-78c4-360a-6eb0-33fcf689d26a@huawei.com \
    --to=yangjihong1@huawei.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=asavkov@redhat.com \
    --cc=ast@kernel.org \
    --cc=benjamin.tissoires@redhat.com \
    --cc=bpf@vger.kernel.org \
    --cc=colin.i.king@gmail.com \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=delyank@fb.com \
    --cc=edumazet@google.com \
    --cc=haoluo@google.com \
    --cc=illusionist.neo@gmail.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=linux@armlinux.org.uk \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=mykolal@fb.com \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=sdf@google.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yhs@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.