Commit 9481382b authored by David S. Miller's avatar David S. Miller
Browse files


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: default avatarDavid S. Miller <davem@davemloft.net>
parents 57c722e9 4f7aafd7
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -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,
		      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;
		u32 dst_reg = insn->dst_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;
		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) {
		prog = orig_prog;
		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[]
	 * 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;
		addrs[i] = proglen;
	}
@@ -1180,7 +1181,7 @@ out_image:

	if (!image || !prog->is_func || extra_pass) {
		if (image)
			bpf_prog_fill_jited_linfo(prog, addrs);
			bpf_prog_fill_jited_linfo(prog, addrs + 1);
out_addrs:
		kfree(addrs);
		kfree(jit_data);
+6 −2
Original line number Diff line number Diff line
@@ -204,7 +204,11 @@ int do_pin_fd(int fd, const char *name)
	if (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))
@@ -237,7 +241,7 @@ int do_pin_any(int argc, char **argv, int (*get_fd_by_id)(__u32))

	fd = get_fd_by_id(id);
	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;
	}

+18 −15
Original line number Diff line number Diff line
@@ -182,7 +182,6 @@ struct bpf_program {
	bpf_program_clear_priv_t clear_priv;

	enum bpf_attach_type expected_attach_type;
	int btf_fd;
	void *func_info;
	__u32 func_info_rec_size;
	__u32 func_info_cnt;
@@ -313,7 +312,6 @@ void bpf_program__unload(struct bpf_program *prog)
	prog->instances.nr = -1;
	zfree(&prog->instances.fds);

	zclose(prog->btf_fd);
	zfree(&prog->func_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.nr = -1;
	prog->type = BPF_PROG_TYPE_UNSPEC;
	prog->btf_fd = -1;

	return 0;
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);
	}

	if (!insn_offset)
		prog->btf_fd = btf__fd(obj->btf);

	return 0;
}

@@ -2463,7 +2457,7 @@ load_program(struct bpf_program *prog, struct bpf_insn *insns, int insns_cnt,
	char *cp, errmsg[STRERR_BUFSIZE];
	int log_buf_size = BPF_LOG_BUF_SIZE;
	char *log_buf;
	int ret;
	int btf_fd, ret;

	if (!insns || !insns_cnt)
		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.kern_version = kern_version;
	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_rec_size = prog->func_info_rec_size;
	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";
	int len = 0, n = 0, il = 0, ir = 0;
	unsigned int start = 0, end = 0;
	int tmp_cpus = 0;
	static int cpus;
	char buf[128];
	int error = 0;
	int fd = -1;

	if (cpus > 0)
		return cpus;
	tmp_cpus = READ_ONCE(cpus);
	if (tmp_cpus > 0)
		return tmp_cpus;

	fd = open(fcpu, O_RDONLY);
	if (fd < 0) {
@@ -5029,7 +5030,7 @@ int libbpf_num_possible_cpus(void)
	}
	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+ */
		if (buf[ir] == ',' || buf[ir] == '\0') {
			buf[ir] = '\0';
@@ -5041,13 +5042,15 @@ int libbpf_num_possible_cpus(void)
			} else if (n == 1) {
				end = start;
			}
			cpus += end - start + 1;
			tmp_cpus += end - start + 1;
			il = ir + 1;
		}
	}
	if (cpus <= 0) {
		pr_warning("Invalid #CPUs %d from %s\n", cpus, fcpu);
	if (tmp_cpus <= 0) {
		pr_warning("Invalid #CPUs %d from %s\n", tmp_cpus, fcpu);
		return -EINVAL;
	}
	return cpus;

	WRITE_ONCE(cpus, tmp_cpus);
	return tmp_cpus;
}
+28 −0
Original line number Diff line number Diff line
@@ -159,3 +159,31 @@
	.errstr = "loop detected",
	.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,
},