Acked-by: Hao Luo <haoluo@xxxxxxxxxx>, with a suggestion on adding a comment. On Fri, Jan 8, 2021 at 2:09 PM Andrii Nakryiko <andrii@xxxxxxxxxx> wrote: > > Add support for directly accessing kernel module variables from BPF programs > using special ldimm64 instructions. This functionality builds upon vmlinux > ksym support, but extends ldimm64 with src_reg=BPF_PSEUDO_BTF_ID to allow > specifying kernel module BTF's FD in insn[1].imm field. > > During BPF program load time, verifier will resolve FD to BTF object and will > take reference on BTF object itself and, for module BTFs, corresponding module > as well, to make sure it won't be unloaded from under running BPF program. The > mechanism used is similar to how bpf_prog keeps track of used bpf_maps. > > One interesting change is also in how per-CPU variable is determined. The > logic is to find .data..percpu data section in provided BTF, but both vmlinux > and module each have their own .data..percpu entries in BTF. So for module's > case, the search for DATASEC record needs to look at only module's added BTF > types. This is implemented with custom search function. > > Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx> > --- > include/linux/bpf.h | 10 +++ > include/linux/bpf_verifier.h | 3 + > include/linux/btf.h | 3 + > kernel/bpf/btf.c | 31 +++++++- > kernel/bpf/core.c | 23 ++++++ > kernel/bpf/verifier.c | 149 ++++++++++++++++++++++++++++------- > 6 files changed, 189 insertions(+), 30 deletions(-) [...] > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 17270b8404f1..af94c6871ab8 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -9703,6 +9703,31 @@ static int do_check(struct bpf_verifier_env *env) > return 0; > } > > +static int find_btf_percpu_datasec(struct btf *btf) > +{ > + const struct btf_type *t; > + const char *tname; > + int i, n; > + It would be good to add a short comment here explaining the reason why the search for DATASEC in the module case needs to skip entries. > + n = btf_nr_types(btf); > + if (btf_is_module(btf)) > + i = btf_nr_types(btf_vmlinux); > + else > + i = 1; > + > + for(; i < n; i++) { > + t = btf_type_by_id(btf, i); > + if (BTF_INFO_KIND(t->info) != BTF_KIND_DATASEC) > + continue; > + > + tname = btf_name_by_offset(btf, t->name_off); > + if (!strcmp(tname, ".data..percpu")) > + return i; > + } > + > + return -ENOENT; > +} [...] > 2.24.1 >