forked from luck/tmp_suning_uos_patched
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2019-08-11 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) x64 JIT code generation fix for backward-jumps to 1st insn, from Alexei. 2) Fix buggy multi-closing of BTF file descriptor in libbpf, from Andrii. 3) Fix libbpf_num_possible_cpus() to make it thread safe, from Takshak. 4) Fix bpftool to dump an error if pinning fails, from Jakub. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
9481382b36
|
@ -390,8 +390,9 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
|
||||||
|
|
||||||
emit_prologue(&prog, bpf_prog->aux->stack_depth,
|
emit_prologue(&prog, bpf_prog->aux->stack_depth,
|
||||||
bpf_prog_was_classic(bpf_prog));
|
bpf_prog_was_classic(bpf_prog));
|
||||||
|
addrs[0] = prog - temp;
|
||||||
|
|
||||||
for (i = 0; i < insn_cnt; i++, insn++) {
|
for (i = 1; i <= insn_cnt; i++, insn++) {
|
||||||
const s32 imm32 = insn->imm;
|
const s32 imm32 = insn->imm;
|
||||||
u32 dst_reg = insn->dst_reg;
|
u32 dst_reg = insn->dst_reg;
|
||||||
u32 src_reg = insn->src_reg;
|
u32 src_reg = insn->src_reg;
|
||||||
|
@ -1105,7 +1106,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||||
extra_pass = true;
|
extra_pass = true;
|
||||||
goto skip_init_addrs;
|
goto skip_init_addrs;
|
||||||
}
|
}
|
||||||
addrs = kmalloc_array(prog->len, sizeof(*addrs), GFP_KERNEL);
|
addrs = kmalloc_array(prog->len + 1, sizeof(*addrs), GFP_KERNEL);
|
||||||
if (!addrs) {
|
if (!addrs) {
|
||||||
prog = orig_prog;
|
prog = orig_prog;
|
||||||
goto out_addrs;
|
goto out_addrs;
|
||||||
|
@ -1115,7 +1116,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||||
* Before first pass, make a rough estimation of addrs[]
|
* Before first pass, make a rough estimation of addrs[]
|
||||||
* each BPF instruction is translated to less than 64 bytes
|
* each BPF instruction is translated to less than 64 bytes
|
||||||
*/
|
*/
|
||||||
for (proglen = 0, i = 0; i < prog->len; i++) {
|
for (proglen = 0, i = 0; i <= prog->len; i++) {
|
||||||
proglen += 64;
|
proglen += 64;
|
||||||
addrs[i] = proglen;
|
addrs[i] = proglen;
|
||||||
}
|
}
|
||||||
|
@ -1180,7 +1181,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog)
|
||||||
|
|
||||||
if (!image || !prog->is_func || extra_pass) {
|
if (!image || !prog->is_func || extra_pass) {
|
||||||
if (image)
|
if (image)
|
||||||
bpf_prog_fill_jited_linfo(prog, addrs);
|
bpf_prog_fill_jited_linfo(prog, addrs + 1);
|
||||||
out_addrs:
|
out_addrs:
|
||||||
kfree(addrs);
|
kfree(addrs);
|
||||||
kfree(jit_data);
|
kfree(jit_data);
|
||||||
|
|
|
@ -204,7 +204,11 @@ int do_pin_fd(int fd, const char *name)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return bpf_obj_pin(fd, name);
|
err = bpf_obj_pin(fd, name);
|
||||||
|
if (err)
|
||||||
|
p_err("can't pin the object (%s): %s", name, strerror(errno));
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
|
int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
|
||||||
|
@ -237,7 +241,7 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))
|
||||||
|
|
||||||
fd = get_fd_by_id(id);
|
fd = get_fd_by_id(id);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
p_err("can't get prog by id (%u): %s", id, strerror(errno));
|
p_err("can't open object by id (%u): %s", id, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,6 @@ struct bpf_program {
|
||||||
bpf_program_clear_priv_t clear_priv;
|
bpf_program_clear_priv_t clear_priv;
|
||||||
|
|
||||||
enum bpf_attach_type expected_attach_type;
|
enum bpf_attach_type expected_attach_type;
|
||||||
int btf_fd;
|
|
||||||
void *func_info;
|
void *func_info;
|
||||||
__u32 func_info_rec_size;
|
__u32 func_info_rec_size;
|
||||||
__u32 func_info_cnt;
|
__u32 func_info_cnt;
|
||||||
|
@ -313,7 +312,6 @@ void bpf_program__unload(struct bpf_program *prog)
|
||||||
prog->instances.nr = -1;
|
prog->instances.nr = -1;
|
||||||
zfree(&prog->instances.fds);
|
zfree(&prog->instances.fds);
|
||||||
|
|
||||||
zclose(prog->btf_fd);
|
|
||||||
zfree(&prog->func_info);
|
zfree(&prog->func_info);
|
||||||
zfree(&prog->line_info);
|
zfree(&prog->line_info);
|
||||||
}
|
}
|
||||||
|
@ -392,7 +390,6 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx,
|
||||||
prog->instances.fds = NULL;
|
prog->instances.fds = NULL;
|
||||||
prog->instances.nr = -1;
|
prog->instances.nr = -1;
|
||||||
prog->type = BPF_PROG_TYPE_UNSPEC;
|
prog->type = BPF_PROG_TYPE_UNSPEC;
|
||||||
prog->btf_fd = -1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
errout:
|
errout:
|
||||||
|
@ -2288,9 +2285,6 @@ bpf_program_reloc_btf_ext(struct bpf_program *prog, struct bpf_object *obj,
|
||||||
prog->line_info_rec_size = btf_ext__line_info_rec_size(obj->btf_ext);
|
prog->line_info_rec_size = btf_ext__line_info_rec_size(obj->btf_ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!insn_offset)
|
|
||||||
prog->btf_fd = btf__fd(obj->btf);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2463,7 +2457,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
|
||||||
char *cp, errmsg[STRERR_BUFSIZE];
|
char *cp, errmsg[STRERR_BUFSIZE];
|
||||||
int log_buf_size = BPF_LOG_BUF_SIZE;
|
int log_buf_size = BPF_LOG_BUF_SIZE;
|
||||||
char *log_buf;
|
char *log_buf;
|
||||||
int ret;
|
int btf_fd, ret;
|
||||||
|
|
||||||
if (!insns || !insns_cnt)
|
if (!insns || !insns_cnt)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -2478,7 +2472,12 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
|
||||||
load_attr.license = license;
|
load_attr.license = license;
|
||||||
load_attr.kern_version = kern_version;
|
load_attr.kern_version = kern_version;
|
||||||
load_attr.prog_ifindex = prog->prog_ifindex;
|
load_attr.prog_ifindex = prog->prog_ifindex;
|
||||||
load_attr.prog_btf_fd = prog->btf_fd >= 0 ? prog->btf_fd : 0;
|
/* if .BTF.ext was loaded, kernel supports associated BTF for prog */
|
||||||
|
if (prog->obj->btf_ext)
|
||||||
|
btf_fd = bpf_object__btf_fd(prog->obj);
|
||||||
|
else
|
||||||
|
btf_fd = -1;
|
||||||
|
load_attr.prog_btf_fd = btf_fd >= 0 ? btf_fd : 0;
|
||||||
load_attr.func_info = prog->func_info;
|
load_attr.func_info = prog->func_info;
|
||||||
load_attr.func_info_rec_size = prog->func_info_rec_size;
|
load_attr.func_info_rec_size = prog->func_info_rec_size;
|
||||||
load_attr.func_info_cnt = prog->func_info_cnt;
|
load_attr.func_info_cnt = prog->func_info_cnt;
|
||||||
|
@ -5000,13 +4999,15 @@ int libbpf_num_possible_cpus(void)
|
||||||
static const char *fcpu = "/sys/devices/system/cpu/possible";
|
static const char *fcpu = "/sys/devices/system/cpu/possible";
|
||||||
int len = 0, n = 0, il = 0, ir = 0;
|
int len = 0, n = 0, il = 0, ir = 0;
|
||||||
unsigned int start = 0, end = 0;
|
unsigned int start = 0, end = 0;
|
||||||
|
int tmp_cpus = 0;
|
||||||
static int cpus;
|
static int cpus;
|
||||||
char buf[128];
|
char buf[128];
|
||||||
int error = 0;
|
int error = 0;
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
|
|
||||||
if (cpus > 0)
|
tmp_cpus = READ_ONCE(cpus);
|
||||||
return cpus;
|
if (tmp_cpus > 0)
|
||||||
|
return tmp_cpus;
|
||||||
|
|
||||||
fd = open(fcpu, O_RDONLY);
|
fd = open(fcpu, O_RDONLY);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
@ -5029,7 +5030,7 @@ int libbpf_num_possible_cpus(void)
|
||||||
}
|
}
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
|
||||||
for (ir = 0, cpus = 0; ir <= len; ir++) {
|
for (ir = 0, tmp_cpus = 0; ir <= len; ir++) {
|
||||||
/* Each sub string separated by ',' has format \d+-\d+ or \d+ */
|
/* Each sub string separated by ',' has format \d+-\d+ or \d+ */
|
||||||
if (buf[ir] == ',' || buf[ir] == '\0') {
|
if (buf[ir] == ',' || buf[ir] == '\0') {
|
||||||
buf[ir] = '\0';
|
buf[ir] = '\0';
|
||||||
|
@ -5041,13 +5042,15 @@ int libbpf_num_possible_cpus(void)
|
||||||
} else if (n == 1) {
|
} else if (n == 1) {
|
||||||
end = start;
|
end = start;
|
||||||
}
|
}
|
||||||
cpus += end - start + 1;
|
tmp_cpus += end - start + 1;
|
||||||
il = ir + 1;
|
il = ir + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (cpus <= 0) {
|
if (tmp_cpus <= 0) {
|
||||||
pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu);
|
pr_warning("Invalid #CPUs %d from %s\n", tmp_cpus, fcpu);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
return cpus;
|
|
||||||
|
WRITE_ONCE(cpus, tmp_cpus);
|
||||||
|
return tmp_cpus;
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,3 +159,31 @@
|
||||||
.errstr = "loop detected",
|
.errstr = "loop detected",
|
||||||
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
|
.prog_type = BPF_PROG_TYPE_TRACEPOINT,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"not-taken loop with back jump to 1st insn",
|
||||||
|
.insns = {
|
||||||
|
BPF_MOV64_IMM(BPF_REG_0, 123),
|
||||||
|
BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 4, -2),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
|
},
|
||||||
|
.result = ACCEPT,
|
||||||
|
.prog_type = BPF_PROG_TYPE_XDP,
|
||||||
|
.retval = 123,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"taken loop with back jump to 1st insn",
|
||||||
|
.insns = {
|
||||||
|
BPF_MOV64_IMM(BPF_REG_1, 10),
|
||||||
|
BPF_MOV64_IMM(BPF_REG_2, 0),
|
||||||
|
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
|
BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1),
|
||||||
|
BPF_ALU64_IMM(BPF_SUB, BPF_REG_1, 1),
|
||||||
|
BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, -3),
|
||||||
|
BPF_MOV64_REG(BPF_REG_0, BPF_REG_2),
|
||||||
|
BPF_EXIT_INSN(),
|
||||||
|
},
|
||||||
|
.result = ACCEPT,
|
||||||
|
.prog_type = BPF_PROG_TYPE_XDP,
|
||||||
|
.retval = 55,
|
||||||
|
},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user