diff options
Diffstat (limited to 'kernel/bpf/btf.c')
-rw-r--r-- | kernel/bpf/btf.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c index 93b6905e3a9b..e804b26a0506 100644 --- a/kernel/bpf/btf.c +++ b/kernel/bpf/btf.c | |||
@@ -546,22 +546,41 @@ static bool btf_type_int_is_regular(const struct btf_type *t) | |||
546 | } | 546 | } |
547 | 547 | ||
548 | /* | 548 | /* |
549 | * Check that given type is a regular int and has the expected size. | 549 | * Check that given struct member is a regular int with expected |
550 | * offset and size. | ||
550 | */ | 551 | */ |
551 | bool btf_type_is_reg_int(const struct btf_type *t, u32 expected_size) | 552 | bool btf_member_is_reg_int(const struct btf *btf, const struct btf_type *s, |
553 | const struct btf_member *m, | ||
554 | u32 expected_offset, u32 expected_size) | ||
552 | { | 555 | { |
553 | u8 nr_bits, nr_bytes; | 556 | const struct btf_type *t; |
554 | u32 int_data; | 557 | u32 id, int_data; |
558 | u8 nr_bits; | ||
555 | 559 | ||
556 | if (!btf_type_is_int(t)) | 560 | id = m->type; |
561 | t = btf_type_id_size(btf, &id, NULL); | ||
562 | if (!t || !btf_type_is_int(t)) | ||
557 | return false; | 563 | return false; |
558 | 564 | ||
559 | int_data = btf_type_int(t); | 565 | int_data = btf_type_int(t); |
560 | nr_bits = BTF_INT_BITS(int_data); | 566 | nr_bits = BTF_INT_BITS(int_data); |
561 | nr_bytes = BITS_ROUNDUP_BYTES(nr_bits); | 567 | if (btf_type_kflag(s)) { |
562 | if (BITS_PER_BYTE_MASKED(nr_bits) || | 568 | u32 bitfield_size = BTF_MEMBER_BITFIELD_SIZE(m->offset); |
563 | BTF_INT_OFFSET(int_data) || | 569 | u32 bit_offset = BTF_MEMBER_BIT_OFFSET(m->offset); |
564 | nr_bytes != expected_size) | 570 | |
571 | /* if kflag set, int should be a regular int and | ||
572 | * bit offset should be at byte boundary. | ||
573 | */ | ||
574 | return !bitfield_size && | ||
575 | BITS_ROUNDUP_BYTES(bit_offset) == expected_offset && | ||
576 | BITS_ROUNDUP_BYTES(nr_bits) == expected_size; | ||
577 | } | ||
578 | |||
579 | if (BTF_INT_OFFSET(int_data) || | ||
580 | BITS_PER_BYTE_MASKED(m->offset) || | ||
581 | BITS_ROUNDUP_BYTES(m->offset) != expected_offset || | ||
582 | BITS_PER_BYTE_MASKED(nr_bits) || | ||
583 | BITS_ROUNDUP_BYTES(nr_bits) != expected_size) | ||
565 | return false; | 584 | return false; |
566 | 585 | ||
567 | return true; | 586 | return true; |