Commit 167ff131 authored by David S. Miller's avatar David S. Miller
Browse files


Alexei Starovoitov says:

====================
pull-request: bpf 2020-04-24

The following pull-request contains BPF updates for your *net* tree.

We've added 17 non-merge commits during the last 5 day(s) which contain
a total of 19 files changed, 203 insertions(+), 85 deletions(-).

The main changes are:

1) link_update fix, from Andrii.

2) libbpf get_xdp_id fix, from David.

3) xadd verifier fix, from Jann.

4) x86-32 JIT fixes, from Luke and Wang.

5) test_btf fix, from Stanislav.

6) freplace verifier fix, from Toke.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3554e54a e1cebd84
Loading
Loading
Loading
Loading
+15 −3
Original line number Diff line number Diff line
@@ -158,6 +158,19 @@ static bool is_ereg(u32 reg)
			     BIT(BPF_REG_AX));
}

/*
 * is_ereg_8l() == true if BPF register 'reg' is mapped to access x86-64
 * lower 8-bit registers dil,sil,bpl,spl,r8b..r15b, which need extra byte
 * of encoding. al,cl,dl,bl have simpler encoding.
 */
static bool is_ereg_8l(u32 reg)
{
	return is_ereg(reg) ||
	    (1 << reg) & (BIT(BPF_REG_1) |
			  BIT(BPF_REG_2) |
			  BIT(BPF_REG_FP));
}

static bool is_axreg(u32 reg)
{
	return reg == BPF_REG_0;
@@ -598,9 +611,8 @@ static void emit_stx(u8 **pprog, u32 size, u32 dst_reg, u32 src_reg, int off)
	switch (size) {
	case BPF_B:
		/* Emit 'mov byte ptr [rax + off], al' */
		if (is_ereg(dst_reg) || is_ereg(src_reg) ||
		    /* We have to add extra byte for x86 SIL, DIL regs */
		    src_reg == BPF_REG_1 || src_reg == BPF_REG_2)
		if (is_ereg(dst_reg) || is_ereg_8l(src_reg))
			/* Add extra byte for eregs or SIL,DIL,BPL in src_reg */
			EMIT2(add_2mod(0x40, dst_reg, src_reg), 0x88);
		else
			EMIT1(0x88);
+22 −6
Original line number Diff line number Diff line
@@ -1847,14 +1847,16 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
			case BPF_B:
			case BPF_H:
			case BPF_W:
				if (!bpf_prog->aux->verifier_zext)
				if (bpf_prog->aux->verifier_zext)
					break;
				if (dstk) {
					EMIT3(0xC7, add_1reg(0x40, IA32_EBP),
					      STACK_VAR(dst_hi));
					EMIT(0x0, 4);
				} else {
					EMIT3(0xC7, add_1reg(0xC0, dst_hi), 0);
					/* xor dst_hi,dst_hi */
					EMIT2(0x33,
					      add_2reg(0xC0, dst_hi, dst_hi));
				}
				break;
			case BPF_DW:
@@ -2013,8 +2015,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
		case BPF_JMP | BPF_JSET | BPF_X:
		case BPF_JMP32 | BPF_JSET | BPF_X: {
			bool is_jmp64 = BPF_CLASS(insn->code) == BPF_JMP;
			u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
			u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
			u8 dreg_lo = IA32_EAX;
			u8 dreg_hi = IA32_EDX;
			u8 sreg_lo = sstk ? IA32_ECX : src_lo;
			u8 sreg_hi = sstk ? IA32_EBX : src_hi;

@@ -2026,6 +2028,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
					      add_2reg(0x40, IA32_EBP,
						       IA32_EDX),
					      STACK_VAR(dst_hi));
			} else {
				/* mov dreg_lo,dst_lo */
				EMIT2(0x89, add_2reg(0xC0, dreg_lo, dst_lo));
				if (is_jmp64)
					/* mov dreg_hi,dst_hi */
					EMIT2(0x89,
					      add_2reg(0xC0, dreg_hi, dst_hi));
			}

			if (sstk) {
@@ -2050,8 +2059,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
		case BPF_JMP | BPF_JSET | BPF_K:
		case BPF_JMP32 | BPF_JSET | BPF_K: {
			bool is_jmp64 = BPF_CLASS(insn->code) == BPF_JMP;
			u8 dreg_lo = dstk ? IA32_EAX : dst_lo;
			u8 dreg_hi = dstk ? IA32_EDX : dst_hi;
			u8 dreg_lo = IA32_EAX;
			u8 dreg_hi = IA32_EDX;
			u8 sreg_lo = IA32_ECX;
			u8 sreg_hi = IA32_EBX;
			u32 hi;
@@ -2064,6 +2073,13 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
					      add_2reg(0x40, IA32_EBP,
						       IA32_EDX),
					      STACK_VAR(dst_hi));
			} else {
				/* mov dreg_lo,dst_lo */
				EMIT2(0x89, add_2reg(0xC0, dreg_lo, dst_lo));
				if (is_jmp64)
					/* mov dreg_hi,dst_hi */
					EMIT2(0x89,
					      add_2reg(0xC0, dreg_hi, dst_hi));
			}

			/* mov ecx,imm32 */
+1 −1
Original line number Diff line number Diff line
@@ -1642,7 +1642,7 @@ union bpf_attr {
 * 		ifindex, but doesn't require a map to do so.
 * 	Return
 * 		**XDP_REDIRECT** on success, or the value of the two lower bits
 * 		of the **flags* argument on error.
 * 		of the *flags* argument on error.
 *
 * int bpf_sk_redirect_map(struct sk_buff *skb, struct bpf_map *map, u32 key, u64 flags)
 * 	Description
+1 −1
Original line number Diff line number Diff line
@@ -469,7 +469,7 @@ static int cpu_map_update_elem(struct bpf_map *map, void *key, void *value,
		return -EOVERFLOW;

	/* Make sure CPU is a valid possible cpu */
	if (!cpu_possible(key_cpu))
	if (key_cpu >= nr_cpumask_bits || !cpu_possible(key_cpu))
		return -ENODEV;

	if (qsize == 0) {
+10 −3
Original line number Diff line number Diff line
@@ -2283,7 +2283,7 @@ static void bpf_link_show_fdinfo(struct seq_file *m, struct file *filp)
}
#endif

const struct file_operations bpf_link_fops = {
static const struct file_operations bpf_link_fops = {
#ifdef CONFIG_PROC_FS
	.show_fdinfo	= bpf_link_show_fdinfo,
#endif
@@ -3628,8 +3628,10 @@ static int link_update(union bpf_attr *attr)
		return PTR_ERR(link);

	new_prog = bpf_prog_get(attr->link_update.new_prog_fd);
	if (IS_ERR(new_prog))
		return PTR_ERR(new_prog);
	if (IS_ERR(new_prog)) {
		ret = PTR_ERR(new_prog);
		goto out_put_link;
	}

	if (flags & BPF_F_REPLACE) {
		old_prog = bpf_prog_get(attr->link_update.old_prog_fd);
@@ -3638,6 +3640,9 @@ static int link_update(union bpf_attr *attr)
			old_prog = NULL;
			goto out_put_progs;
		}
	} else if (attr->link_update.old_prog_fd) {
		ret = -EINVAL;
		goto out_put_progs;
	}

#ifdef CONFIG_CGROUP_BPF
@@ -3653,6 +3658,8 @@ out_put_progs:
		bpf_prog_put(old_prog);
	if (ret)
		bpf_prog_put(new_prog);
out_put_link:
	bpf_link_put(link);
	return ret;
}

Loading