diff mbox series

[bpf-next,v1,2/4] compiler_types: define __percpu as __attribute__((btf_type_tag("percpu")))

Message ID 20220304191657.981240-3-haoluo@google.com (mailing list archive)
State Accepted
Commit 9216c916237805c93d054ed022afb172ddbc3ed1
Delegated to: BPF
Headers show
Series bpf: add __percpu tagging in vmlinux BTF | expand

Checks

Context Check Description
netdev/tree_selection success Clearly marked for bpf-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/subject_prefix success Link
netdev/cover_letter success Series has a cover letter
netdev/patch_count success Link
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 17983 this patch: 17983
netdev/cc_maintainers warning 10 maintainers not CCed: john.fastabend@gmail.com kafai@fb.com songliubraving@fb.com ojeda@kernel.org nathan@kernel.org llvm@lists.linux.dev keescook@chromium.org netdev@vger.kernel.org elver@google.com ndesaulniers@google.com
netdev/build_clang success Errors and warnings before: 3942 this patch: 3942
netdev/module_param success Was 0 now: 0
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn success Errors and warnings before: 17601 this patch: 17601
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 13 lines checked
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0
bpf/vmtest-bpf-next-PR success PR summary
bpf/vmtest-bpf-next success VM_Test

Commit Message

Hao Luo March 4, 2022, 7:16 p.m. UTC
This is similar to commit 7472d5a642c9 ("compiler_types: define __user as
__attribute__((btf_type_tag("user")))"), where a type tag "user" was
introduced to identify the pointers that point to user memory. With that
change, the newest compile toolchain can encode __user information into
vmlinux BTF, which can be used by the BPF verifier to enforce safe
program behaviors.

Similarly, we have __percpu attribute, which is mainly used to indicate
memory is allocated in percpu region. The __percpu pointers in kernel
are supposed to be used together with functions like per_cpu_ptr() and
this_cpu_ptr(), which perform necessary calculation on the pointer's
base address. Without the btf_type_tag introduced in this patch,
__percpu pointers will be treated as regular memory pointers in vmlinux
BTF and BPF programs are allowed to directly dereference them, generating
incorrect behaviors. Now with "percpu" btf_type_tag, the BPF verifier is
able to differentiate __percpu pointers from regular pointers and forbids
unexpected behaviors like direct load.

The following is an example similar to the one given in commit
7472d5a642c9:

  [$ ~] cat test.c
  #define __percpu __attribute__((btf_type_tag("percpu")))
  int foo(int __percpu *arg) {
  	return *arg;
  }
  [$ ~] clang -O2 -g -c test.c
  [$ ~] pahole -JV test.o
  ...
  File test.o:
  [1] INT int size=4 nr_bits=32 encoding=SIGNED
  [2] TYPE_TAG percpu type_id=1
  [3] PTR (anon) type_id=2
  [4] FUNC_PROTO (anon) return=1 args=(3 arg)
  [5] FUNC foo type_id=4
  [$ ~]

for the function argument "int __percpu *arg", its type is described as
	PTR -> TYPE_TAG(percpu) -> INT
The kernel can use this information for bpf verification or other
use cases.

Like commit 7472d5a642c9, this feature requires clang (>= clang14) and
pahole (>= 1.23).

Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Hao Luo <haoluo@google.com>
---
 include/linux/compiler_types.h | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

Comments

Yonghong Song March 5, 2022, 8:06 p.m. UTC | #1
On 3/4/22 11:16 AM, Hao Luo wrote:
> This is similar to commit 7472d5a642c9 ("compiler_types: define __user as
> __attribute__((btf_type_tag("user")))"), where a type tag "user" was
> introduced to identify the pointers that point to user memory. With that
> change, the newest compile toolchain can encode __user information into
> vmlinux BTF, which can be used by the BPF verifier to enforce safe
> program behaviors.
> 
> Similarly, we have __percpu attribute, which is mainly used to indicate
> memory is allocated in percpu region. The __percpu pointers in kernel
> are supposed to be used together with functions like per_cpu_ptr() and
> this_cpu_ptr(), which perform necessary calculation on the pointer's
> base address. Without the btf_type_tag introduced in this patch,
> __percpu pointers will be treated as regular memory pointers in vmlinux
> BTF and BPF programs are allowed to directly dereference them, generating
> incorrect behaviors. Now with "percpu" btf_type_tag, the BPF verifier is
> able to differentiate __percpu pointers from regular pointers and forbids
> unexpected behaviors like direct load.
> 
> The following is an example similar to the one given in commit
> 7472d5a642c9:
> 
>    [$ ~] cat test.c
>    #define __percpu __attribute__((btf_type_tag("percpu")))
>    int foo(int __percpu *arg) {
>    	return *arg;
>    }
>    [$ ~] clang -O2 -g -c test.c
>    [$ ~] pahole -JV test.o
>    ...
>    File test.o:
>    [1] INT int size=4 nr_bits=32 encoding=SIGNED
>    [2] TYPE_TAG percpu type_id=1
>    [3] PTR (anon) type_id=2
>    [4] FUNC_PROTO (anon) return=1 args=(3 arg)
>    [5] FUNC foo type_id=4
>    [$ ~]
> 
> for the function argument "int __percpu *arg", its type is described as
> 	PTR -> TYPE_TAG(percpu) -> INT
> The kernel can use this information for bpf verification or other
> use cases.
> 
> Like commit 7472d5a642c9, this feature requires clang (>= clang14) and
> pahole (>= 1.23).
> 
> Cc: Yonghong Song <yhs@fb.com>
> Signed-off-by: Hao Luo <haoluo@google.com>

Acked-by: Yonghong Song <yhs@fb.com>
Andrii Nakryiko March 8, 2022, 1:44 a.m. UTC | #2
On Fri, Mar 4, 2022 at 11:17 AM Hao Luo <haoluo@google.com> wrote:
>
> This is similar to commit 7472d5a642c9 ("compiler_types: define __user as
> __attribute__((btf_type_tag("user")))"), where a type tag "user" was
> introduced to identify the pointers that point to user memory. With that
> change, the newest compile toolchain can encode __user information into
> vmlinux BTF, which can be used by the BPF verifier to enforce safe
> program behaviors.
>
> Similarly, we have __percpu attribute, which is mainly used to indicate
> memory is allocated in percpu region. The __percpu pointers in kernel
> are supposed to be used together with functions like per_cpu_ptr() and
> this_cpu_ptr(), which perform necessary calculation on the pointer's
> base address. Without the btf_type_tag introduced in this patch,
> __percpu pointers will be treated as regular memory pointers in vmlinux
> BTF and BPF programs are allowed to directly dereference them, generating
> incorrect behaviors. Now with "percpu" btf_type_tag, the BPF verifier is
> able to differentiate __percpu pointers from regular pointers and forbids
> unexpected behaviors like direct load.
>
> The following is an example similar to the one given in commit
> 7472d5a642c9:
>
>   [$ ~] cat test.c
>   #define __percpu __attribute__((btf_type_tag("percpu")))
>   int foo(int __percpu *arg) {
>         return *arg;
>   }
>   [$ ~] clang -O2 -g -c test.c
>   [$ ~] pahole -JV test.o
>   ...
>   File test.o:
>   [1] INT int size=4 nr_bits=32 encoding=SIGNED
>   [2] TYPE_TAG percpu type_id=1
>   [3] PTR (anon) type_id=2
>   [4] FUNC_PROTO (anon) return=1 args=(3 arg)
>   [5] FUNC foo type_id=4
>   [$ ~]
>
> for the function argument "int __percpu *arg", its type is described as
>         PTR -> TYPE_TAG(percpu) -> INT
> The kernel can use this information for bpf verification or other
> use cases.
>
> Like commit 7472d5a642c9, this feature requires clang (>= clang14) and
> pahole (>= 1.23).
>
> Cc: Yonghong Song <yhs@fb.com>
> Signed-off-by: Hao Luo <haoluo@google.com>
> ---
>  include/linux/compiler_types.h | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> index 3f31ff400432..223abf43679a 100644
> --- a/include/linux/compiler_types.h
> +++ b/include/linux/compiler_types.h
> @@ -38,7 +38,12 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
>  #  define __user
>  # endif
>  # define __iomem
> -# define __percpu
> +# if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
> +       __has_attribute(btf_type_tag)
> +#  define __percpu     __attribute__((btf_type_tag("percpu")))


Maybe let's add

#if defined(CONFIG_DEBUG_INFO_BTF) &&
defined(CONFIG_PAHOLE_HAS_BTF_TAG) && __has_attribute(btf_type_tag)
#define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
#else
#define BTF_TYPE_TAG(value) /* nothing */
#endif

and use BTF_TYPE_TAG() macro unconditionally everywhere?

> +# else
> +#  define __percpu
> +# endif
>  # define __rcu
>  # define __chk_user_ptr(x)     (void)0
>  # define __chk_io_ptr(x)       (void)0
> --
> 2.35.1.616.g0bdcbb4464-goog
>
Yonghong Song March 9, 2022, 7:07 a.m. UTC | #3
On 3/7/22 5:44 PM, Andrii Nakryiko wrote:
> On Fri, Mar 4, 2022 at 11:17 AM Hao Luo <haoluo@google.com> wrote:
>>
>> This is similar to commit 7472d5a642c9 ("compiler_types: define __user as
>> __attribute__((btf_type_tag("user")))"), where a type tag "user" was
>> introduced to identify the pointers that point to user memory. With that
>> change, the newest compile toolchain can encode __user information into
>> vmlinux BTF, which can be used by the BPF verifier to enforce safe
>> program behaviors.
>>
>> Similarly, we have __percpu attribute, which is mainly used to indicate
>> memory is allocated in percpu region. The __percpu pointers in kernel
>> are supposed to be used together with functions like per_cpu_ptr() and
>> this_cpu_ptr(), which perform necessary calculation on the pointer's
>> base address. Without the btf_type_tag introduced in this patch,
>> __percpu pointers will be treated as regular memory pointers in vmlinux
>> BTF and BPF programs are allowed to directly dereference them, generating
>> incorrect behaviors. Now with "percpu" btf_type_tag, the BPF verifier is
>> able to differentiate __percpu pointers from regular pointers and forbids
>> unexpected behaviors like direct load.
>>
>> The following is an example similar to the one given in commit
>> 7472d5a642c9:
>>
>>    [$ ~] cat test.c
>>    #define __percpu __attribute__((btf_type_tag("percpu")))
>>    int foo(int __percpu *arg) {
>>          return *arg;
>>    }
>>    [$ ~] clang -O2 -g -c test.c
>>    [$ ~] pahole -JV test.o
>>    ...
>>    File test.o:
>>    [1] INT int size=4 nr_bits=32 encoding=SIGNED
>>    [2] TYPE_TAG percpu type_id=1
>>    [3] PTR (anon) type_id=2
>>    [4] FUNC_PROTO (anon) return=1 args=(3 arg)
>>    [5] FUNC foo type_id=4
>>    [$ ~]
>>
>> for the function argument "int __percpu *arg", its type is described as
>>          PTR -> TYPE_TAG(percpu) -> INT
>> The kernel can use this information for bpf verification or other
>> use cases.
>>
>> Like commit 7472d5a642c9, this feature requires clang (>= clang14) and
>> pahole (>= 1.23).
>>
>> Cc: Yonghong Song <yhs@fb.com>
>> Signed-off-by: Hao Luo <haoluo@google.com>
>> ---
>>   include/linux/compiler_types.h | 7 ++++++-
>>   1 file changed, 6 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
>> index 3f31ff400432..223abf43679a 100644
>> --- a/include/linux/compiler_types.h
>> +++ b/include/linux/compiler_types.h
>> @@ -38,7 +38,12 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
>>   #  define __user
>>   # endif
>>   # define __iomem
>> -# define __percpu
>> +# if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
>> +       __has_attribute(btf_type_tag)
>> +#  define __percpu     __attribute__((btf_type_tag("percpu")))
> 
> 
> Maybe let's add
> 
> #if defined(CONFIG_DEBUG_INFO_BTF) &&
> defined(CONFIG_PAHOLE_HAS_BTF_TAG) && __has_attribute(btf_type_tag)
> #define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
> #else
> #define BTF_TYPE_TAG(value) /* nothing */
> #endif
> 
> and use BTF_TYPE_TAG() macro unconditionally everywhere?

Agree that the above suggestion is a good idea, esp. we may
convert others, e.g., __rcu, with btf_type_tag in the future,
and a common checking will simplify things a lot.

Hao, could you send a followup patch with Andrii's suggestion?

> 
>> +# else
>> +#  define __percpu
>> +# endif
>>   # define __rcu
>>   # define __chk_user_ptr(x)     (void)0
>>   # define __chk_io_ptr(x)       (void)0
>> --
>> 2.35.1.616.g0bdcbb4464-goog
>>
Hao Luo March 9, 2022, 7:31 p.m. UTC | #4
On Tue, Mar 8, 2022 at 11:08 PM Yonghong Song <yhs@fb.com> wrote:
>
>
>
> On 3/7/22 5:44 PM, Andrii Nakryiko wrote:
> > On Fri, Mar 4, 2022 at 11:17 AM Hao Luo <haoluo@google.com> wrote:
> >>
[...]
> >>
> >> diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
> >> index 3f31ff400432..223abf43679a 100644
> >> --- a/include/linux/compiler_types.h
> >> +++ b/include/linux/compiler_types.h
> >> @@ -38,7 +38,12 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
> >>   #  define __user
> >>   # endif
> >>   # define __iomem
> >> -# define __percpu
> >> +# if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
> >> +       __has_attribute(btf_type_tag)
> >> +#  define __percpu     __attribute__((btf_type_tag("percpu")))
> >
> >
> > Maybe let's add
> >
> > #if defined(CONFIG_DEBUG_INFO_BTF) &&
> > defined(CONFIG_PAHOLE_HAS_BTF_TAG) && __has_attribute(btf_type_tag)
> > #define BTF_TYPE_TAG(value) __attribute__((btf_type_tag(#value)))
> > #else
> > #define BTF_TYPE_TAG(value) /* nothing */
> > #endif
> >
> > and use BTF_TYPE_TAG() macro unconditionally everywhere?
>
> Agree that the above suggestion is a good idea, esp. we may
> convert others, e.g., __rcu, with btf_type_tag in the future,
> and a common checking will simplify things a lot.
>
> Hao, could you send a followup patch with Andrii's suggestion?
>

No problem. Will send the patch this afternoon.
diff mbox series

Patch

diff --git a/include/linux/compiler_types.h b/include/linux/compiler_types.h
index 3f31ff400432..223abf43679a 100644
--- a/include/linux/compiler_types.h
+++ b/include/linux/compiler_types.h
@@ -38,7 +38,12 @@  static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
 #  define __user
 # endif
 # define __iomem
-# define __percpu
+# if defined(CONFIG_DEBUG_INFO_BTF) && defined(CONFIG_PAHOLE_HAS_BTF_TAG) && \
+	__has_attribute(btf_type_tag)
+#  define __percpu	__attribute__((btf_type_tag("percpu")))
+# else
+#  define __percpu
+# endif
 # define __rcu
 # define __chk_user_ptr(x)	(void)0
 # define __chk_io_ptr(x)	(void)0