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


Alexei Starovoitov says:

====================
pull-request: bpf-next 2020-05-14

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

The main changes are:

1) Merged tag 'perf-for-bpf-2020-05-06' from tip tree that includes CAP_PERFMON.

2) support for narrow loads in bpf_sock_addr progs and additional
   helpers in cg-skb progs, from Andrey.

3) bpf benchmark runner, from Andrii.

4) arm and riscv JIT optimizations, from Luke.

5) bpf iterator infrastructure, from Yonghong.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 9b65d2ff b92d44b5
Loading
Loading
Loading
Loading
+9 −5
Original line number Diff line number Diff line
@@ -795,6 +795,9 @@ static inline void emit_a32_alu_i(const s8 dst, const u32 val,
	case BPF_RSH:
		emit(ARM_LSR_I(rd, rd, val), ctx);
		break;
	case BPF_ARSH:
		emit(ARM_ASR_I(rd, rd, val), ctx);
		break;
	case BPF_NEG:
		emit(ARM_RSB_I(rd, rd, val), ctx);
		break;
@@ -860,8 +863,8 @@ static inline void emit_a32_arsh_r64(const s8 dst[], const s8 src[],
	emit(ARM_SUBS_I(tmp2[0], rt, 32), ctx);
	emit(ARM_MOV_SR(ARM_LR, rd[1], SRTYPE_LSR, rt), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASL, ARM_IP), ctx);
	_emit(ARM_COND_MI, ARM_B(0), ctx);
	emit(ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASR, tmp2[0]), ctx);
	_emit(ARM_COND_PL,
	      ARM_ORR_SR(ARM_LR, ARM_LR, rd[0], SRTYPE_ASR, tmp2[0]), ctx);
	emit(ARM_MOV_SR(ARM_IP, rd[0], SRTYPE_ASR, rt), ctx);

	arm_bpf_put_reg32(dst_lo, ARM_LR, ctx);
@@ -1408,7 +1411,6 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
	case BPF_ALU | BPF_MUL | BPF_X:
	case BPF_ALU | BPF_LSH | BPF_X:
	case BPF_ALU | BPF_RSH | BPF_X:
	case BPF_ALU | BPF_ARSH | BPF_K:
	case BPF_ALU | BPF_ARSH | BPF_X:
	case BPF_ALU64 | BPF_ADD | BPF_K:
	case BPF_ALU64 | BPF_ADD | BPF_X:
@@ -1465,10 +1467,12 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
	case BPF_ALU64 | BPF_MOD | BPF_K:
	case BPF_ALU64 | BPF_MOD | BPF_X:
		goto notyet;
	/* dst = dst >> imm */
	/* dst = dst << imm */
	case BPF_ALU | BPF_RSH | BPF_K:
	/* dst = dst >> imm */
	/* dst = dst >> imm (signed) */
	case BPF_ALU | BPF_LSH | BPF_K:
	case BPF_ALU | BPF_RSH | BPF_K:
	case BPF_ALU | BPF_ARSH | BPF_K:
		if (unlikely(imm > 31))
			return -EINVAL;
		if (imm)
+3 −0
Original line number Diff line number Diff line
@@ -94,6 +94,9 @@
#define ARM_INST_LSR_I		0x01a00020
#define ARM_INST_LSR_R		0x01a00030

#define ARM_INST_ASR_I		0x01a00040
#define ARM_INST_ASR_R		0x01a00050

#define ARM_INST_MOV_R		0x01a00000
#define ARM_INST_MOVS_R		0x01b00000
#define ARM_INST_MOV_I		0x03a00000
+44 −20
Original line number Diff line number Diff line
@@ -515,7 +515,7 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,
	case BPF_ALU | BPF_LSH | BPF_X:
	case BPF_ALU64 | BPF_LSH | BPF_X:
		emit(is64 ? rv_sll(rd, rd, rs) : rv_sllw(rd, rd, rs), ctx);
		if (!is64)
		if (!is64 && !aux->verifier_zext)
			emit_zext_32(rd, ctx);
		break;
	case BPF_ALU | BPF_RSH | BPF_X:
@@ -542,13 +542,21 @@ int bpf_jit_emit_insn(const struct bpf_insn *insn, struct rv_jit_context *ctx,

	/* dst = BSWAP##imm(dst) */
	case BPF_ALU | BPF_END | BPF_FROM_LE:
	{
		int shift = 64 - imm;

		emit(rv_slli(rd, rd, shift), ctx);
		emit(rv_srli(rd, rd, shift), ctx);
		switch (imm) {
		case 16:
			emit(rv_slli(rd, rd, 48), ctx);
			emit(rv_srli(rd, rd, 48), ctx);
			break;
		case 32:
			if (!aux->verifier_zext)
				emit_zext_32(rd, ctx);
			break;
		case 64:
			/* Do nothing */
			break;
		}
		break;

	case BPF_ALU | BPF_END | BPF_FROM_BE:
		emit(rv_addi(RV_REG_T2, RV_REG_ZERO, 0), ctx);

@@ -692,19 +700,19 @@ out_be:
	case BPF_ALU | BPF_LSH | BPF_K:
	case BPF_ALU64 | BPF_LSH | BPF_K:
		emit(is64 ? rv_slli(rd, rd, imm) : rv_slliw(rd, rd, imm), ctx);
		if (!is64)
		if (!is64 && !aux->verifier_zext)
			emit_zext_32(rd, ctx);
		break;
	case BPF_ALU | BPF_RSH | BPF_K:
	case BPF_ALU64 | BPF_RSH | BPF_K:
		emit(is64 ? rv_srli(rd, rd, imm) : rv_srliw(rd, rd, imm), ctx);
		if (!is64)
		if (!is64 && !aux->verifier_zext)
			emit_zext_32(rd, ctx);
		break;
	case BPF_ALU | BPF_ARSH | BPF_K:
	case BPF_ALU64 | BPF_ARSH | BPF_K:
		emit(is64 ? rv_srai(rd, rd, imm) : rv_sraiw(rd, rd, imm), ctx);
		if (!is64)
		if (!is64 && !aux->verifier_zext)
			emit_zext_32(rd, ctx);
		break;

@@ -784,11 +792,15 @@ out_be:
	case BPF_JMP32 | BPF_JSGE | BPF_K:
	case BPF_JMP | BPF_JSLE | BPF_K:
	case BPF_JMP32 | BPF_JSLE | BPF_K:
	case BPF_JMP | BPF_JSET | BPF_K:
	case BPF_JMP32 | BPF_JSET | BPF_K:
		rvoff = rv_offset(i, off, ctx);
		s = ctx->ninsns;
		if (imm) {
			emit_imm(RV_REG_T1, imm, ctx);
			rs = RV_REG_T1;
		} else {
			/* If imm is 0, simply use zero register. */
			rs = RV_REG_ZERO;
		}
		if (!is64) {
			if (is_signed_bpf_cond(BPF_OP(code)))
				emit_sext_32_rd(&rd, ctx);
@@ -799,16 +811,28 @@ out_be:

		/* Adjust for extra insns */
		rvoff -= (e - s) << 2;
		emit_branch(BPF_OP(code), rd, rs, rvoff, ctx);
		break;

		if (BPF_OP(code) == BPF_JSET) {
			/* Adjust for and */
			rvoff -= 4;
			emit(rv_and(RV_REG_T1, rd, RV_REG_T1), ctx);
			emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff,
				    ctx);
	case BPF_JMP | BPF_JSET | BPF_K:
	case BPF_JMP32 | BPF_JSET | BPF_K:
		rvoff = rv_offset(i, off, ctx);
		s = ctx->ninsns;
		if (is_12b_int(imm)) {
			emit(rv_andi(RV_REG_T1, rd, imm), ctx);
		} else {
			emit_branch(BPF_OP(code), rd, RV_REG_T1, rvoff, ctx);
			emit_imm(RV_REG_T1, imm, ctx);
			emit(rv_and(RV_REG_T1, rd, RV_REG_T1), ctx);
		}
		/* For jset32, we should clear the upper 32 bits of t1, but
		 * sign-extension is sufficient here and saves one instruction,
		 * as t1 is used only in comparison against zero.
		 */
		if (!is64 && imm < 0)
			emit(rv_addiw(RV_REG_T1, RV_REG_T1, 0), ctx);
		e = ctx->ninsns;
		rvoff -= (e - s) << 2;
		emit_branch(BPF_JNE, RV_REG_T1, RV_REG_ZERO, rvoff, ctx);
		break;

	/* function call */
+2 −2
Original line number Diff line number Diff line
@@ -1475,8 +1475,8 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
	for (i = 0; i < insn_cnt; i++, insn++) {
		const s32 imm32 = insn->imm;
		const bool is64 = BPF_CLASS(insn->code) == BPF_ALU64;
		const bool dstk = insn->dst_reg == BPF_REG_AX ? false : true;
		const bool sstk = insn->src_reg == BPF_REG_AX ? false : true;
		const bool dstk = insn->dst_reg != BPF_REG_AX;
		const bool sstk = insn->src_reg != BPF_REG_AX;
		const u8 code = insn->code;
		const u8 *dst = bpf2ia32[insn->dst_reg];
		const u8 *src = bpf2ia32[insn->src_reg];
+19 −0
Original line number Diff line number Diff line
@@ -98,6 +98,25 @@ static const struct proc_ops proc_net_seq_ops = {
	.proc_release	= seq_release_net,
};

int bpf_iter_init_seq_net(void *priv_data)
{
#ifdef CONFIG_NET_NS
	struct seq_net_private *p = priv_data;

	p->net = get_net(current->nsproxy->net_ns);
#endif
	return 0;
}

void bpf_iter_fini_seq_net(void *priv_data)
{
#ifdef CONFIG_NET_NS
	struct seq_net_private *p = priv_data;

	put_net(p->net);
#endif
}

struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
		struct proc_dir_entry *parent, const struct seq_operations *ops,
		unsigned int state_size, void *data)
Loading