diff mbox series

[03/11] bpf: Add btf_ids object

Message ID 20200616100512.2168860-4-jolsa@kernel.org
State Changes Requested
Delegated to: BPF Maintainers
Headers show
Series bpf: Add d_path helper | expand

Commit Message

Jiri Olsa June 16, 2020, 10:05 a.m. UTC
Adding support to generate .BTF_ids section that would
hold various BTF IDs list for verifier.

Adding macros help to define lists of BTF IDs placed in
.BTF_ids section. They are initially filled with zeros
(during compilation) and resolved later during the
linking phase by btfid tool.

Following defines list of one BTF ID that is accessible
within kernel code as bpf_skb_output_btf_ids array.

  extern int bpf_skb_output_btf_ids[];

  BTF_ID_LIST(bpf_skb_output_btf_ids)
  BTF_ID(struct, sk_buff)

Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 include/asm-generic/vmlinux.lds.h |  4 ++
 kernel/bpf/Makefile               |  2 +-
 kernel/bpf/btf_ids.c              |  3 ++
 kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 1 deletion(-)
 create mode 100644 kernel/bpf/btf_ids.c
 create mode 100644 kernel/bpf/btf_ids.h

Comments

Andrii Nakryiko June 19, 2020, 12:56 a.m. UTC | #1
On Tue, Jun 16, 2020 at 3:05 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Adding support to generate .BTF_ids section that would
> hold various BTF IDs list for verifier.
>
> Adding macros help to define lists of BTF IDs placed in
> .BTF_ids section. They are initially filled with zeros
> (during compilation) and resolved later during the
> linking phase by btfid tool.
>
> Following defines list of one BTF ID that is accessible
> within kernel code as bpf_skb_output_btf_ids array.
>
>   extern int bpf_skb_output_btf_ids[];
>
>   BTF_ID_LIST(bpf_skb_output_btf_ids)
>   BTF_ID(struct, sk_buff)
>
> Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  include/asm-generic/vmlinux.lds.h |  4 ++
>  kernel/bpf/Makefile               |  2 +-
>  kernel/bpf/btf_ids.c              |  3 ++
>  kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
>  4 files changed, 78 insertions(+), 1 deletion(-)
>  create mode 100644 kernel/bpf/btf_ids.c
>  create mode 100644 kernel/bpf/btf_ids.h
>

[...]

> +/*
> + * Following macros help to define lists of BTF IDs placed
> + * in .BTF_ids section. They are initially filled with zeros
> + * (during compilation) and resolved later during the
> + * linking phase by btfid tool.
> + *
> + * Any change in list layout must be reflected in btfid
> + * tool logic.
> + */
> +
> +#define SECTION ".BTF_ids"

nit: SECTION is super generic and non-greppable. BTF_IDS_SECTION?

> +
> +#define ____BTF_ID(symbol)                             \
> +asm(                                                   \
> +".pushsection " SECTION ",\"a\";               \n"     \

section should be also read-only? Either immediately here, of btfid
tool should mark it? Unless I missed that it's already doing it :)

> +".local " #symbol " ;                          \n"     \
> +".type  " #symbol ", @object;                  \n"     \
> +".size  " #symbol ", 4;                        \n"     \
> +#symbol ":                                     \n"     \
> +".zero 4                                       \n"     \
> +".popsection;                                  \n");
> +
> +#define __BTF_ID(...) \
> +       ____BTF_ID(__VA_ARGS__)

why varargs, if it's always a single argument? Or it's one of those
macro black magic things were it works only in this particular case,
but not others?


> +
> +#define __ID(prefix) \
> +       __PASTE(prefix, __COUNTER__)
> +
> +
> +/*
> + * The BTF_ID defines unique symbol for each ID pointing
> + * to 4 zero bytes.
> + */
> +#define BTF_ID(prefix, name) \
> +       __BTF_ID(__ID(__BTF_ID__##prefix##__##name##__))
> +
> +
> +/*
> + * The BTF_ID_LIST macro defines pure (unsorted) list
> + * of BTF IDs, with following layout:
> + *
> + * BTF_ID_LIST(list1)
> + * BTF_ID(type1, name1)
> + * BTF_ID(type2, name2)
> + *
> + * list1:
> + * __BTF_ID__type1__name1__1:
> + * .zero 4
> + * __BTF_ID__type2__name2__2:
> + * .zero 4
> + *
> + */
> +#define BTF_ID_LIST(name)                              \

nit: btw, you call it a list here, but btfids tool talks about
"sorts". Maybe stick to consistent naming. Either "list" or "set"
seems to be appropriate. Set implies a sorted aspect a bit more, IMO.

> +asm(                                                   \
> +".pushsection " SECTION ",\"a\";               \n"     \
> +".global " #name ";                            \n"     \

I was expecting to see reserved 4 bytes for list size? I also couldn't
find where btfids tool prepends it. From what I could understand, it
just assumed the first 4 bytes are the length prefix? Sorry if I'm
slow...


> +#name ":;                                      \n"     \
> +".popsection;                                  \n");
> +
> +#endif
> --
> 2.25.4
>
Andrii Nakryiko June 19, 2020, 1:02 a.m. UTC | #2
On Tue, Jun 16, 2020 at 3:05 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Adding support to generate .BTF_ids section that would
> hold various BTF IDs list for verifier.
>
> Adding macros help to define lists of BTF IDs placed in
> .BTF_ids section. They are initially filled with zeros
> (during compilation) and resolved later during the
> linking phase by btfid tool.
>
> Following defines list of one BTF ID that is accessible
> within kernel code as bpf_skb_output_btf_ids array.
>
>   extern int bpf_skb_output_btf_ids[];
>
>   BTF_ID_LIST(bpf_skb_output_btf_ids)
>   BTF_ID(struct, sk_buff)
>
> Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  include/asm-generic/vmlinux.lds.h |  4 ++
>  kernel/bpf/Makefile               |  2 +-
>  kernel/bpf/btf_ids.c              |  3 ++
>  kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
>  4 files changed, 78 insertions(+), 1 deletion(-)
>  create mode 100644 kernel/bpf/btf_ids.c
>  create mode 100644 kernel/bpf/btf_ids.h
>
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index db600ef218d7..0be2ee265931 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -641,6 +641,10 @@
>                 __start_BTF = .;                                        \
>                 *(.BTF)                                                 \
>                 __stop_BTF = .;                                         \
> +       }                                                               \
> +       . = ALIGN(4);                                                   \
> +       .BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) {                   \
> +               *(.BTF_ids)                                             \
>         }
>  #else
>  #define BTF
> diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
> index 1131a921e1a6..21e4fc7c25ab 100644
> --- a/kernel/bpf/Makefile
> +++ b/kernel/bpf/Makefile
> @@ -7,7 +7,7 @@ obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list
>  obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o
>  obj-$(CONFIG_BPF_SYSCALL) += disasm.o
>  obj-$(CONFIG_BPF_JIT) += trampoline.o
> -obj-$(CONFIG_BPF_SYSCALL) += btf.o
> +obj-$(CONFIG_BPF_SYSCALL) += btf.o btf_ids.o
>  obj-$(CONFIG_BPF_JIT) += dispatcher.o
>  ifeq ($(CONFIG_NET),y)
>  obj-$(CONFIG_BPF_SYSCALL) += devmap.o
> diff --git a/kernel/bpf/btf_ids.c b/kernel/bpf/btf_ids.c
> new file mode 100644
> index 000000000000..e7f9d94ad293
> --- /dev/null
> +++ b/kernel/bpf/btf_ids.c
> @@ -0,0 +1,3 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +
> +#include "btf_ids.h"

hm... what's the purpose of this btf_ids.c file?

> diff --git a/kernel/bpf/btf_ids.h b/kernel/bpf/btf_ids.h
> new file mode 100644
> index 000000000000..68aa5c38a37f
> --- /dev/null
> +++ b/kernel/bpf/btf_ids.h

[...]
Andrii Nakryiko June 19, 2020, 1:06 a.m. UTC | #3
On Thu, Jun 18, 2020 at 5:56 PM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Tue, Jun 16, 2020 at 3:05 AM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Adding support to generate .BTF_ids section that would
> > hold various BTF IDs list for verifier.
> >
> > Adding macros help to define lists of BTF IDs placed in
> > .BTF_ids section. They are initially filled with zeros
> > (during compilation) and resolved later during the
> > linking phase by btfid tool.
> >
> > Following defines list of one BTF ID that is accessible
> > within kernel code as bpf_skb_output_btf_ids array.
> >
> >   extern int bpf_skb_output_btf_ids[];
> >
> >   BTF_ID_LIST(bpf_skb_output_btf_ids)
> >   BTF_ID(struct, sk_buff)
> >
> > Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  include/asm-generic/vmlinux.lds.h |  4 ++
> >  kernel/bpf/Makefile               |  2 +-
> >  kernel/bpf/btf_ids.c              |  3 ++
> >  kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
> >  4 files changed, 78 insertions(+), 1 deletion(-)
> >  create mode 100644 kernel/bpf/btf_ids.c
> >  create mode 100644 kernel/bpf/btf_ids.h
> >
>
> [...]
>
> > +/*
> > + * Following macros help to define lists of BTF IDs placed
> > + * in .BTF_ids section. They are initially filled with zeros
> > + * (during compilation) and resolved later during the
> > + * linking phase by btfid tool.
> > + *
> > + * Any change in list layout must be reflected in btfid
> > + * tool logic.
> > + */
> > +
> > +#define SECTION ".BTF_ids"
>
> nit: SECTION is super generic and non-greppable. BTF_IDS_SECTION?
>
> > +
> > +#define ____BTF_ID(symbol)                             \
> > +asm(                                                   \
> > +".pushsection " SECTION ",\"a\";               \n"     \
>
> section should be also read-only? Either immediately here, of btfid
> tool should mark it? Unless I missed that it's already doing it :)
>
> > +".local " #symbol " ;                          \n"     \
> > +".type  " #symbol ", @object;                  \n"     \
> > +".size  " #symbol ", 4;                        \n"     \
> > +#symbol ":                                     \n"     \
> > +".zero 4                                       \n"     \
> > +".popsection;                                  \n");
> > +
> > +#define __BTF_ID(...) \
> > +       ____BTF_ID(__VA_ARGS__)
>
> why varargs, if it's always a single argument? Or it's one of those
> macro black magic things were it works only in this particular case,
> but not others?
>
>
> > +
> > +#define __ID(prefix) \
> > +       __PASTE(prefix, __COUNTER__)
> > +
> > +
> > +/*
> > + * The BTF_ID defines unique symbol for each ID pointing
> > + * to 4 zero bytes.
> > + */
> > +#define BTF_ID(prefix, name) \
> > +       __BTF_ID(__ID(__BTF_ID__##prefix##__##name##__))
> > +
> > +
> > +/*
> > + * The BTF_ID_LIST macro defines pure (unsorted) list
> > + * of BTF IDs, with following layout:
> > + *
> > + * BTF_ID_LIST(list1)
> > + * BTF_ID(type1, name1)
> > + * BTF_ID(type2, name2)
> > + *
> > + * list1:
> > + * __BTF_ID__type1__name1__1:
> > + * .zero 4
> > + * __BTF_ID__type2__name2__2:
> > + * .zero 4
> > + *
> > + */
> > +#define BTF_ID_LIST(name)                              \
>
> nit: btw, you call it a list here, but btfids tool talks about
> "sorts". Maybe stick to consistent naming. Either "list" or "set"
> seems to be appropriate. Set implies a sorted aspect a bit more, IMO.
>
> > +asm(                                                   \
> > +".pushsection " SECTION ",\"a\";               \n"     \
> > +".global " #name ";                            \n"     \
>
> I was expecting to see reserved 4 bytes for list size? I also couldn't
> find where btfids tool prepends it. From what I could understand, it
> just assumed the first 4 bytes are the length prefix? Sorry if I'm
> slow...

Never mind, this is different from whitelisting you do in patch #8.
But now I'm curious how this list symbol gets its size correctly
calculated?..

>
>
> > +#name ":;                                      \n"     \
> > +".popsection;                                  \n");
> > +
> > +#endif
> > --
> > 2.25.4
> >
Jiri Olsa June 19, 2020, 1:05 p.m. UTC | #4
On Thu, Jun 18, 2020 at 06:02:48PM -0700, Andrii Nakryiko wrote:

SNIP

> > diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> > index db600ef218d7..0be2ee265931 100644
> > --- a/include/asm-generic/vmlinux.lds.h
> > +++ b/include/asm-generic/vmlinux.lds.h
> > @@ -641,6 +641,10 @@
> >                 __start_BTF = .;                                        \
> >                 *(.BTF)                                                 \
> >                 __stop_BTF = .;                                         \
> > +       }                                                               \
> > +       . = ALIGN(4);                                                   \
> > +       .BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) {                   \
> > +               *(.BTF_ids)                                             \
> >         }
> >  #else
> >  #define BTF
> > diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
> > index 1131a921e1a6..21e4fc7c25ab 100644
> > --- a/kernel/bpf/Makefile
> > +++ b/kernel/bpf/Makefile
> > @@ -7,7 +7,7 @@ obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list
> >  obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o
> >  obj-$(CONFIG_BPF_SYSCALL) += disasm.o
> >  obj-$(CONFIG_BPF_JIT) += trampoline.o
> > -obj-$(CONFIG_BPF_SYSCALL) += btf.o
> > +obj-$(CONFIG_BPF_SYSCALL) += btf.o btf_ids.o
> >  obj-$(CONFIG_BPF_JIT) += dispatcher.o
> >  ifeq ($(CONFIG_NET),y)
> >  obj-$(CONFIG_BPF_SYSCALL) += devmap.o
> > diff --git a/kernel/bpf/btf_ids.c b/kernel/bpf/btf_ids.c
> > new file mode 100644
> > index 000000000000..e7f9d94ad293
> > --- /dev/null
> > +++ b/kernel/bpf/btf_ids.c
> > @@ -0,0 +1,3 @@
> > +// SPDX-License-Identifier: GPL-2.0-only
> > +
> > +#include "btf_ids.h"
> 
> hm... what's the purpose of this btf_ids.c file?

I put all the lists in here.. I can add it in that patch later on

jirka

> 
> > diff --git a/kernel/bpf/btf_ids.h b/kernel/bpf/btf_ids.h
> > new file mode 100644
> > index 000000000000..68aa5c38a37f
> > --- /dev/null
> > +++ b/kernel/bpf/btf_ids.h
> 
> [...]
>
Jiri Olsa June 19, 2020, 1:13 p.m. UTC | #5
On Thu, Jun 18, 2020 at 05:56:38PM -0700, Andrii Nakryiko wrote:
> On Tue, Jun 16, 2020 at 3:05 AM Jiri Olsa <jolsa@kernel.org> wrote:
> >
> > Adding support to generate .BTF_ids section that would
> > hold various BTF IDs list for verifier.
> >
> > Adding macros help to define lists of BTF IDs placed in
> > .BTF_ids section. They are initially filled with zeros
> > (during compilation) and resolved later during the
> > linking phase by btfid tool.
> >
> > Following defines list of one BTF ID that is accessible
> > within kernel code as bpf_skb_output_btf_ids array.
> >
> >   extern int bpf_skb_output_btf_ids[];
> >
> >   BTF_ID_LIST(bpf_skb_output_btf_ids)
> >   BTF_ID(struct, sk_buff)
> >
> > Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  include/asm-generic/vmlinux.lds.h |  4 ++
> >  kernel/bpf/Makefile               |  2 +-
> >  kernel/bpf/btf_ids.c              |  3 ++
> >  kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
> >  4 files changed, 78 insertions(+), 1 deletion(-)
> >  create mode 100644 kernel/bpf/btf_ids.c
> >  create mode 100644 kernel/bpf/btf_ids.h
> >
> 
> [...]
> 
> > +/*
> > + * Following macros help to define lists of BTF IDs placed
> > + * in .BTF_ids section. They are initially filled with zeros
> > + * (during compilation) and resolved later during the
> > + * linking phase by btfid tool.
> > + *
> > + * Any change in list layout must be reflected in btfid
> > + * tool logic.
> > + */
> > +
> > +#define SECTION ".BTF_ids"
> 
> nit: SECTION is super generic and non-greppable. BTF_IDS_SECTION?

ok

> 
> > +
> > +#define ____BTF_ID(symbol)                             \
> > +asm(                                                   \
> > +".pushsection " SECTION ",\"a\";               \n"     \
> 
> section should be also read-only? Either immediately here, of btfid
> tool should mark it? Unless I missed that it's already doing it :)

hm, it's there next to the .BTF section within RO_DATA macro,
so I thought that was enough.. I'll double check

> 
> > +".local " #symbol " ;                          \n"     \
> > +".type  " #symbol ", @object;                  \n"     \
> > +".size  " #symbol ", 4;                        \n"     \
> > +#symbol ":                                     \n"     \
> > +".zero 4                                       \n"     \
> > +".popsection;                                  \n");
> > +
> > +#define __BTF_ID(...) \
> > +       ____BTF_ID(__VA_ARGS__)
> 
> why varargs, if it's always a single argument? Or it's one of those
> macro black magic things were it works only in this particular case,
> but not others?

yea, I kind of struggled in here, because any other would not
expand the name concat together with the unique ID bit,
__VA_ARGS__ did it nicely ;-) I'll revisit this

thanks,
jirka
Jiri Olsa June 19, 2020, 1:16 p.m. UTC | #6
On Thu, Jun 18, 2020 at 06:06:49PM -0700, Andrii Nakryiko wrote:

SNIP

> > > +/*
> > > + * The BTF_ID_LIST macro defines pure (unsorted) list
> > > + * of BTF IDs, with following layout:
> > > + *
> > > + * BTF_ID_LIST(list1)
> > > + * BTF_ID(type1, name1)
> > > + * BTF_ID(type2, name2)
> > > + *
> > > + * list1:
> > > + * __BTF_ID__type1__name1__1:
> > > + * .zero 4
> > > + * __BTF_ID__type2__name2__2:
> > > + * .zero 4
> > > + *
> > > + */
> > > +#define BTF_ID_LIST(name)                              \
> >
> > nit: btw, you call it a list here, but btfids tool talks about
> > "sorts". Maybe stick to consistent naming. Either "list" or "set"
> > seems to be appropriate. Set implies a sorted aspect a bit more, IMO.

so how about we keep BTF_ID_LIST as it is and rename
BTF_WHITELIST_* to BTF_SET_*

> >
> > > +asm(                                                   \
> > > +".pushsection " SECTION ",\"a\";               \n"     \
> > > +".global " #name ";                            \n"     \
> >
> > I was expecting to see reserved 4 bytes for list size? I also couldn't
> > find where btfids tool prepends it. From what I could understand, it
> > just assumed the first 4 bytes are the length prefix? Sorry if I'm
> > slow...
> 
> Never mind, this is different from whitelisting you do in patch #8.
> But now I'm curious how this list symbol gets its size correctly
> calculated?..

so the BTF_ID_LIST list does not care about the size,
each symbol in the 'list' gets resolved based on its
__BTF_ID__XX__symbol__XX symbol

the count is kept in BTF_WHITELIST_* list because we
need it to sort it and search in it

thanks,
jirka
Andrii Nakryiko June 19, 2020, 6:15 p.m. UTC | #7
On Fri, Jun 19, 2020 at 6:13 AM Jiri Olsa <jolsa@redhat.com> wrote:
>
> On Thu, Jun 18, 2020 at 05:56:38PM -0700, Andrii Nakryiko wrote:
> > On Tue, Jun 16, 2020 at 3:05 AM Jiri Olsa <jolsa@kernel.org> wrote:
> > >
> > > Adding support to generate .BTF_ids section that would
> > > hold various BTF IDs list for verifier.
> > >
> > > Adding macros help to define lists of BTF IDs placed in
> > > .BTF_ids section. They are initially filled with zeros
> > > (during compilation) and resolved later during the
> > > linking phase by btfid tool.
> > >
> > > Following defines list of one BTF ID that is accessible
> > > within kernel code as bpf_skb_output_btf_ids array.
> > >
> > >   extern int bpf_skb_output_btf_ids[];
> > >
> > >   BTF_ID_LIST(bpf_skb_output_btf_ids)
> > >   BTF_ID(struct, sk_buff)
> > >
> > > Suggested-by: Andrii Nakryiko <andrii.nakryiko@gmail.com>
> > > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > > ---
> > >  include/asm-generic/vmlinux.lds.h |  4 ++
> > >  kernel/bpf/Makefile               |  2 +-
> > >  kernel/bpf/btf_ids.c              |  3 ++
> > >  kernel/bpf/btf_ids.h              | 70 +++++++++++++++++++++++++++++++
> > >  4 files changed, 78 insertions(+), 1 deletion(-)
> > >  create mode 100644 kernel/bpf/btf_ids.c
> > >  create mode 100644 kernel/bpf/btf_ids.h
> > >
> >
> > [...]
> >
> > > +/*
> > > + * Following macros help to define lists of BTF IDs placed
> > > + * in .BTF_ids section. They are initially filled with zeros
> > > + * (during compilation) and resolved later during the
> > > + * linking phase by btfid tool.
> > > + *
> > > + * Any change in list layout must be reflected in btfid
> > > + * tool logic.
> > > + */
> > > +
> > > +#define SECTION ".BTF_ids"
> >
> > nit: SECTION is super generic and non-greppable. BTF_IDS_SECTION?
>
> ok
>
> >
> > > +
> > > +#define ____BTF_ID(symbol)                             \
> > > +asm(                                                   \
> > > +".pushsection " SECTION ",\"a\";               \n"     \
> >
> > section should be also read-only? Either immediately here, of btfid
> > tool should mark it? Unless I missed that it's already doing it :)
>
> hm, it's there next to the .BTF section within RO_DATA macro,
> so I thought that was enough.. I'll double check

ah, linker script magic, got it

>
> >
> > > +".local " #symbol " ;                          \n"     \
> > > +".type  " #symbol ", @object;                  \n"     \
> > > +".size  " #symbol ", 4;                        \n"     \
> > > +#symbol ":                                     \n"     \
> > > +".zero 4                                       \n"     \
> > > +".popsection;                                  \n");
> > > +
> > > +#define __BTF_ID(...) \
> > > +       ____BTF_ID(__VA_ARGS__)
> >
> > why varargs, if it's always a single argument? Or it's one of those
> > macro black magic things were it works only in this particular case,
> > but not others?
>
> yea, I kind of struggled in here, because any other would not
> expand the name concat together with the unique ID bit,
> __VA_ARGS__ did it nicely ;-) I'll revisit this

it's probably not varargs, but rather nested macro call. Macros are
weird and tricky...

>
> thanks,
> jirka
>
diff mbox series

Patch

diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index db600ef218d7..0be2ee265931 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -641,6 +641,10 @@ 
 		__start_BTF = .;					\
 		*(.BTF)							\
 		__stop_BTF = .;						\
+	}								\
+	. = ALIGN(4);							\
+	.BTF_ids : AT(ADDR(.BTF_ids) - LOAD_OFFSET) {			\
+		*(.BTF_ids)						\
 	}
 #else
 #define BTF
diff --git a/kernel/bpf/Makefile b/kernel/bpf/Makefile
index 1131a921e1a6..21e4fc7c25ab 100644
--- a/kernel/bpf/Makefile
+++ b/kernel/bpf/Makefile
@@ -7,7 +7,7 @@  obj-$(CONFIG_BPF_SYSCALL) += hashtab.o arraymap.o percpu_freelist.o bpf_lru_list
 obj-$(CONFIG_BPF_SYSCALL) += local_storage.o queue_stack_maps.o ringbuf.o
 obj-$(CONFIG_BPF_SYSCALL) += disasm.o
 obj-$(CONFIG_BPF_JIT) += trampoline.o
-obj-$(CONFIG_BPF_SYSCALL) += btf.o
+obj-$(CONFIG_BPF_SYSCALL) += btf.o btf_ids.o
 obj-$(CONFIG_BPF_JIT) += dispatcher.o
 ifeq ($(CONFIG_NET),y)
 obj-$(CONFIG_BPF_SYSCALL) += devmap.o
diff --git a/kernel/bpf/btf_ids.c b/kernel/bpf/btf_ids.c
new file mode 100644
index 000000000000..e7f9d94ad293
--- /dev/null
+++ b/kernel/bpf/btf_ids.c
@@ -0,0 +1,3 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include "btf_ids.h"
diff --git a/kernel/bpf/btf_ids.h b/kernel/bpf/btf_ids.h
new file mode 100644
index 000000000000..68aa5c38a37f
--- /dev/null
+++ b/kernel/bpf/btf_ids.h
@@ -0,0 +1,70 @@ 
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __BTF_IDS_H__
+#define __BTF_IDS_H__
+
+#include <linux/stringify.h>
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+
+
+/*
+ * Following macros help to define lists of BTF IDs placed
+ * in .BTF_ids section. They are initially filled with zeros
+ * (during compilation) and resolved later during the
+ * linking phase by btfid tool.
+ *
+ * Any change in list layout must be reflected in btfid
+ * tool logic.
+ */
+
+#define SECTION ".BTF_ids"
+
+#define ____BTF_ID(symbol)				\
+asm(							\
+".pushsection " SECTION ",\"a\";               \n"	\
+".local " #symbol " ;                          \n"	\
+".type  " #symbol ", @object;                  \n"	\
+".size  " #symbol ", 4;                        \n"	\
+#symbol ":                                     \n"	\
+".zero 4                                       \n"	\
+".popsection;                                  \n");
+
+#define __BTF_ID(...) \
+	____BTF_ID(__VA_ARGS__)
+
+#define __ID(prefix) \
+	__PASTE(prefix, __COUNTER__)
+
+
+/*
+ * The BTF_ID defines unique symbol for each ID pointing
+ * to 4 zero bytes.
+ */
+#define BTF_ID(prefix, name) \
+	__BTF_ID(__ID(__BTF_ID__##prefix##__##name##__))
+
+
+/*
+ * The BTF_ID_LIST macro defines pure (unsorted) list
+ * of BTF IDs, with following layout:
+ *
+ * BTF_ID_LIST(list1)
+ * BTF_ID(type1, name1)
+ * BTF_ID(type2, name2)
+ *
+ * list1:
+ * __BTF_ID__type1__name1__1:
+ * .zero 4
+ * __BTF_ID__type2__name2__2:
+ * .zero 4
+ *
+ */
+#define BTF_ID_LIST(name)				\
+asm(							\
+".pushsection " SECTION ",\"a\";               \n"	\
+".global " #name ";                            \n"	\
+#name ":;                                      \n"	\
+".popsection;                                  \n");
+
+#endif