summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-12-02 19:50:29 +0100
committerDavid S. Miller <davem@davemloft.net>2019-12-02 19:50:29 +0100
commit734c7022adaa7833aa809b3f2c3fc0cf09b2a48e (patch)
treea6d220f304709e6c18c0e42b9746bf0c3fcb74c9
parentMerge branch 'akpm' (patches from Andrew) (diff)
parentlibbpf: Fix readelf output parsing on powerpc with recent binutils (diff)
downloadlinux-734c7022adaa7833aa809b3f2c3fc0cf09b2a48e.tar.xz
linux-734c7022adaa7833aa809b3f2c3fc0cf09b2a48e.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2019-12-02 The following pull-request contains BPF updates for your *net* tree. We've added 10 non-merge commits during the last 6 day(s) which contain a total of 10 files changed, 60 insertions(+), 51 deletions(-). The main changes are: 1) Fix vmlinux BTF generation for binutils pre v2.25, from Stanislav Fomichev. 2) Fix libbpf global variable relocation to take symbol's st_value offset into account, from Andrii Nakryiko. 3) Fix libbpf build on powerpc where check_abi target fails due to different readelf output format, from Aurelien Jarno. 4) Don't set BPF insns RO for the case when they are JITed in order to avoid fragmenting the direct map, from Daniel Borkmann. 5) Fix static checker warning in btf_distill_func_proto() as well as a build error due to empty enum when BPF is compiled out, from Alexei Starovoitov. 6) Fix up generation of bpf_helper_defs.h for perf, from Arnaldo Carvalho de Melo. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/filter.h8
-rw-r--r--kernel/bpf/btf.c5
-rwxr-xr-xscripts/link-vmlinux.sh8
-rw-r--r--tools/lib/bpf/Makefile10
-rw-r--r--tools/lib/bpf/libbpf.c45
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/testing/selftests/bpf/progs/fentry_test.c12
-rw-r--r--tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c6
-rw-r--r--tools/testing/selftests/bpf/progs/fexit_test.c12
-rw-r--r--tools/testing/selftests/bpf/progs/test_mmap.c4
10 files changed, 60 insertions, 51 deletions
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 1b1e8b8f88da..a141cb07e76a 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -776,8 +776,12 @@ bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default)
static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
{
- set_vm_flush_reset_perms(fp);
- set_memory_ro((unsigned long)fp, fp->pages);
+#ifndef CONFIG_BPF_JIT_ALWAYS_ON
+ if (!fp->jited) {
+ set_vm_flush_reset_perms(fp);
+ set_memory_ro((unsigned long)fp, fp->pages);
+ }
+#endif
}
static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 40efde5eedcb..7d40da240891 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -3463,6 +3463,7 @@ enum {
__ctx_convert##_id,
#include <linux/bpf_types.h>
#undef BPF_PROG_TYPE
+ __ctx_convert_unused, /* to avoid empty enum in extreme .config */
};
static u8 bpf_ctx_convert_map[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \
@@ -3976,8 +3977,10 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
t = btf_type_by_id(btf, btf_id);
while (t && btf_type_is_modifier(t))
t = btf_type_by_id(btf, t->type);
- if (!t)
+ if (!t) {
+ *bad_type = btf->types[0];
return -EINVAL;
+ }
if (btf_type_is_ptr(t))
/* kernel size of pointer. Not BPF's size of pointer*/
return sizeof(void *);
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
index 06495379fcd8..436379940356 100755
--- a/scripts/link-vmlinux.sh
+++ b/scripts/link-vmlinux.sh
@@ -127,7 +127,9 @@ gen_btf()
cut -d, -f1 | cut -d' ' -f2)
bin_format=$(LANG=C ${OBJDUMP} -f ${1} | grep 'file format' | \
awk '{print $4}')
- ${OBJCOPY} --dump-section .BTF=.btf.vmlinux.bin ${1} 2>/dev/null
+ ${OBJCOPY} --change-section-address .BTF=0 \
+ --set-section-flags .BTF=alloc -O binary \
+ --only-section=.BTF ${1} .btf.vmlinux.bin
${OBJCOPY} -I binary -O ${bin_format} -B ${bin_arch} \
--rename-section .data=.BTF .btf.vmlinux.bin ${2}
}
@@ -253,6 +255,10 @@ btf_vmlinux_bin_o=""
if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
if gen_btf .tmp_vmlinux.btf .btf.vmlinux.bin.o ; then
btf_vmlinux_bin_o=.btf.vmlinux.bin.o
+ else
+ echo >&2 "Failed to generate BTF for vmlinux"
+ echo >&2 "Try to disable CONFIG_DEBUG_INFO_BTF"
+ exit 1
fi
fi
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 99425d0be6ff..3d3d024f7b94 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -147,7 +147,7 @@ TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags)
GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
- awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}' | \
+ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}' | \
sort -u | wc -l)
VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
@@ -180,9 +180,9 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h
$(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h
$(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR)
-bpf_helper_defs.h: $(srctree)/include/uapi/linux/bpf.h
+bpf_helper_defs.h: $(srctree)/tools/include/uapi/linux/bpf.h
$(Q)$(srctree)/scripts/bpf_helpers_doc.py --header \
- --file $(srctree)/include/uapi/linux/bpf.h > bpf_helper_defs.h
+ --file $(srctree)/tools/include/uapi/linux/bpf.h > bpf_helper_defs.h
$(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)
@@ -214,9 +214,9 @@ check_abi: $(OUTPUT)libbpf.so
"versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \
"Please make sure all LIBBPF_API symbols are" \
"versioned in $(VERSION_SCRIPT)." >&2; \
- readelf -s --wide $(OUTPUT)libbpf-in.o | \
+ readelf -s --wide $(BPF_IN_SHARED) | \
cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \
- awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$8}'| \
+ awk '/GLOBAL/ && /DEFAULT/ && !/UND/ {print $$NF}'| \
sort -u > $(OUTPUT)libbpf_global_syms.tmp; \
readelf -s --wide $(OUTPUT)libbpf.so | \
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | \
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index b20f82e58989..3f09772192f1 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -171,10 +171,8 @@ struct bpf_program {
RELO_DATA,
} type;
int insn_idx;
- union {
- int map_idx;
- int text_off;
- };
+ int map_idx;
+ int sym_off;
} *reloc_desc;
int nr_reloc;
int log_level;
@@ -1819,12 +1817,12 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__RELOC;
}
if (sym->st_value % 8) {
- pr_warn("bad call relo offset: %lu\n", sym->st_value);
+ pr_warn("bad call relo offset: %llu\n", (__u64)sym->st_value);
return -LIBBPF_ERRNO__RELOC;
}
reloc_desc->type = RELO_CALL;
reloc_desc->insn_idx = insn_idx;
- reloc_desc->text_off = sym->st_value / 8;
+ reloc_desc->sym_off = sym->st_value;
obj->has_pseudo_calls = true;
return 0;
}
@@ -1868,6 +1866,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
reloc_desc->type = RELO_LD64;
reloc_desc->insn_idx = insn_idx;
reloc_desc->map_idx = map_idx;
+ reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */
return 0;
}
@@ -1899,6 +1898,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
reloc_desc->type = RELO_DATA;
reloc_desc->insn_idx = insn_idx;
reloc_desc->map_idx = map_idx;
+ reloc_desc->sym_off = sym->st_value;
return 0;
}
@@ -3563,8 +3563,8 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
return -LIBBPF_ERRNO__RELOC;
if (prog->idx == obj->efile.text_shndx) {
- pr_warn("relo in .text insn %d into off %d\n",
- relo->insn_idx, relo->text_off);
+ pr_warn("relo in .text insn %d into off %d (insn #%d)\n",
+ relo->insn_idx, relo->sym_off, relo->sym_off / 8);
return -LIBBPF_ERRNO__RELOC;
}
@@ -3599,7 +3599,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
prog->section_name);
}
insn = &prog->insns[relo->insn_idx];
- insn->imm += relo->text_off + prog->main_prog_cnt - relo->insn_idx;
+ insn->imm += relo->sym_off / 8 + prog->main_prog_cnt - relo->insn_idx;
return 0;
}
@@ -3622,31 +3622,26 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
return 0;
for (i = 0; i < prog->nr_reloc; i++) {
- if (prog->reloc_desc[i].type == RELO_LD64 ||
- prog->reloc_desc[i].type == RELO_DATA) {
- bool relo_data = prog->reloc_desc[i].type == RELO_DATA;
- struct bpf_insn *insns = prog->insns;
- int insn_idx, map_idx;
+ struct reloc_desc *relo = &prog->reloc_desc[i];
- insn_idx = prog->reloc_desc[i].insn_idx;
- map_idx = prog->reloc_desc[i].map_idx;
+ if (relo->type == RELO_LD64 || relo->type == RELO_DATA) {
+ struct bpf_insn *insn = &prog->insns[relo->insn_idx];
- if (insn_idx + 1 >= (int)prog->insns_cnt) {
+ if (relo->insn_idx + 1 >= (int)prog->insns_cnt) {
pr_warn("relocation out of range: '%s'\n",
prog->section_name);
return -LIBBPF_ERRNO__RELOC;
}
- if (!relo_data) {
- insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
+ if (relo->type != RELO_DATA) {
+ insn[0].src_reg = BPF_PSEUDO_MAP_FD;
} else {
- insns[insn_idx].src_reg = BPF_PSEUDO_MAP_VALUE;
- insns[insn_idx + 1].imm = insns[insn_idx].imm;
+ insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
+ insn[1].imm = insn[0].imm + relo->sym_off;
}
- insns[insn_idx].imm = obj->maps[map_idx].fd;
- } else if (prog->reloc_desc[i].type == RELO_CALL) {
- err = bpf_program__reloc_text(prog, obj,
- &prog->reloc_desc[i]);
+ insn[0].imm = obj->maps[relo->map_idx].fd;
+ } else if (relo->type == RELO_CALL) {
+ err = bpf_program__reloc_text(prog, obj, relo);
if (err)
return err;
}
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 70f1ff4e2eb4..4934edb5adfd 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -19,3 +19,4 @@ tools/lib/bitmap.c
tools/lib/str_error_r.c
tools/lib/vsprintf.c
tools/lib/zalloc.c
+scripts/bpf_helpers_doc.py
diff --git a/tools/testing/selftests/bpf/progs/fentry_test.c b/tools/testing/selftests/bpf/progs/fentry_test.c
index d2af9f039df5..615f7c6bca77 100644
--- a/tools/testing/selftests/bpf/progs/fentry_test.c
+++ b/tools/testing/selftests/bpf/progs/fentry_test.c
@@ -6,28 +6,28 @@
char _license[] SEC("license") = "GPL";
-static volatile __u64 test1_result;
+__u64 test1_result = 0;
BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a)
{
test1_result = a == 1;
return 0;
}
-static volatile __u64 test2_result;
+__u64 test2_result = 0;
BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b)
{
test2_result = a == 2 && b == 3;
return 0;
}
-static volatile __u64 test3_result;
+__u64 test3_result = 0;
BPF_TRACE_3("fentry/bpf_fentry_test3", test3, char, a, int, b, __u64, c)
{
test3_result = a == 4 && b == 5 && c == 6;
return 0;
}
-static volatile __u64 test4_result;
+__u64 test4_result = 0;
BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
void *, a, char, b, int, c, __u64, d)
{
@@ -35,7 +35,7 @@ BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
return 0;
}
-static volatile __u64 test5_result;
+__u64 test5_result = 0;
BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
__u64, a, void *, b, short, c, int, d, __u64, e)
{
@@ -44,7 +44,7 @@ BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
return 0;
}
-static volatile __u64 test6_result;
+__u64 test6_result = 0;
BPF_TRACE_6("fentry/bpf_fentry_test6", test6,
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f)
{
diff --git a/tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c b/tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c
index 525d47d7b589..2d211ee98a1c 100644
--- a/tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c
+++ b/tools/testing/selftests/bpf/progs/fexit_bpf2bpf.c
@@ -8,7 +8,7 @@ struct sk_buff {
unsigned int len;
};
-static volatile __u64 test_result;
+__u64 test_result = 0;
BPF_TRACE_2("fexit/test_pkt_access", test_main,
struct sk_buff *, skb, int, ret)
{
@@ -23,7 +23,7 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main,
return 0;
}
-static volatile __u64 test_result_subprog1;
+__u64 test_result_subprog1 = 0;
BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1,
struct sk_buff *, skb, int, ret)
{
@@ -56,7 +56,7 @@ struct args_subprog2 {
__u64 args[5];
__u64 ret;
};
-static volatile __u64 test_result_subprog2;
+__u64 test_result_subprog2 = 0;
SEC("fexit/test_pkt_access_subprog2")
int test_subprog2(struct args_subprog2 *ctx)
{
diff --git a/tools/testing/selftests/bpf/progs/fexit_test.c b/tools/testing/selftests/bpf/progs/fexit_test.c
index 2487e98edb34..86db0d60fb6e 100644
--- a/tools/testing/selftests/bpf/progs/fexit_test.c
+++ b/tools/testing/selftests/bpf/progs/fexit_test.c
@@ -6,28 +6,28 @@
char _license[] SEC("license") = "GPL";
-static volatile __u64 test1_result;
+__u64 test1_result = 0;
BPF_TRACE_2("fexit/bpf_fentry_test1", test1, int, a, int, ret)
{
test1_result = a == 1 && ret == 2;
return 0;
}
-static volatile __u64 test2_result;
+__u64 test2_result = 0;
BPF_TRACE_3("fexit/bpf_fentry_test2", test2, int, a, __u64, b, int, ret)
{
test2_result = a == 2 && b == 3 && ret == 5;
return 0;
}
-static volatile __u64 test3_result;
+__u64 test3_result = 0;
BPF_TRACE_4("fexit/bpf_fentry_test3", test3, char, a, int, b, __u64, c, int, ret)
{
test3_result = a == 4 && b == 5 && c == 6 && ret == 15;
return 0;
}
-static volatile __u64 test4_result;
+__u64 test4_result = 0;
BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
void *, a, char, b, int, c, __u64, d, int, ret)
{
@@ -37,7 +37,7 @@ BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
return 0;
}
-static volatile __u64 test5_result;
+__u64 test5_result = 0;
BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
__u64, a, void *, b, short, c, int, d, __u64, e, int, ret)
{
@@ -46,7 +46,7 @@ BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
return 0;
}
-static volatile __u64 test6_result;
+__u64 test6_result = 0;
BPF_TRACE_7("fexit/bpf_fentry_test6", test6,
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f,
int, ret)
diff --git a/tools/testing/selftests/bpf/progs/test_mmap.c b/tools/testing/selftests/bpf/progs/test_mmap.c
index 0d2ec9fbcf61..e808791b7047 100644
--- a/tools/testing/selftests/bpf/progs/test_mmap.c
+++ b/tools/testing/selftests/bpf/progs/test_mmap.c
@@ -15,8 +15,8 @@ struct {
__type(value, __u64);
} data_map SEC(".maps");
-static volatile __u64 in_val;
-static volatile __u64 out_val;
+__u64 in_val = 0;
+__u64 out_val = 0;
SEC("raw_tracepoint/sys_enter")
int test_mmap(void *ctx)