Commit 734c7022 authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 596cf45c 3464afdf
...@@ -776,8 +776,12 @@ bpf_ctx_narrow_access_offset(u32 off, u32 size, u32 size_default) ...@@ -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) static inline void bpf_prog_lock_ro(struct bpf_prog *fp)
{ {
set_vm_flush_reset_perms(fp); #ifndef CONFIG_BPF_JIT_ALWAYS_ON
set_memory_ro((unsigned long)fp, fp->pages); 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) static inline void bpf_jit_binary_lock_ro(struct bpf_binary_header *hdr)
......
...@@ -3463,6 +3463,7 @@ enum { ...@@ -3463,6 +3463,7 @@ enum {
__ctx_convert##_id, __ctx_convert##_id,
#include <linux/bpf_types.h> #include <linux/bpf_types.h>
#undef BPF_PROG_TYPE #undef BPF_PROG_TYPE
__ctx_convert_unused, /* to avoid empty enum in extreme .config */
}; };
static u8 bpf_ctx_convert_map[] = { static u8 bpf_ctx_convert_map[] = {
#define BPF_PROG_TYPE(_id, _name, prog_ctx_type, kern_ctx_type) \ #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, ...@@ -3976,8 +3977,10 @@ static int __get_type_size(struct btf *btf, u32 btf_id,
t = btf_type_by_id(btf, btf_id); t = btf_type_by_id(btf, btf_id);
while (t && btf_type_is_modifier(t)) while (t && btf_type_is_modifier(t))
t = btf_type_by_id(btf, t->type); t = btf_type_by_id(btf, t->type);
if (!t) if (!t) {
*bad_type = btf->types[0];
return -EINVAL; return -EINVAL;
}
if (btf_type_is_ptr(t)) if (btf_type_is_ptr(t))
/* kernel size of pointer. Not BPF's size of pointer*/ /* kernel size of pointer. Not BPF's size of pointer*/
return sizeof(void *); return sizeof(void *);
......
...@@ -127,7 +127,9 @@ gen_btf() ...@@ -127,7 +127,9 @@ gen_btf()
cut -d, -f1 | cut -d' ' -f2) cut -d, -f1 | cut -d' ' -f2)
bin_format=$(LANG=C ${OBJDUMP} -f ${1} | grep 'file format' | \ bin_format=$(LANG=C ${OBJDUMP} -f ${1} | grep 'file format' | \
awk '{print $4}') 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} \ ${OBJCOPY} -I binary -O ${bin_format} -B ${bin_arch} \
--rename-section .data=.BTF .btf.vmlinux.bin ${2} --rename-section .data=.BTF .btf.vmlinux.bin ${2}
} }
...@@ -253,6 +255,10 @@ btf_vmlinux_bin_o="" ...@@ -253,6 +255,10 @@ btf_vmlinux_bin_o=""
if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then if [ -n "${CONFIG_DEBUG_INFO_BTF}" ]; then
if gen_btf .tmp_vmlinux.btf .btf.vmlinux.bin.o ; then if gen_btf .tmp_vmlinux.btf .btf.vmlinux.bin.o ; then
btf_vmlinux_bin_o=.btf.vmlinux.bin.o 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
fi fi
......
...@@ -147,7 +147,7 @@ TAGS_PROG := $(if $(shell which etags 2>/dev/null),etags,ctags) ...@@ -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) | \ GLOBAL_SYM_COUNT = $(shell readelf -s --wide $(BPF_IN_SHARED) | \
cut -d "@" -f1 | sed 's/_v[0-9]_[0-9]_[0-9].*//' | \ 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) sort -u | wc -l)
VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \ VERSIONED_SYM_COUNT = $(shell readelf -s --wide $(OUTPUT)libbpf.so | \
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l) grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | sort -u | wc -l)
...@@ -180,9 +180,9 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h ...@@ -180,9 +180,9 @@ $(BPF_IN_SHARED): force elfdep bpfdep bpf_helper_defs.h
$(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h $(BPF_IN_STATIC): force elfdep bpfdep bpf_helper_defs.h
$(Q)$(MAKE) $(build)=libbpf OUTPUT=$(STATIC_OBJDIR) $(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 \ $(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) $(OUTPUT)libbpf.so: $(OUTPUT)libbpf.so.$(LIBBPF_VERSION)
...@@ -214,9 +214,9 @@ check_abi: $(OUTPUT)libbpf.so ...@@ -214,9 +214,9 @@ check_abi: $(OUTPUT)libbpf.so
"versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \ "versioned symbols in $^ ($(VERSIONED_SYM_COUNT))." \
"Please make sure all LIBBPF_API symbols are" \ "Please make sure all LIBBPF_API symbols are" \
"versioned in $(VERSION_SCRIPT)." >&2; \ "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].*//' | \ 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; \ sort -u > $(OUTPUT)libbpf_global_syms.tmp; \
readelf -s --wide $(OUTPUT)libbpf.so | \ readelf -s --wide $(OUTPUT)libbpf.so | \
grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | \ grep -Eo '[^ ]+@LIBBPF_' | cut -d@ -f1 | \
......
...@@ -171,10 +171,8 @@ struct bpf_program { ...@@ -171,10 +171,8 @@ struct bpf_program {
RELO_DATA, RELO_DATA,
} type; } type;
int insn_idx; int insn_idx;
union { int map_idx;
int map_idx; int sym_off;
int text_off;
};
} *reloc_desc; } *reloc_desc;
int nr_reloc; int nr_reloc;
int log_level; int log_level;
...@@ -1819,12 +1817,12 @@ static int bpf_program__record_reloc(struct bpf_program *prog, ...@@ -1819,12 +1817,12 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
return -LIBBPF_ERRNO__RELOC; return -LIBBPF_ERRNO__RELOC;
} }
if (sym->st_value % 8) { 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; return -LIBBPF_ERRNO__RELOC;
} }
reloc_desc->type = RELO_CALL; reloc_desc->type = RELO_CALL;
reloc_desc->insn_idx = insn_idx; 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; obj->has_pseudo_calls = true;
return 0; return 0;
} }
...@@ -1868,6 +1866,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog, ...@@ -1868,6 +1866,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
reloc_desc->type = RELO_LD64; reloc_desc->type = RELO_LD64;
reloc_desc->insn_idx = insn_idx; reloc_desc->insn_idx = insn_idx;
reloc_desc->map_idx = map_idx; reloc_desc->map_idx = map_idx;
reloc_desc->sym_off = 0; /* sym->st_value determines map_idx */
return 0; return 0;
} }
...@@ -1899,6 +1898,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog, ...@@ -1899,6 +1898,7 @@ static int bpf_program__record_reloc(struct bpf_program *prog,
reloc_desc->type = RELO_DATA; reloc_desc->type = RELO_DATA;
reloc_desc->insn_idx = insn_idx; reloc_desc->insn_idx = insn_idx;
reloc_desc->map_idx = map_idx; reloc_desc->map_idx = map_idx;
reloc_desc->sym_off = sym->st_value;
return 0; return 0;
} }
...@@ -3563,8 +3563,8 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, ...@@ -3563,8 +3563,8 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
return -LIBBPF_ERRNO__RELOC; return -LIBBPF_ERRNO__RELOC;
if (prog->idx == obj->efile.text_shndx) { if (prog->idx == obj->efile.text_shndx) {
pr_warn("relo in .text insn %d into off %d\n", pr_warn("relo in .text insn %d into off %d (insn #%d)\n",
relo->insn_idx, relo->text_off); relo->insn_idx, relo->sym_off, relo->sym_off / 8);
return -LIBBPF_ERRNO__RELOC; return -LIBBPF_ERRNO__RELOC;
} }
...@@ -3599,7 +3599,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj, ...@@ -3599,7 +3599,7 @@ bpf_program__reloc_text(struct bpf_program *prog, struct bpf_object *obj,
prog->section_name); prog->section_name);
} }
insn = &prog->insns[relo->insn_idx]; 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; return 0;
} }
...@@ -3622,31 +3622,26 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj) ...@@ -3622,31 +3622,26 @@ bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
return 0; return 0;
for (i = 0; i < prog->nr_reloc; i++) { for (i = 0; i < prog->nr_reloc; i++) {
if (prog->reloc_desc[i].type == RELO_LD64 || struct reloc_desc *relo = &prog->reloc_desc[i];
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;
insn_idx = prog->reloc_desc[i].insn_idx; if (relo->type == RELO_LD64 || relo->type == RELO_DATA) {
map_idx = prog->reloc_desc[i].map_idx; 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", pr_warn("relocation out of range: '%s'\n",
prog->section_name); prog->section_name);
return -LIBBPF_ERRNO__RELOC; return -LIBBPF_ERRNO__RELOC;
} }
if (!relo_data) { if (relo->type != RELO_DATA) {
insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD; insn[0].src_reg = BPF_PSEUDO_MAP_FD;
} else { } else {
insns[insn_idx].src_reg = BPF_PSEUDO_MAP_VALUE; insn[0].src_reg = BPF_PSEUDO_MAP_VALUE;
insns[insn_idx + 1].imm = insns[insn_idx].imm; insn[1].imm = insn[0].imm + relo->sym_off;
} }
insns[insn_idx].imm = obj->maps[map_idx].fd; insn[0].imm = obj->maps[relo->map_idx].fd;
} else if (prog->reloc_desc[i].type == RELO_CALL) { } else if (relo->type == RELO_CALL) {
err = bpf_program__reloc_text(prog, obj, err = bpf_program__reloc_text(prog, obj, relo);
&prog->reloc_desc[i]);
if (err) if (err)
return err; return err;
} }
......
...@@ -19,3 +19,4 @@ tools/lib/bitmap.c ...@@ -19,3 +19,4 @@ tools/lib/bitmap.c
tools/lib/str_error_r.c tools/lib/str_error_r.c
tools/lib/vsprintf.c tools/lib/vsprintf.c
tools/lib/zalloc.c tools/lib/zalloc.c
scripts/bpf_helpers_doc.py
...@@ -6,28 +6,28 @@ ...@@ -6,28 +6,28 @@
char _license[] SEC("license") = "GPL"; char _license[] SEC("license") = "GPL";
static volatile __u64 test1_result; __u64 test1_result = 0;
BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a) BPF_TRACE_1("fentry/bpf_fentry_test1", test1, int, a)
{ {
test1_result = a == 1; test1_result = a == 1;
return 0; return 0;
} }
static volatile __u64 test2_result; __u64 test2_result = 0;
BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b) BPF_TRACE_2("fentry/bpf_fentry_test2", test2, int, a, __u64, b)
{ {
test2_result = a == 2 && b == 3; test2_result = a == 2 && b == 3;
return 0; 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) BPF_TRACE_3("fentry/bpf_fentry_test3", test3, char, a, int, b, __u64, c)
{ {
test3_result = a == 4 && b == 5 && c == 6; test3_result = a == 4 && b == 5 && c == 6;
return 0; return 0;
} }
static volatile __u64 test4_result; __u64 test4_result = 0;
BPF_TRACE_4("fentry/bpf_fentry_test4", test4, BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
void *, a, char, b, int, c, __u64, d) void *, a, char, b, int, c, __u64, d)
{ {
...@@ -35,7 +35,7 @@ BPF_TRACE_4("fentry/bpf_fentry_test4", test4, ...@@ -35,7 +35,7 @@ BPF_TRACE_4("fentry/bpf_fentry_test4", test4,
return 0; return 0;
} }
static volatile __u64 test5_result; __u64 test5_result = 0;
BPF_TRACE_5("fentry/bpf_fentry_test5", test5, BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
__u64, a, void *, b, short, c, int, d, __u64, e) __u64, a, void *, b, short, c, int, d, __u64, e)
{ {
...@@ -44,7 +44,7 @@ BPF_TRACE_5("fentry/bpf_fentry_test5", test5, ...@@ -44,7 +44,7 @@ BPF_TRACE_5("fentry/bpf_fentry_test5", test5,
return 0; return 0;
} }
static volatile __u64 test6_result; __u64 test6_result = 0;
BPF_TRACE_6("fentry/bpf_fentry_test6", test6, BPF_TRACE_6("fentry/bpf_fentry_test6", test6,
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f) __u64, a, void *, b, short, c, int, d, void *, e, __u64, f)
{ {
......
...@@ -8,7 +8,7 @@ struct sk_buff { ...@@ -8,7 +8,7 @@ struct sk_buff {
unsigned int len; unsigned int len;
}; };
static volatile __u64 test_result; __u64 test_result = 0;
BPF_TRACE_2("fexit/test_pkt_access", test_main, BPF_TRACE_2("fexit/test_pkt_access", test_main,
struct sk_buff *, skb, int, ret) struct sk_buff *, skb, int, ret)
{ {
...@@ -23,7 +23,7 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main, ...@@ -23,7 +23,7 @@ BPF_TRACE_2("fexit/test_pkt_access", test_main,
return 0; return 0;
} }
static volatile __u64 test_result_subprog1; __u64 test_result_subprog1 = 0;
BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1, BPF_TRACE_2("fexit/test_pkt_access_subprog1", test_subprog1,
struct sk_buff *, skb, int, ret) struct sk_buff *, skb, int, ret)
{ {
...@@ -56,7 +56,7 @@ struct args_subprog2 { ...@@ -56,7 +56,7 @@ struct args_subprog2 {
__u64 args[5]; __u64 args[5];
__u64 ret; __u64 ret;
}; };
static volatile __u64 test_result_subprog2; __u64 test_result_subprog2 = 0;
SEC("fexit/test_pkt_access_subprog2") SEC("fexit/test_pkt_access_subprog2")
int test_subprog2(struct args_subprog2 *ctx) int test_subprog2(struct args_subprog2 *ctx)
{ {
......
...@@ -6,28 +6,28 @@ ...@@ -6,28 +6,28 @@
char _license[] SEC("license") = "GPL"; 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) BPF_TRACE_2("fexit/bpf_fentry_test1", test1, int, a, int, ret)
{ {
test1_result = a == 1 && ret == 2; test1_result = a == 1 && ret == 2;
return 0; 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) BPF_TRACE_3("fexit/bpf_fentry_test2", test2, int, a, __u64, b, int, ret)
{ {
test2_result = a == 2 && b == 3 && ret == 5; test2_result = a == 2 && b == 3 && ret == 5;
return 0; 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) 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; test3_result = a == 4 && b == 5 && c == 6 && ret == 15;
return 0; return 0;
} }
static volatile __u64 test4_result; __u64 test4_result = 0;
BPF_TRACE_5("fexit/bpf_fentry_test4", test4, BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
void *, a, char, b, int, c, __u64, d, int, ret) void *, a, char, b, int, c, __u64, d, int, ret)
{ {
...@@ -37,7 +37,7 @@ BPF_TRACE_5("fexit/bpf_fentry_test4", test4, ...@@ -37,7 +37,7 @@ BPF_TRACE_5("fexit/bpf_fentry_test4", test4,
return 0; return 0;
} }
static volatile __u64 test5_result; __u64 test5_result = 0;
BPF_TRACE_6("fexit/bpf_fentry_test5", test5, BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
__u64, a, void *, b, short, c, int, d, __u64, e, int, ret) __u64, a, void *, b, short, c, int, d, __u64, e, int, ret)
{ {
...@@ -46,7 +46,7 @@ BPF_TRACE_6("fexit/bpf_fentry_test5", test5, ...@@ -46,7 +46,7 @@ BPF_TRACE_6("fexit/bpf_fentry_test5", test5,
return 0; return 0;
} }
static volatile __u64 test6_result; __u64 test6_result = 0;
BPF_TRACE_7("fexit/bpf_fentry_test6", test6, BPF_TRACE_7("fexit/bpf_fentry_test6", test6,
__u64, a, void *, b, short, c, int, d, void *, e, __u64, f, __u64, a, void *, b, short, c, int, d, void *, e, __u64, f,
int, ret) int, ret)
......
...@@ -15,8 +15,8 @@ struct { ...@@ -15,8 +15,8 @@ struct {
__type(value, __u64); __type(value, __u64);
} data_map SEC(".maps"); } data_map SEC(".maps");
static volatile __u64 in_val; __u64 in_val = 0;
static volatile __u64 out_val; __u64 out_val = 0;
SEC("raw_tracepoint/sys_enter") SEC("raw_tracepoint/sys_enter")
int test_mmap(void *ctx) int test_mmap(void *ctx)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment