Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'Integrate kernel module BTF support'

Andrii Nakryiko says:

====================

This patch set adds BTF generation for kernel modules using a compact split
BTF approach. Respective patches have all the details.

Kernel module BTFs rely on pahole's split BTF support, which is added in [0]
and will be available starting from v1.19. Support for it is detected
automatically during kernel build time.

This patch set implements in-kernel support for split BTF loading and
validation. It also extends GET_OBJ_INFO API for BTFs to return BTF's module
name and a flag whether BTF itself is in-kernel or user-provided. vmlinux BTF
is also exposed to user-space through the same BTF object iteration APIs.

Follow up patch set will utilize the fact that vmlinux and module BTFs now
have associated ID to provide ability to attach BPF fentry/fexit/etc programs
to functions defined in kernel modules.

bpftool is also extended to show module/vmlinux BTF's name.

[0] https://patchwork.kernel.org/project/netdevbpf/list/?series=378699&state=*

v3->v4:
- copy_to_user() on ENOSPC in btf_get_info_by_fd() (Martin);
v2->v3:
- get rid of unnecessary gotos (Song);
v2->v1:
- drop WARNs, add fewer pr_warn()'s instead (Greg);
- properly initialize sysfs binary attribute structure (Greg);
- add __maybe_unused to any_section_objs, used conditionally by module BTF;
rfc->v1:
- CONFIG_DEBUG_INFO_BTF_MODULES is derived automatically (Alexei);
- vmlinux BTF now has explicit "vmlinux" name (Alexei);
- added sysfs ABI documentation for /sys/kernel/btf/<module> (Greg).

Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>

+459 -58
+8
Documentation/ABI/testing/sysfs-kernel-btf
··· 15 15 information with description of all internal kernel types. See 16 16 Documentation/bpf/btf.rst for detailed description of format 17 17 itself. 18 + 19 + What: /sys/kernel/btf/<module-name> 20 + Date: Nov 2020 21 + KernelVersion: 5.11 22 + Contact: bpf@vger.kernel.org 23 + Description: 24 + Read-only binary attribute exposing kernel module's BTF type 25 + information as an add-on to the kernel's BTF (/sys/kernel/btf/vmlinux).
+2
include/linux/bpf.h
··· 36 36 struct bpf_iter_aux_info; 37 37 struct bpf_local_storage; 38 38 struct bpf_local_storage_map; 39 + struct kobject; 39 40 40 41 extern struct idr btf_idr; 41 42 extern spinlock_t btf_idr_lock; 43 + extern struct kobject *btf_kobj; 42 44 43 45 typedef int (*bpf_iter_init_seq_priv_t)(void *private_data, 44 46 struct bpf_iter_aux_info *aux);
+4
include/linux/module.h
··· 475 475 unsigned int num_bpf_raw_events; 476 476 struct bpf_raw_event_map *bpf_raw_events; 477 477 #endif 478 + #ifdef CONFIG_DEBUG_INFO_BTF_MODULES 479 + unsigned int btf_data_size; 480 + void *btf_data; 481 + #endif 478 482 #ifdef CONFIG_JUMP_LABEL 479 483 struct jump_entry *jump_entries; 480 484 unsigned int num_jump_entries;
+3
include/uapi/linux/bpf.h
··· 4466 4466 __aligned_u64 btf; 4467 4467 __u32 btf_size; 4468 4468 __u32 id; 4469 + __aligned_u64 name; 4470 + __u32 name_len; 4471 + __u32 kernel_btf; 4469 4472 } __attribute__((aligned(8))); 4470 4473 4471 4474 struct bpf_link_info {
+352 -54
kernel/bpf/btf.c
··· 22 22 #include <linux/skmsg.h> 23 23 #include <linux/perf_event.h> 24 24 #include <linux/bsearch.h> 25 + #include <linux/kobject.h> 26 + #include <linux/sysfs.h> 25 27 #include <net/sock.h> 26 28 27 29 /* BTF (BPF Type Format) is the meta data format which describes ··· 205 203 const char *strings; 206 204 void *nohdr_data; 207 205 struct btf_header hdr; 208 - u32 nr_types; 206 + u32 nr_types; /* includes VOID for base BTF */ 209 207 u32 types_size; 210 208 u32 data_size; 211 209 refcount_t refcnt; 212 210 u32 id; 213 211 struct rcu_head rcu; 212 + 213 + /* split BTF support */ 214 + struct btf *base_btf; 215 + u32 start_id; /* first type ID in this BTF (0 for base BTF) */ 216 + u32 start_str_off; /* first string offset (0 for base BTF) */ 217 + char name[MODULE_NAME_LEN]; 218 + bool kernel_btf; 214 219 }; 215 220 216 221 enum verifier_phase { ··· 458 449 return BTF_INFO_KIND(t->info) == BTF_KIND_DATASEC; 459 450 } 460 451 452 + static u32 btf_nr_types_total(const struct btf *btf) 453 + { 454 + u32 total = 0; 455 + 456 + while (btf) { 457 + total += btf->nr_types; 458 + btf = btf->base_btf; 459 + } 460 + 461 + return total; 462 + } 463 + 461 464 s32 btf_find_by_name_kind(const struct btf *btf, const char *name, u8 kind) 462 465 { 463 466 const struct btf_type *t; 464 467 const char *tname; 465 - u32 i; 468 + u32 i, total; 466 469 467 - for (i = 1; i <= btf->nr_types; i++) { 468 - t = btf->types[i]; 470 + total = btf_nr_types_total(btf); 471 + for (i = 1; i < total; i++) { 472 + t = btf_type_by_id(btf, i); 469 473 if (BTF_INFO_KIND(t->info) != kind) 470 474 continue; 471 475 ··· 621 599 622 600 static bool btf_name_offset_valid(const struct btf *btf, u32 offset) 623 601 { 624 - return BTF_STR_OFFSET_VALID(offset) && 625 - offset < btf->hdr.str_len; 602 + if (!BTF_STR_OFFSET_VALID(offset)) 603 + return false; 604 + 605 + while (offset < btf->start_str_off) 606 + btf = btf->base_btf; 607 + 608 + offset -= btf->start_str_off; 609 + return offset < btf->hdr.str_len; 626 610 } 627 611 628 612 static bool __btf_name_char_ok(char c, bool first, bool dot_ok) ··· 642 614 return true; 643 615 } 644 616 617 + static const char *btf_str_by_offset(const struct btf *btf, u32 offset) 618 + { 619 + while (offset < btf->start_str_off) 620 + btf = btf->base_btf; 621 + 622 + offset -= btf->start_str_off; 623 + if (offset < btf->hdr.str_len) 624 + return &btf->strings[offset]; 625 + 626 + return NULL; 627 + } 628 + 645 629 static bool __btf_name_valid(const struct btf *btf, u32 offset, bool dot_ok) 646 630 { 647 631 /* offset must be valid */ 648 - const char *src = &btf->strings[offset]; 632 + const char *src = btf_str_by_offset(btf, offset); 649 633 const char *src_limit; 650 634 651 635 if (!__btf_name_char_ok(*src, true, dot_ok)) ··· 690 650 691 651 static const char *__btf_name_by_offset(const struct btf *btf, u32 offset) 692 652 { 653 + const char *name; 654 + 693 655 if (!offset) 694 656 return "(anon)"; 695 - else if (offset < btf->hdr.str_len) 696 - return &btf->strings[offset]; 697 - else 698 - return "(invalid-name-offset)"; 657 + 658 + name = btf_str_by_offset(btf, offset); 659 + return name ?: "(invalid-name-offset)"; 699 660 } 700 661 701 662 const char *btf_name_by_offset(const struct btf *btf, u32 offset) 702 663 { 703 - if (offset < btf->hdr.str_len) 704 - return &btf->strings[offset]; 705 - 706 - return NULL; 664 + return btf_str_by_offset(btf, offset); 707 665 } 708 666 709 667 const struct btf_type *btf_type_by_id(const struct btf *btf, u32 type_id) 710 668 { 711 - if (type_id > btf->nr_types) 712 - return NULL; 669 + while (type_id < btf->start_id) 670 + btf = btf->base_btf; 713 671 672 + type_id -= btf->start_id; 673 + if (type_id >= btf->nr_types) 674 + return NULL; 714 675 return btf->types[type_id]; 715 676 } 716 677 ··· 1431 1390 { 1432 1391 struct btf *btf = env->btf; 1433 1392 1434 - /* < 2 because +1 for btf_void which is always in btf->types[0]. 1435 - * btf_void is not accounted in btf->nr_types because btf_void 1436 - * does not come from the BTF file. 1437 - */ 1438 - if (btf->types_size - btf->nr_types < 2) { 1393 + if (btf->types_size == btf->nr_types) { 1439 1394 /* Expand 'types' array */ 1440 1395 1441 1396 struct btf_type **new_types; 1442 1397 u32 expand_by, new_size; 1443 1398 1444 - if (btf->types_size == BTF_MAX_TYPE) { 1399 + if (btf->start_id + btf->types_size == BTF_MAX_TYPE) { 1445 1400 btf_verifier_log(env, "Exceeded max num of types"); 1446 1401 return -E2BIG; 1447 1402 } ··· 1451 1414 if (!new_types) 1452 1415 return -ENOMEM; 1453 1416 1454 - if (btf->nr_types == 0) 1455 - new_types[0] = &btf_void; 1456 - else 1417 + if (btf->nr_types == 0) { 1418 + if (!btf->base_btf) { 1419 + /* lazily init VOID type */ 1420 + new_types[0] = &btf_void; 1421 + btf->nr_types++; 1422 + } 1423 + } else { 1457 1424 memcpy(new_types, btf->types, 1458 - sizeof(*btf->types) * (btf->nr_types + 1)); 1425 + sizeof(*btf->types) * btf->nr_types); 1426 + } 1459 1427 1460 1428 kvfree(btf->types); 1461 1429 btf->types = new_types; 1462 1430 btf->types_size = new_size; 1463 1431 } 1464 1432 1465 - btf->types[++(btf->nr_types)] = t; 1433 + btf->types[btf->nr_types++] = t; 1466 1434 1467 1435 return 0; 1468 1436 } ··· 1540 1498 u32 *resolved_ids = NULL; 1541 1499 u8 *visit_states = NULL; 1542 1500 1543 - /* +1 for btf_void */ 1544 - resolved_sizes = kvcalloc(nr_types + 1, sizeof(*resolved_sizes), 1501 + resolved_sizes = kvcalloc(nr_types, sizeof(*resolved_sizes), 1545 1502 GFP_KERNEL | __GFP_NOWARN); 1546 1503 if (!resolved_sizes) 1547 1504 goto nomem; 1548 1505 1549 - resolved_ids = kvcalloc(nr_types + 1, sizeof(*resolved_ids), 1506 + resolved_ids = kvcalloc(nr_types, sizeof(*resolved_ids), 1550 1507 GFP_KERNEL | __GFP_NOWARN); 1551 1508 if (!resolved_ids) 1552 1509 goto nomem; 1553 1510 1554 - visit_states = kvcalloc(nr_types + 1, sizeof(*visit_states), 1511 + visit_states = kvcalloc(nr_types, sizeof(*visit_states), 1555 1512 GFP_KERNEL | __GFP_NOWARN); 1556 1513 if (!visit_states) 1557 1514 goto nomem; ··· 1602 1561 static bool env_type_is_resolved(const struct btf_verifier_env *env, 1603 1562 u32 type_id) 1604 1563 { 1605 - return env->visit_states[type_id] == RESOLVED; 1564 + /* base BTF types should be resolved by now */ 1565 + if (type_id < env->btf->start_id) 1566 + return true; 1567 + 1568 + return env->visit_states[type_id - env->btf->start_id] == RESOLVED; 1606 1569 } 1607 1570 1608 1571 static int env_stack_push(struct btf_verifier_env *env, 1609 1572 const struct btf_type *t, u32 type_id) 1610 1573 { 1574 + const struct btf *btf = env->btf; 1611 1575 struct resolve_vertex *v; 1612 1576 1613 1577 if (env->top_stack == MAX_RESOLVE_DEPTH) 1614 1578 return -E2BIG; 1615 1579 1616 - if (env->visit_states[type_id] != NOT_VISITED) 1580 + if (type_id < btf->start_id 1581 + || env->visit_states[type_id - btf->start_id] != NOT_VISITED) 1617 1582 return -EEXIST; 1618 1583 1619 - env->visit_states[type_id] = VISITED; 1584 + env->visit_states[type_id - btf->start_id] = VISITED; 1620 1585 1621 1586 v = &env->stack[env->top_stack++]; 1622 1587 v->t = t; ··· 1652 1605 u32 type_id = env->stack[--(env->top_stack)].type_id; 1653 1606 struct btf *btf = env->btf; 1654 1607 1608 + type_id -= btf->start_id; /* adjust to local type id */ 1655 1609 btf->resolved_sizes[type_id] = resolved_size; 1656 1610 btf->resolved_ids[type_id] = resolved_type_id; 1657 1611 env->visit_states[type_id] = RESOLVED; ··· 1757 1709 return __btf_resolve_size(btf, type, type_size, NULL, NULL, NULL, NULL); 1758 1710 } 1759 1711 1712 + static u32 btf_resolved_type_id(const struct btf *btf, u32 type_id) 1713 + { 1714 + while (type_id < btf->start_id) 1715 + btf = btf->base_btf; 1716 + 1717 + return btf->resolved_ids[type_id - btf->start_id]; 1718 + } 1719 + 1760 1720 /* The input param "type_id" must point to a needs_resolve type */ 1761 1721 static const struct btf_type *btf_type_id_resolve(const struct btf *btf, 1762 1722 u32 *type_id) 1763 1723 { 1764 - *type_id = btf->resolved_ids[*type_id]; 1724 + *type_id = btf_resolved_type_id(btf, *type_id); 1765 1725 return btf_type_by_id(btf, *type_id); 1726 + } 1727 + 1728 + static u32 btf_resolved_type_size(const struct btf *btf, u32 type_id) 1729 + { 1730 + while (type_id < btf->start_id) 1731 + btf = btf->base_btf; 1732 + 1733 + return btf->resolved_sizes[type_id - btf->start_id]; 1766 1734 } 1767 1735 1768 1736 const struct btf_type *btf_type_id_size(const struct btf *btf, ··· 1795 1731 if (btf_type_has_size(size_type)) { 1796 1732 size = size_type->size; 1797 1733 } else if (btf_type_is_array(size_type)) { 1798 - size = btf->resolved_sizes[size_type_id]; 1734 + size = btf_resolved_type_size(btf, size_type_id); 1799 1735 } else if (btf_type_is_ptr(size_type)) { 1800 1736 size = sizeof(void *); 1801 1737 } else { ··· 1803 1739 !btf_type_is_var(size_type))) 1804 1740 return NULL; 1805 1741 1806 - size_type_id = btf->resolved_ids[size_type_id]; 1742 + size_type_id = btf_resolved_type_id(btf, size_type_id); 1807 1743 size_type = btf_type_by_id(btf, size_type_id); 1808 1744 if (btf_type_nosize_or_null(size_type)) 1809 1745 return NULL; 1810 1746 else if (btf_type_has_size(size_type)) 1811 1747 size = size_type->size; 1812 1748 else if (btf_type_is_array(size_type)) 1813 - size = btf->resolved_sizes[size_type_id]; 1749 + size = btf_resolved_type_size(btf, size_type_id); 1814 1750 else if (btf_type_is_ptr(size_type)) 1815 1751 size = sizeof(void *); 1816 1752 else ··· 3862 3798 cur = btf->nohdr_data + hdr->type_off; 3863 3799 end = cur + hdr->type_len; 3864 3800 3865 - env->log_type_id = 1; 3801 + env->log_type_id = btf->base_btf ? btf->start_id : 1; 3866 3802 while (cur < end) { 3867 3803 struct btf_type *t = cur; 3868 3804 s32 meta_size; ··· 3889 3825 return false; 3890 3826 3891 3827 if (btf_type_is_struct(t) || btf_type_is_datasec(t)) 3892 - return !btf->resolved_ids[type_id] && 3893 - !btf->resolved_sizes[type_id]; 3828 + return !btf_resolved_type_id(btf, type_id) && 3829 + !btf_resolved_type_size(btf, type_id); 3894 3830 3895 3831 if (btf_type_is_modifier(t) || btf_type_is_ptr(t) || 3896 3832 btf_type_is_var(t)) { ··· 3910 3846 elem_type = btf_type_id_size(btf, &elem_type_id, &elem_size); 3911 3847 return elem_type && !btf_type_is_modifier(elem_type) && 3912 3848 (array->nelems * elem_size == 3913 - btf->resolved_sizes[type_id]); 3849 + btf_resolved_type_size(btf, type_id)); 3914 3850 } 3915 3851 3916 3852 return false; ··· 3952 3888 static int btf_check_all_types(struct btf_verifier_env *env) 3953 3889 { 3954 3890 struct btf *btf = env->btf; 3955 - u32 type_id; 3891 + const struct btf_type *t; 3892 + u32 type_id, i; 3956 3893 int err; 3957 3894 3958 3895 err = env_resolve_init(env); ··· 3961 3896 return err; 3962 3897 3963 3898 env->phase++; 3964 - for (type_id = 1; type_id <= btf->nr_types; type_id++) { 3965 - const struct btf_type *t = btf_type_by_id(btf, type_id); 3899 + for (i = btf->base_btf ? 0 : 1; i < btf->nr_types; i++) { 3900 + type_id = btf->start_id + i; 3901 + t = btf_type_by_id(btf, type_id); 3966 3902 3967 3903 env->log_type_id = type_id; 3968 3904 if (btf_type_needs_resolve(t) && ··· 4000 3934 return -EINVAL; 4001 3935 } 4002 3936 4003 - if (!hdr->type_len) { 3937 + if (!env->btf->base_btf && !hdr->type_len) { 4004 3938 btf_verifier_log(env, "No type found"); 4005 3939 return -EINVAL; 4006 3940 } ··· 4027 3961 return -EINVAL; 4028 3962 } 4029 3963 4030 - if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET || 4031 - start[0] || end[-1]) { 3964 + btf->strings = start; 3965 + 3966 + if (btf->base_btf && !hdr->str_len) 3967 + return 0; 3968 + if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET || end[-1]) { 4032 3969 btf_verifier_log(env, "Invalid string section"); 4033 3970 return -EINVAL; 4034 3971 } 4035 - 4036 - btf->strings = start; 3972 + if (!btf->base_btf && start[0]) { 3973 + btf_verifier_log(env, "Invalid string section"); 3974 + return -EINVAL; 3975 + } 4037 3976 4038 3977 return 0; 4039 3978 } ··· 4433 4362 4434 4363 btf->data = __start_BTF; 4435 4364 btf->data_size = __stop_BTF - __start_BTF; 4365 + btf->kernel_btf = true; 4366 + snprintf(btf->name, sizeof(btf->name), "vmlinux"); 4436 4367 4437 4368 err = btf_parse_hdr(env); 4438 4369 if (err) ··· 4460 4387 4461 4388 bpf_struct_ops_init(btf, log); 4462 4389 4390 + refcount_set(&btf->refcnt, 1); 4391 + 4392 + err = btf_alloc_id(btf); 4393 + if (err) 4394 + goto errout; 4395 + 4396 + btf_verifier_env_free(env); 4397 + return btf; 4398 + 4399 + errout: 4400 + btf_verifier_env_free(env); 4401 + if (btf) { 4402 + kvfree(btf->types); 4403 + kfree(btf); 4404 + } 4405 + return ERR_PTR(err); 4406 + } 4407 + 4408 + static struct btf *btf_parse_module(const char *module_name, const void *data, unsigned int data_size) 4409 + { 4410 + struct btf_verifier_env *env = NULL; 4411 + struct bpf_verifier_log *log; 4412 + struct btf *btf = NULL, *base_btf; 4413 + int err; 4414 + 4415 + base_btf = bpf_get_btf_vmlinux(); 4416 + if (IS_ERR(base_btf)) 4417 + return base_btf; 4418 + if (!base_btf) 4419 + return ERR_PTR(-EINVAL); 4420 + 4421 + env = kzalloc(sizeof(*env), GFP_KERNEL | __GFP_NOWARN); 4422 + if (!env) 4423 + return ERR_PTR(-ENOMEM); 4424 + 4425 + log = &env->log; 4426 + log->level = BPF_LOG_KERNEL; 4427 + 4428 + btf = kzalloc(sizeof(*btf), GFP_KERNEL | __GFP_NOWARN); 4429 + if (!btf) { 4430 + err = -ENOMEM; 4431 + goto errout; 4432 + } 4433 + env->btf = btf; 4434 + 4435 + btf->base_btf = base_btf; 4436 + btf->start_id = base_btf->nr_types; 4437 + btf->start_str_off = base_btf->hdr.str_len; 4438 + btf->kernel_btf = true; 4439 + snprintf(btf->name, sizeof(btf->name), "%s", module_name); 4440 + 4441 + btf->data = kvmalloc(data_size, GFP_KERNEL | __GFP_NOWARN); 4442 + if (!btf->data) { 4443 + err = -ENOMEM; 4444 + goto errout; 4445 + } 4446 + memcpy(btf->data, data, data_size); 4447 + btf->data_size = data_size; 4448 + 4449 + err = btf_parse_hdr(env); 4450 + if (err) 4451 + goto errout; 4452 + 4453 + btf->nohdr_data = btf->data + btf->hdr.hdr_len; 4454 + 4455 + err = btf_parse_str_sec(env); 4456 + if (err) 4457 + goto errout; 4458 + 4459 + err = btf_check_all_metas(env); 4460 + if (err) 4461 + goto errout; 4462 + 4463 4463 btf_verifier_env_free(env); 4464 4464 refcount_set(&btf->refcnt, 1); 4465 4465 return btf; ··· 4540 4394 errout: 4541 4395 btf_verifier_env_free(env); 4542 4396 if (btf) { 4397 + kvfree(btf->data); 4543 4398 kvfree(btf->types); 4544 4399 kfree(btf); 4545 4400 } ··· 5055 4908 while (t && btf_type_is_modifier(t)) 5056 4909 t = btf_type_by_id(btf, t->type); 5057 4910 if (!t) { 5058 - *bad_type = btf->types[0]; 4911 + *bad_type = btf_type_by_id(btf, 0); 5059 4912 return -EINVAL; 5060 4913 } 5061 4914 if (btf_type_is_ptr(t)) ··· 5633 5486 struct bpf_btf_info info; 5634 5487 u32 info_copy, btf_copy; 5635 5488 void __user *ubtf; 5636 - u32 uinfo_len; 5489 + char __user *uname; 5490 + u32 uinfo_len, uname_len, name_len; 5491 + int ret = 0; 5637 5492 5638 5493 uinfo = u64_to_user_ptr(attr->info.info); 5639 5494 uinfo_len = attr->info.info_len; ··· 5652 5503 return -EFAULT; 5653 5504 info.btf_size = btf->data_size; 5654 5505 5506 + info.kernel_btf = btf->kernel_btf; 5507 + 5508 + uname = u64_to_user_ptr(info.name); 5509 + uname_len = info.name_len; 5510 + if (!uname ^ !uname_len) 5511 + return -EINVAL; 5512 + 5513 + name_len = strlen(btf->name); 5514 + info.name_len = name_len; 5515 + 5516 + if (uname) { 5517 + if (uname_len >= name_len + 1) { 5518 + if (copy_to_user(uname, btf->name, name_len + 1)) 5519 + return -EFAULT; 5520 + } else { 5521 + char zero = '\0'; 5522 + 5523 + if (copy_to_user(uname, btf->name, uname_len - 1)) 5524 + return -EFAULT; 5525 + if (put_user(zero, uname + uname_len - 1)) 5526 + return -EFAULT; 5527 + /* let user-space know about too short buffer */ 5528 + ret = -ENOSPC; 5529 + } 5530 + } 5531 + 5655 5532 if (copy_to_user(uinfo, &info, info_copy) || 5656 5533 put_user(info_copy, &uattr->info.info_len)) 5657 5534 return -EFAULT; 5658 5535 5659 - return 0; 5536 + return ret; 5660 5537 } 5661 5538 5662 5539 int btf_get_fd_by_id(u32 id) ··· 5722 5547 { 5723 5548 return bsearch(&id, set->ids, set->cnt, sizeof(u32), btf_id_cmp_func) != NULL; 5724 5549 } 5550 + 5551 + #ifdef CONFIG_DEBUG_INFO_BTF_MODULES 5552 + struct btf_module { 5553 + struct list_head list; 5554 + struct module *module; 5555 + struct btf *btf; 5556 + struct bin_attribute *sysfs_attr; 5557 + }; 5558 + 5559 + static LIST_HEAD(btf_modules); 5560 + static DEFINE_MUTEX(btf_module_mutex); 5561 + 5562 + static ssize_t 5563 + btf_module_read(struct file *file, struct kobject *kobj, 5564 + struct bin_attribute *bin_attr, 5565 + char *buf, loff_t off, size_t len) 5566 + { 5567 + const struct btf *btf = bin_attr->private; 5568 + 5569 + memcpy(buf, btf->data + off, len); 5570 + return len; 5571 + } 5572 + 5573 + static int btf_module_notify(struct notifier_block *nb, unsigned long op, 5574 + void *module) 5575 + { 5576 + struct btf_module *btf_mod, *tmp; 5577 + struct module *mod = module; 5578 + struct btf *btf; 5579 + int err = 0; 5580 + 5581 + if (mod->btf_data_size == 0 || 5582 + (op != MODULE_STATE_COMING && op != MODULE_STATE_GOING)) 5583 + goto out; 5584 + 5585 + switch (op) { 5586 + case MODULE_STATE_COMING: 5587 + btf_mod = kzalloc(sizeof(*btf_mod), GFP_KERNEL); 5588 + if (!btf_mod) { 5589 + err = -ENOMEM; 5590 + goto out; 5591 + } 5592 + btf = btf_parse_module(mod->name, mod->btf_data, mod->btf_data_size); 5593 + if (IS_ERR(btf)) { 5594 + pr_warn("failed to validate module [%s] BTF: %ld\n", 5595 + mod->name, PTR_ERR(btf)); 5596 + kfree(btf_mod); 5597 + err = PTR_ERR(btf); 5598 + goto out; 5599 + } 5600 + err = btf_alloc_id(btf); 5601 + if (err) { 5602 + btf_free(btf); 5603 + kfree(btf_mod); 5604 + goto out; 5605 + } 5606 + 5607 + mutex_lock(&btf_module_mutex); 5608 + btf_mod->module = module; 5609 + btf_mod->btf = btf; 5610 + list_add(&btf_mod->list, &btf_modules); 5611 + mutex_unlock(&btf_module_mutex); 5612 + 5613 + if (IS_ENABLED(CONFIG_SYSFS)) { 5614 + struct bin_attribute *attr; 5615 + 5616 + attr = kzalloc(sizeof(*attr), GFP_KERNEL); 5617 + if (!attr) 5618 + goto out; 5619 + 5620 + sysfs_bin_attr_init(attr); 5621 + attr->attr.name = btf->name; 5622 + attr->attr.mode = 0444; 5623 + attr->size = btf->data_size; 5624 + attr->private = btf; 5625 + attr->read = btf_module_read; 5626 + 5627 + err = sysfs_create_bin_file(btf_kobj, attr); 5628 + if (err) { 5629 + pr_warn("failed to register module [%s] BTF in sysfs: %d\n", 5630 + mod->name, err); 5631 + kfree(attr); 5632 + err = 0; 5633 + goto out; 5634 + } 5635 + 5636 + btf_mod->sysfs_attr = attr; 5637 + } 5638 + 5639 + break; 5640 + case MODULE_STATE_GOING: 5641 + mutex_lock(&btf_module_mutex); 5642 + list_for_each_entry_safe(btf_mod, tmp, &btf_modules, list) { 5643 + if (btf_mod->module != module) 5644 + continue; 5645 + 5646 + list_del(&btf_mod->list); 5647 + if (btf_mod->sysfs_attr) 5648 + sysfs_remove_bin_file(btf_kobj, btf_mod->sysfs_attr); 5649 + btf_put(btf_mod->btf); 5650 + kfree(btf_mod->sysfs_attr); 5651 + kfree(btf_mod); 5652 + break; 5653 + } 5654 + mutex_unlock(&btf_module_mutex); 5655 + break; 5656 + } 5657 + out: 5658 + return notifier_from_errno(err); 5659 + } 5660 + 5661 + static struct notifier_block btf_module_nb = { 5662 + .notifier_call = btf_module_notify, 5663 + }; 5664 + 5665 + static int __init btf_module_init(void) 5666 + { 5667 + register_module_notifier(&btf_module_nb); 5668 + return 0; 5669 + } 5670 + 5671 + fs_initcall(btf_module_init); 5672 + #endif /* CONFIG_DEBUG_INFO_BTF_MODULES */
+1 -1
kernel/bpf/sysfs_btf.c
··· 26 26 .read = btf_vmlinux_read, 27 27 }; 28 28 29 - static struct kobject *btf_kobj; 29 + struct kobject *btf_kobj; 30 30 31 31 static int __init btf_vmlinux_init(void) 32 32 {
+32
kernel/module.c
··· 380 380 return (void *)info->sechdrs[sec].sh_addr; 381 381 } 382 382 383 + /* Find a module section: 0 means not found. Ignores SHF_ALLOC flag. */ 384 + static unsigned int find_any_sec(const struct load_info *info, const char *name) 385 + { 386 + unsigned int i; 387 + 388 + for (i = 1; i < info->hdr->e_shnum; i++) { 389 + Elf_Shdr *shdr = &info->sechdrs[i]; 390 + if (strcmp(info->secstrings + shdr->sh_name, name) == 0) 391 + return i; 392 + } 393 + return 0; 394 + } 395 + 396 + /* 397 + * Find a module section, or NULL. Fill in number of "objects" in section. 398 + * Ignores SHF_ALLOC flag. 399 + */ 400 + static __maybe_unused void *any_section_objs(const struct load_info *info, 401 + const char *name, 402 + size_t object_size, 403 + unsigned int *num) 404 + { 405 + unsigned int sec = find_any_sec(info, name); 406 + 407 + /* Section 0 has sh_addr 0 and sh_size 0. */ 408 + *num = info->sechdrs[sec].sh_size / object_size; 409 + return (void *)info->sechdrs[sec].sh_addr; 410 + } 411 + 383 412 /* Provided by the linker */ 384 413 extern const struct kernel_symbol __start___ksymtab[]; 385 414 extern const struct kernel_symbol __stop___ksymtab[]; ··· 3278 3249 mod->bpf_raw_events = section_objs(info, "__bpf_raw_tp_map", 3279 3250 sizeof(*mod->bpf_raw_events), 3280 3251 &mod->num_bpf_raw_events); 3252 + #endif 3253 + #ifdef CONFIG_DEBUG_INFO_BTF_MODULES 3254 + mod->btf_data = any_section_objs(info, ".BTF", 1, &mod->btf_data_size); 3281 3255 #endif 3282 3256 #ifdef CONFIG_JUMP_LABEL 3283 3257 mod->jump_entries = section_objs(info, "__jump_table",
+9
lib/Kconfig.debug
··· 274 274 Turning this on expects presence of pahole tool, which will convert 275 275 DWARF type info into equivalent deduplicated BTF type info. 276 276 277 + config PAHOLE_HAS_SPLIT_BTF 278 + def_bool $(success, test `$(PAHOLE) --version | sed -E 's/v([0-9]+)\.([0-9]+)/\1\2/'` -ge "119") 279 + 280 + config DEBUG_INFO_BTF_MODULES 281 + def_bool y 282 + depends on DEBUG_INFO_BTF && MODULES && PAHOLE_HAS_SPLIT_BTF 283 + help 284 + Generate compact split BTF type information for kernel modules. 285 + 277 286 config GDB_SCRIPTS 278 287 bool "Provide GDB scripts for kernel debugging" 279 288 help
+18 -2
scripts/Makefile.modfinal
··· 6 6 PHONY := __modfinal 7 7 __modfinal: 8 8 9 + include include/config/auto.conf 9 10 include $(srctree)/scripts/Kbuild.include 10 11 11 12 # for c_flags ··· 37 36 -T scripts/module.lds -o $@ $(filter %.o, $^); \ 38 37 $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) 39 38 40 - $(modules): %.ko: %.o %.mod.o scripts/module.lds FORCE 41 - +$(call if_changed,ld_ko_o) 39 + quiet_cmd_btf_ko = BTF [M] $@ 40 + cmd_btf_ko = LLVM_OBJCOPY=$(OBJCOPY) $(PAHOLE) -J --btf_base vmlinux $@ 41 + 42 + # Same as newer-prereqs, but allows to exclude specified extra dependencies 43 + newer_prereqs_except = $(filter-out $(PHONY) $(1),$?) 44 + 45 + # Same as if_changed, but allows to exclude specified extra dependencies 46 + if_changed_except = $(if $(call newer_prereqs_except,$(2))$(cmd-check), \ 47 + $(cmd); \ 48 + printf '%s\n' 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd, @:) 49 + 50 + # Re-generate module BTFs if either module's .ko or vmlinux changed 51 + $(modules): %.ko: %.o %.mod.o scripts/module.lds vmlinux FORCE 52 + +$(call if_changed_except,ld_ko_o,vmlinux) 53 + ifdef CONFIG_DEBUG_INFO_BTF_MODULES 54 + +$(if $(newer-prereqs),$(call cmd,btf_ko)) 55 + endif 42 56 43 57 targets += $(modules) $(modules:.ko=.mod.o) 44 58
+27 -1
tools/bpf/bpftool/btf.c
··· 742 742 struct btf_attach_table *btf_map_table) 743 743 { 744 744 struct btf_attach_point *obj; 745 + const char *name = u64_to_ptr(info->name); 745 746 int n; 746 747 747 748 printf("%u: ", info->id); 749 + if (info->kernel_btf) 750 + printf("name [%s] ", name); 751 + else if (name && name[0]) 752 + printf("name %s ", name); 748 753 printf("size %uB", info->btf_size); 749 754 750 755 n = 0; ··· 776 771 struct btf_attach_table *btf_map_table) 777 772 { 778 773 struct btf_attach_point *obj; 774 + const char *name = u64_to_ptr(info->name); 779 775 780 776 jsonw_start_object(json_wtr); /* btf object */ 781 777 jsonw_uint_field(json_wtr, "id", info->id); ··· 802 796 803 797 emit_obj_refs_json(&refs_table, info->id, json_wtr); /* pids */ 804 798 799 + jsonw_bool_field(json_wtr, "kernel", info->kernel_btf); 800 + 801 + if (name && name[0]) 802 + jsonw_string_field(json_wtr, "name", name); 803 + 805 804 jsonw_end_object(json_wtr); /* btf object */ 806 805 } 807 806 ··· 814 803 show_btf(int fd, struct btf_attach_table *btf_prog_table, 815 804 struct btf_attach_table *btf_map_table) 816 805 { 817 - struct bpf_btf_info info = {}; 806 + struct bpf_btf_info info; 818 807 __u32 len = sizeof(info); 808 + char name[64]; 819 809 int err; 820 810 811 + memset(&info, 0, sizeof(info)); 821 812 err = bpf_obj_get_info_by_fd(fd, &info, &len); 822 813 if (err) { 823 814 p_err("can't get BTF object info: %s", strerror(errno)); 824 815 return -1; 816 + } 817 + /* if kernel support emitting BTF object name, pass name pointer */ 818 + if (info.name_len) { 819 + memset(&info, 0, sizeof(info)); 820 + info.name_len = sizeof(name); 821 + info.name = ptr_to_u64(name); 822 + len = sizeof(info); 823 + 824 + err = bpf_obj_get_info_by_fd(fd, &info, &len); 825 + if (err) { 826 + p_err("can't get BTF object info: %s", strerror(errno)); 827 + return -1; 828 + } 825 829 } 826 830 827 831 if (json_output)
+3
tools/include/uapi/linux/bpf.h
··· 4466 4466 __aligned_u64 btf; 4467 4467 __u32 btf_size; 4468 4468 __u32 id; 4469 + __aligned_u64 name; 4470 + __u32 name_len; 4471 + __u32 kernel_btf; 4469 4472 } __attribute__((aligned(8))); 4470 4473 4471 4474 struct bpf_link_info {