Re: [PATCH bpf-next v2 1/1] docs/bpf: Add description for CO-RE relocations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 2023-08-25 at 21:24 -0700, Yonghong Song wrote:
> 
> On 8/25/23 3:45 PM, Eduard Zingerman wrote:
> > Add a section on CO-RE relocations to llvm_relo.rst.
> > Describe relevant .BTF.ext structure, `enum bpf_core_relo_kind`
> > and `struct bpf_core_relo` in some detail.
> > Description is based on doc-strings from:
> > - include/uapi/linux/bpf.h:struct bpf_core_relo
> > - tools/lib/bpf/relo_core.c:__bpf_core_types_match()
> > 
> > Signed-off-by: Eduard Zingerman <eddyz87@xxxxxxxxx>
> 
> LGTM with a couple minor nits below.

Thank you, will fix these nits in the v3.

> 
> Acked-by: Yonghong Song <yonghong.song@xxxxxxxxx>
> 
> > ---
> >   Documentation/bpf/btf.rst        |  31 +++-
> >   Documentation/bpf/llvm_reloc.rst | 304 +++++++++++++++++++++++++++++++
> >   2 files changed, 329 insertions(+), 6 deletions(-)
> > 
> [...]
> > +.. code-block:: c
> > +
> > + enum bpf_core_relo_kind {
> > +	BPF_CORE_FIELD_BYTE_OFFSET = 0,  /* field byte offset */
> > +	BPF_CORE_FIELD_BYTE_SIZE   = 1,  /* field size in bytes */
> > +	BPF_CORE_FIELD_EXISTS      = 2,  /* field existence in target kernel */
> > +	BPF_CORE_FIELD_SIGNED      = 3,  /* field signedness (0 - unsigned, 1 - signed) */
> > +	BPF_CORE_FIELD_LSHIFT_U64  = 4,  /* bitfield-specific left bitshift */
> > +	BPF_CORE_FIELD_RSHIFT_U64  = 5,  /* bitfield-specific right bitshift */
> > +	BPF_CORE_TYPE_ID_LOCAL     = 6,  /* type ID in local BPF object */
> > +	BPF_CORE_TYPE_ID_TARGET    = 7,  /* type ID in target kernel */
> > +	BPF_CORE_TYPE_EXISTS       = 8,  /* type existence in target kernel */
> > +	BPF_CORE_TYPE_SIZE         = 9,  /* type size in bytes */
> > +	BPF_CORE_ENUMVAL_EXISTS    = 10, /* enum value existence in target kernel */
> > +	BPF_CORE_ENUMVAL_VALUE     = 11, /* enum value integer value */
> > +	BPF_CORE_TYPE_MATCHES      = 12, /* type match in target kernel */
> > + };
> > +
> > +Notes:
> > +
> > +* ``BPF_CORE_FIELD_LSHIFT_U64`` and ``BPF_CORE_FIELD_RSHIFT_U64`` are
> > +  supposed to be used to read bitfield values using the following
> > +  algorithm:
> > +
> > +  .. code-block:: c
> > +
> > +     // To read bitfield ``f`` from ``struct s``
> > +     is_signed = relo(s->f, BPF_CORE_FIELD_SIGNED)
> > +     off = relo(s->f, BPF_CORE_FIELD_BYTE_OFFSET)
> > +     sz  = relo(s->f, BPF_CORE_FIELD_BYTE_SIZE)
> > +     l   = relo(s->f, BPF_CORE_FIELD_LSHIFT_U64)
> > +     r   = relo(s->f, BPF_CORE_FIELD_RSHIFT_U64)
> > +     // define ``v`` as signed or unsigned integer of size ``sz``
> > +     v = *((void *)s) + off)
> 
> parenthesis not matching in the above.
> 
> How about below to a little bit more precise?
>    v = *({s|u}<sz> *)((void *)s + off)
> 
> > +     v <<= l
> > +     v >>= r
> > +
> [...]
> > +
> > +CO-RE Relocation Examples
> > +=========================
> > +
> > +For the following C code:
> > +
> > +.. code-block:: c
> > +
> > + struct foo {
> > +   int a;
> > +   int b;
> > +   unsigned c:15;
> > + } __attribute__((preserve_access_index));
> > +
> > + enum bar { U, V };
> > +
> > +With the following BTF definitions:
> > +
> > +.. code-block::
> > +
> > + ...
> > + [2] STRUCT 'foo' size=8 vlen=2
> > + 	'a' type_id=3 bits_offset=0
> > + 	'b' type_id=3 bits_offset=32
> > +        'c' type_id=4 bits_offset=64 bitfield_size=15
> 
> Misalignment in the above.
> 
> 
> > + [3] INT 'int' size=4 bits_offset=0 nr_bits=32 encoding=SIGNED
> > + [4] INT 'unsigned int' size=4 bits_offset=0 nr_bits=32 encoding=(none)
> > + ...
> > + [16] ENUM 'bar' encoding=UNSIGNED size=4 vlen=2
> > + 	'U' val=0
> > + 	'V' val=1
> > +
> > +Field offset relocations are generated automatically when
> > +``__attribute__((preserve_access_index))`` is used, for example:
> > +
> > +.. code-block:: c
> > +
> > +  void alpha(struct foo *s, volatile unsigned long *g) {
> > +    *g = s->a;
> > +    s->a = 1;
> > +  }
> > +
> > +  00 <alpha>:
> > +    0:  r3 = *(s32 *)(r1 + 0x0)
> > +           00:  CO-RE <byte_off> [2] struct foo::a (0:0)
> > +    1:  *(u64 *)(r2 + 0x0) = r3
> > +    2:  *(u32 *)(r1 + 0x0) = 0x1
> > +           10:  CO-RE <byte_off> [2] struct foo::a (0:0)
> > +    3:  exit
> > +
> > +
> > +All relocation kinds could be requested via built-in functions.
> > +E.g. field-based relocations:
> > +
> > +.. code-block:: c
> > +
> > +  void bravo(struct foo *s, volatile unsigned long *g) {
> > +    *g = __builtin_preserve_field_info(s->b, 0 /* field byte offset */);
> > +    *g = __builtin_preserve_field_info(s->b, 1 /* field byte size */);
> > +    *g = __builtin_preserve_field_info(s->b, 2 /* field existence */);
> > +    *g = __builtin_preserve_field_info(s->b, 3 /* field signedness */);
> > +    *g = __builtin_preserve_field_info(s->c, 4 /* bitfield left shift */);
> > +    *g = __builtin_preserve_field_info(s->c, 5 /* bitfield right shift */);
> > +  }
> > +
> > +  20 <bravo>:
> > +     4:     r1 = 0x4
> > +            20:  CO-RE <byte_off> [2] struct foo::b (0:1)
> > +     5:     *(u64 *)(r2 + 0x0) = r1
> > +     6:     r1 = 0x4
> > +            30:  CO-RE <byte_sz> [2] struct foo::b (0:1)
> > +     7:     *(u64 *)(r2 + 0x0) = r1
> > +     8:     r1 = 0x1
> > +            40:  CO-RE <field_exists> [2] struct foo::b (0:1)
> > +     9:     *(u64 *)(r2 + 0x0) = r1
> > +    10:     r1 = 0x1
> > +            50:  CO-RE <signed> [2] struct foo::b (0:1)
> > +    11:     *(u64 *)(r2 + 0x0) = r1
> > +    12:     r1 = 0x31
> > +            60:  CO-RE <lshift_u64> [2] struct foo::c (0:2)
> > +    13:     *(u64 *)(r2 + 0x0) = r1
> > +    14:     r1 = 0x31
> > +            70:  CO-RE <rshift_u64> [2] struct foo::c (0:2)
> > +    15:     *(u64 *)(r2 + 0x0) = r1
> > +    16:     exit
> > +
> > +
> [...]






[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux