aboutsummaryrefslogtreecommitdiffstats
path: root/samples
diff options
context:
space:
mode:
authorJesper Dangaard Brouer <brouer@redhat.com>2017-05-30 08:37:51 -0400
committerDavid S. Miller <davem@davemloft.net>2017-05-31 12:59:20 -0400
commit7bc57950bd41d40685ca45a4079ce74d5d41250b (patch)
treed49eeafaf1464ffbb0aa72c35c4c4dcf8fc87aec /samples
parent9831724a08f06f9560fcc3f1132cbd290e5f9149 (diff)
samples/bpf: bpf_load.c order of prog_fd[] should correspond with ELF order
An eBPF ELF file generated with LLVM can contain several program section, which can be used for bpf tail calls. The bpf prog file descriptors are accessible via array prog_fd[]. At-least XDP samples assume ordering, and uses prog_fd[0] is the main XDP program to attach. The actual order of array prog_fd[] depend on whether or not a bpf program section is referencing any maps or not. Not using a map result in being loaded/processed after all other prog section. Thus, this can lead to some very strange and hard to debug situation, as the user can only see a FD and cannot correlated that with the ELF section name. The fix is rather simple, and even removes duplicate memcmp code. Simply load program sections as the last step, instead of load_and_attach while processing the relocation section. When working with tail calls, it become even more essential that the order of prog_fd[] is consistant, like the current dependency of the map_fd[] order. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'samples')
-rw-r--r--samples/bpf/bpf_load.c19
1 files changed, 5 insertions, 14 deletions
diff --git a/samples/bpf/bpf_load.c b/samples/bpf/bpf_load.c
index 74456b3eb89a..a91c57dd8571 100644
--- a/samples/bpf/bpf_load.c
+++ b/samples/bpf/bpf_load.c
@@ -516,16 +516,18 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
516 processed_sec[maps_shndx] = true; 516 processed_sec[maps_shndx] = true;
517 } 517 }
518 518
519 /* load programs that need map fixup (relocations) */ 519 /* process all relo sections, and rewrite bpf insns for maps */
520 for (i = 1; i < ehdr.e_shnum; i++) { 520 for (i = 1; i < ehdr.e_shnum; i++) {
521 if (processed_sec[i]) 521 if (processed_sec[i])
522 continue; 522 continue;
523 523
524 if (get_sec(elf, i, &ehdr, &shname, &shdr, &data)) 524 if (get_sec(elf, i, &ehdr, &shname, &shdr, &data))
525 continue; 525 continue;
526
526 if (shdr.sh_type == SHT_REL) { 527 if (shdr.sh_type == SHT_REL) {
527 struct bpf_insn *insns; 528 struct bpf_insn *insns;
528 529
530 /* locate prog sec that need map fixup (relocations) */
529 if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog, 531 if (get_sec(elf, shdr.sh_info, &ehdr, &shname_prog,
530 &shdr_prog, &data_prog)) 532 &shdr_prog, &data_prog))
531 continue; 533 continue;
@@ -535,26 +537,15 @@ static int do_load_bpf_file(const char *path, fixup_map_cb fixup_map)
535 continue; 537 continue;
536 538
537 insns = (struct bpf_insn *) data_prog->d_buf; 539 insns = (struct bpf_insn *) data_prog->d_buf;
538 540 processed_sec[i] = true; /* relo section */
539 processed_sec[shdr.sh_info] = true;
540 processed_sec[i] = true;
541 541
542 if (parse_relo_and_apply(data, symbols, &shdr, insns, 542 if (parse_relo_and_apply(data, symbols, &shdr, insns,
543 map_data, nr_maps)) 543 map_data, nr_maps))
544 continue; 544 continue;
545
546 if (memcmp(shname_prog, "kprobe/", 7) == 0 ||
547 memcmp(shname_prog, "kretprobe/", 10) == 0 ||
548 memcmp(shname_prog, "tracepoint/", 11) == 0 ||
549 memcmp(shname_prog, "xdp", 3) == 0 ||
550 memcmp(shname_prog, "perf_event", 10) == 0 ||
551 memcmp(shname_prog, "socket", 6) == 0 ||
552 memcmp(shname_prog, "cgroup/", 7) == 0)
553 load_and_attach(shname_prog, insns, data_prog->d_size);
554 } 545 }
555 } 546 }
556 547
557 /* load programs that don't use maps */ 548 /* load programs */
558 for (i = 1; i < ehdr.e_shnum; i++) { 549 for (i = 1; i < ehdr.e_shnum; i++) {
559 550
560 if (processed_sec[i]) 551 if (processed_sec[i])