提交 a83d081e 编写于 作者: D Daniel Borkmann 提交者: Ralf Baechle

MIPS: BPF JIT: Fix build error.

  mips: allmodconfig fails in 3.16-rc1 with lots of undefined symbols.

  arch/mips/net/bpf_jit.c: In function 'is_load_to_a':
  arch/mips/net/bpf_jit.c:559:7: error: 'BPF_S_LD_W_LEN' undeclared (first use in this function)
  arch/mips/net/bpf_jit.c:559:7: note: each undeclared identifier is reported only once for each function it appears in
  arch/mips/net/bpf_jit.c:560:7: error: 'BPF_S_LD_W_ABS' undeclared (first use in this function)
  [...]

The reason behind this is that 34805931 ("net: filter: get rid of
BPF_S_* enum") was routed via net-next tree, that takes all BPF-related
changes, at a time where MIPS BPF JIT was not part of net-next, while
c6610de3 ("MIPS: net: Add BPF JIT") was routed via mips arch tree
and went into mainline within the same merge window. Thus, fix it up by
converting BPF_S_* in a similar fashion as in 34805931 for MIPS.
Reported-by: NGuenter Roeck <linux@roeck-us.net>
Signed-off-by: NDaniel Borkmann <dborkman@redhat.com>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Markos Chandras <markos.chandras@imgtec.com>
Cc: linux-kernel@vger.kernel.org <linux-kernel@vger.kernel.org>
Cc: Linux MIPS Mailing List <linux-mips@linux-mips.org>
Patchwork: https://patchwork.linux-mips.org/patch/7099/Signed-off-by: NRalf Baechle <ralf@linux-mips.org>
上级 16f77de8
...@@ -556,18 +556,10 @@ static inline void update_on_xread(struct jit_ctx *ctx) ...@@ -556,18 +556,10 @@ static inline void update_on_xread(struct jit_ctx *ctx)
static bool is_load_to_a(u16 inst) static bool is_load_to_a(u16 inst)
{ {
switch (inst) { switch (inst) {
case BPF_S_LD_W_LEN: case BPF_LD | BPF_W | BPF_LEN:
case BPF_S_LD_W_ABS: case BPF_LD | BPF_W | BPF_ABS:
case BPF_S_LD_H_ABS: case BPF_LD | BPF_H | BPF_ABS:
case BPF_S_LD_B_ABS: case BPF_LD | BPF_B | BPF_ABS:
case BPF_S_ANC_CPU:
case BPF_S_ANC_IFINDEX:
case BPF_S_ANC_MARK:
case BPF_S_ANC_PROTOCOL:
case BPF_S_ANC_RXHASH:
case BPF_S_ANC_VLAN_TAG:
case BPF_S_ANC_VLAN_TAG_PRESENT:
case BPF_S_ANC_QUEUE:
return true; return true;
default: default:
return false; return false;
...@@ -709,7 +701,7 @@ static void build_prologue(struct jit_ctx *ctx) ...@@ -709,7 +701,7 @@ static void build_prologue(struct jit_ctx *ctx)
emit_jit_reg_move(r_X, r_zero, ctx); emit_jit_reg_move(r_X, r_zero, ctx);
/* Do not leak kernel data to userspace */ /* Do not leak kernel data to userspace */
if ((first_inst != BPF_S_RET_K) && !(is_load_to_a(first_inst))) if ((first_inst != (BPF_RET | BPF_K)) && !(is_load_to_a(first_inst)))
emit_jit_reg_move(r_A, r_zero, ctx); emit_jit_reg_move(r_A, r_zero, ctx);
} }
...@@ -783,41 +775,44 @@ static int build_body(struct jit_ctx *ctx) ...@@ -783,41 +775,44 @@ static int build_body(struct jit_ctx *ctx)
u32 k, b_off __maybe_unused; u32 k, b_off __maybe_unused;
for (i = 0; i < prog->len; i++) { for (i = 0; i < prog->len; i++) {
u16 code;
inst = &(prog->insns[i]); inst = &(prog->insns[i]);
pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n", pr_debug("%s: code->0x%02x, jt->0x%x, jf->0x%x, k->0x%x\n",
__func__, inst->code, inst->jt, inst->jf, inst->k); __func__, inst->code, inst->jt, inst->jf, inst->k);
k = inst->k; k = inst->k;
code = bpf_anc_helper(inst);
if (ctx->target == NULL) if (ctx->target == NULL)
ctx->offsets[i] = ctx->idx * 4; ctx->offsets[i] = ctx->idx * 4;
switch (inst->code) { switch (code) {
case BPF_S_LD_IMM: case BPF_LD | BPF_IMM:
/* A <- k ==> li r_A, k */ /* A <- k ==> li r_A, k */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_load_imm(r_A, k, ctx); emit_load_imm(r_A, k, ctx);
break; break;
case BPF_S_LD_W_LEN: case BPF_LD | BPF_W | BPF_LEN:
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4); BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, len) != 4);
/* A <- len ==> lw r_A, offset(skb) */ /* A <- len ==> lw r_A, offset(skb) */
ctx->flags |= SEEN_SKB | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_A;
off = offsetof(struct sk_buff, len); off = offsetof(struct sk_buff, len);
emit_load(r_A, r_skb, off, ctx); emit_load(r_A, r_skb, off, ctx);
break; break;
case BPF_S_LD_MEM: case BPF_LD | BPF_MEM:
/* A <- M[k] ==> lw r_A, offset(M) */ /* A <- M[k] ==> lw r_A, offset(M) */
ctx->flags |= SEEN_MEM | SEEN_A; ctx->flags |= SEEN_MEM | SEEN_A;
emit_load(r_A, r_M, SCRATCH_OFF(k), ctx); emit_load(r_A, r_M, SCRATCH_OFF(k), ctx);
break; break;
case BPF_S_LD_W_ABS: case BPF_LD | BPF_W | BPF_ABS:
/* A <- P[k:4] */ /* A <- P[k:4] */
load_order = 2; load_order = 2;
goto load; goto load;
case BPF_S_LD_H_ABS: case BPF_LD | BPF_H | BPF_ABS:
/* A <- P[k:2] */ /* A <- P[k:2] */
load_order = 1; load_order = 1;
goto load; goto load;
case BPF_S_LD_B_ABS: case BPF_LD | BPF_B | BPF_ABS:
/* A <- P[k:1] */ /* A <- P[k:1] */
load_order = 0; load_order = 0;
load: load:
...@@ -852,15 +847,15 @@ static int build_body(struct jit_ctx *ctx) ...@@ -852,15 +847,15 @@ static int build_body(struct jit_ctx *ctx)
emit_b(b_imm(prog->len, ctx), ctx); emit_b(b_imm(prog->len, ctx), ctx);
emit_reg_move(r_ret, r_zero, ctx); emit_reg_move(r_ret, r_zero, ctx);
break; break;
case BPF_S_LD_W_IND: case BPF_LD | BPF_W | BPF_IND:
/* A <- P[X + k:4] */ /* A <- P[X + k:4] */
load_order = 2; load_order = 2;
goto load_ind; goto load_ind;
case BPF_S_LD_H_IND: case BPF_LD | BPF_H | BPF_IND:
/* A <- P[X + k:2] */ /* A <- P[X + k:2] */
load_order = 1; load_order = 1;
goto load_ind; goto load_ind;
case BPF_S_LD_B_IND: case BPF_LD | BPF_B | BPF_IND:
/* A <- P[X + k:1] */ /* A <- P[X + k:1] */
load_order = 0; load_order = 0;
load_ind: load_ind:
...@@ -868,23 +863,23 @@ static int build_body(struct jit_ctx *ctx) ...@@ -868,23 +863,23 @@ static int build_body(struct jit_ctx *ctx)
ctx->flags |= SEEN_OFF | SEEN_X; ctx->flags |= SEEN_OFF | SEEN_X;
emit_addiu(r_off, r_X, k, ctx); emit_addiu(r_off, r_X, k, ctx);
goto load_common; goto load_common;
case BPF_S_LDX_IMM: case BPF_LDX | BPF_IMM:
/* X <- k */ /* X <- k */
ctx->flags |= SEEN_X; ctx->flags |= SEEN_X;
emit_load_imm(r_X, k, ctx); emit_load_imm(r_X, k, ctx);
break; break;
case BPF_S_LDX_MEM: case BPF_LDX | BPF_MEM:
/* X <- M[k] */ /* X <- M[k] */
ctx->flags |= SEEN_X | SEEN_MEM; ctx->flags |= SEEN_X | SEEN_MEM;
emit_load(r_X, r_M, SCRATCH_OFF(k), ctx); emit_load(r_X, r_M, SCRATCH_OFF(k), ctx);
break; break;
case BPF_S_LDX_W_LEN: case BPF_LDX | BPF_W | BPF_LEN:
/* X <- len */ /* X <- len */
ctx->flags |= SEEN_X | SEEN_SKB; ctx->flags |= SEEN_X | SEEN_SKB;
off = offsetof(struct sk_buff, len); off = offsetof(struct sk_buff, len);
emit_load(r_X, r_skb, off, ctx); emit_load(r_X, r_skb, off, ctx);
break; break;
case BPF_S_LDX_B_MSH: case BPF_LDX | BPF_B | BPF_MSH:
/* X <- 4 * (P[k:1] & 0xf) */ /* X <- 4 * (P[k:1] & 0xf) */
ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB; ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
/* Load offset to a1 */ /* Load offset to a1 */
...@@ -917,50 +912,50 @@ static int build_body(struct jit_ctx *ctx) ...@@ -917,50 +912,50 @@ static int build_body(struct jit_ctx *ctx)
emit_b(b_imm(prog->len, ctx), ctx); emit_b(b_imm(prog->len, ctx), ctx);
emit_load_imm(r_ret, 0, ctx); /* delay slot */ emit_load_imm(r_ret, 0, ctx); /* delay slot */
break; break;
case BPF_S_ST: case BPF_ST:
/* M[k] <- A */ /* M[k] <- A */
ctx->flags |= SEEN_MEM | SEEN_A; ctx->flags |= SEEN_MEM | SEEN_A;
emit_store(r_A, r_M, SCRATCH_OFF(k), ctx); emit_store(r_A, r_M, SCRATCH_OFF(k), ctx);
break; break;
case BPF_S_STX: case BPF_STX:
/* M[k] <- X */ /* M[k] <- X */
ctx->flags |= SEEN_MEM | SEEN_X; ctx->flags |= SEEN_MEM | SEEN_X;
emit_store(r_X, r_M, SCRATCH_OFF(k), ctx); emit_store(r_X, r_M, SCRATCH_OFF(k), ctx);
break; break;
case BPF_S_ALU_ADD_K: case BPF_ALU | BPF_ADD | BPF_K:
/* A += K */ /* A += K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_addiu(r_A, r_A, k, ctx); emit_addiu(r_A, r_A, k, ctx);
break; break;
case BPF_S_ALU_ADD_X: case BPF_ALU | BPF_ADD | BPF_X:
/* A += X */ /* A += X */
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
emit_addu(r_A, r_A, r_X, ctx); emit_addu(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_SUB_K: case BPF_ALU | BPF_SUB | BPF_K:
/* A -= K */ /* A -= K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_addiu(r_A, r_A, -k, ctx); emit_addiu(r_A, r_A, -k, ctx);
break; break;
case BPF_S_ALU_SUB_X: case BPF_ALU | BPF_SUB | BPF_X:
/* A -= X */ /* A -= X */
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
emit_subu(r_A, r_A, r_X, ctx); emit_subu(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_MUL_K: case BPF_ALU | BPF_MUL | BPF_K:
/* A *= K */ /* A *= K */
/* Load K to scratch register before MUL */ /* Load K to scratch register before MUL */
ctx->flags |= SEEN_A | SEEN_S0; ctx->flags |= SEEN_A | SEEN_S0;
emit_load_imm(r_s0, k, ctx); emit_load_imm(r_s0, k, ctx);
emit_mul(r_A, r_A, r_s0, ctx); emit_mul(r_A, r_A, r_s0, ctx);
break; break;
case BPF_S_ALU_MUL_X: case BPF_ALU | BPF_MUL | BPF_X:
/* A *= X */ /* A *= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
emit_mul(r_A, r_A, r_X, ctx); emit_mul(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_DIV_K: case BPF_ALU | BPF_DIV | BPF_K:
/* A /= k */ /* A /= k */
if (k == 1) if (k == 1)
break; break;
...@@ -973,7 +968,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -973,7 +968,7 @@ static int build_body(struct jit_ctx *ctx)
emit_load_imm(r_s0, k, ctx); emit_load_imm(r_s0, k, ctx);
emit_div(r_A, r_s0, ctx); emit_div(r_A, r_s0, ctx);
break; break;
case BPF_S_ALU_MOD_K: case BPF_ALU | BPF_MOD | BPF_K:
/* A %= k */ /* A %= k */
if (k == 1 || optimize_div(&k)) { if (k == 1 || optimize_div(&k)) {
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
...@@ -984,7 +979,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -984,7 +979,7 @@ static int build_body(struct jit_ctx *ctx)
emit_mod(r_A, r_s0, ctx); emit_mod(r_A, r_s0, ctx);
} }
break; break;
case BPF_S_ALU_DIV_X: case BPF_ALU | BPF_DIV | BPF_X:
/* A /= X */ /* A /= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_X | SEEN_A; ctx->flags |= SEEN_X | SEEN_A;
...@@ -994,7 +989,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -994,7 +989,7 @@ static int build_body(struct jit_ctx *ctx)
emit_load_imm(r_val, 0, ctx); /* delay slot */ emit_load_imm(r_val, 0, ctx); /* delay slot */
emit_div(r_A, r_X, ctx); emit_div(r_A, r_X, ctx);
break; break;
case BPF_S_ALU_MOD_X: case BPF_ALU | BPF_MOD | BPF_X:
/* A %= X */ /* A %= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_X | SEEN_A; ctx->flags |= SEEN_X | SEEN_A;
...@@ -1004,94 +999,94 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1004,94 +999,94 @@ static int build_body(struct jit_ctx *ctx)
emit_load_imm(r_val, 0, ctx); /* delay slot */ emit_load_imm(r_val, 0, ctx); /* delay slot */
emit_mod(r_A, r_X, ctx); emit_mod(r_A, r_X, ctx);
break; break;
case BPF_S_ALU_OR_K: case BPF_ALU | BPF_OR | BPF_K:
/* A |= K */ /* A |= K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_ori(r_A, r_A, k, ctx); emit_ori(r_A, r_A, k, ctx);
break; break;
case BPF_S_ALU_OR_X: case BPF_ALU | BPF_OR | BPF_X:
/* A |= X */ /* A |= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_ori(r_A, r_A, r_X, ctx); emit_ori(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_XOR_K: case BPF_ALU | BPF_XOR | BPF_K:
/* A ^= k */ /* A ^= k */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_xori(r_A, r_A, k, ctx); emit_xori(r_A, r_A, k, ctx);
break; break;
case BPF_S_ANC_ALU_XOR_X: case BPF_ANC | SKF_AD_ALU_XOR_X:
case BPF_S_ALU_XOR_X: case BPF_ALU | BPF_XOR | BPF_X:
/* A ^= X */ /* A ^= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_xor(r_A, r_A, r_X, ctx); emit_xor(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_AND_K: case BPF_ALU | BPF_AND | BPF_K:
/* A &= K */ /* A &= K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_andi(r_A, r_A, k, ctx); emit_andi(r_A, r_A, k, ctx);
break; break;
case BPF_S_ALU_AND_X: case BPF_ALU | BPF_AND | BPF_X:
/* A &= X */ /* A &= X */
update_on_xread(ctx); update_on_xread(ctx);
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
emit_and(r_A, r_A, r_X, ctx); emit_and(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_LSH_K: case BPF_ALU | BPF_LSH | BPF_K:
/* A <<= K */ /* A <<= K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_sll(r_A, r_A, k, ctx); emit_sll(r_A, r_A, k, ctx);
break; break;
case BPF_S_ALU_LSH_X: case BPF_ALU | BPF_LSH | BPF_X:
/* A <<= X */ /* A <<= X */
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
update_on_xread(ctx); update_on_xread(ctx);
emit_sllv(r_A, r_A, r_X, ctx); emit_sllv(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_RSH_K: case BPF_ALU | BPF_RSH | BPF_K:
/* A >>= K */ /* A >>= K */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_srl(r_A, r_A, k, ctx); emit_srl(r_A, r_A, k, ctx);
break; break;
case BPF_S_ALU_RSH_X: case BPF_ALU | BPF_RSH | BPF_X:
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
update_on_xread(ctx); update_on_xread(ctx);
emit_srlv(r_A, r_A, r_X, ctx); emit_srlv(r_A, r_A, r_X, ctx);
break; break;
case BPF_S_ALU_NEG: case BPF_ALU | BPF_NEG:
/* A = -A */ /* A = -A */
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
emit_neg(r_A, ctx); emit_neg(r_A, ctx);
break; break;
case BPF_S_JMP_JA: case BPF_JMP | BPF_JA:
/* pc += K */ /* pc += K */
emit_b(b_imm(i + k + 1, ctx), ctx); emit_b(b_imm(i + k + 1, ctx), ctx);
emit_nop(ctx); emit_nop(ctx);
break; break;
case BPF_S_JMP_JEQ_K: case BPF_JMP | BPF_JEQ | BPF_K:
/* pc += ( A == K ) ? pc->jt : pc->jf */ /* pc += ( A == K ) ? pc->jt : pc->jf */
condt = MIPS_COND_EQ | MIPS_COND_K; condt = MIPS_COND_EQ | MIPS_COND_K;
goto jmp_cmp; goto jmp_cmp;
case BPF_S_JMP_JEQ_X: case BPF_JMP | BPF_JEQ | BPF_X:
ctx->flags |= SEEN_X; ctx->flags |= SEEN_X;
/* pc += ( A == X ) ? pc->jt : pc->jf */ /* pc += ( A == X ) ? pc->jt : pc->jf */
condt = MIPS_COND_EQ | MIPS_COND_X; condt = MIPS_COND_EQ | MIPS_COND_X;
goto jmp_cmp; goto jmp_cmp;
case BPF_S_JMP_JGE_K: case BPF_JMP | BPF_JGE | BPF_K:
/* pc += ( A >= K ) ? pc->jt : pc->jf */ /* pc += ( A >= K ) ? pc->jt : pc->jf */
condt = MIPS_COND_GE | MIPS_COND_K; condt = MIPS_COND_GE | MIPS_COND_K;
goto jmp_cmp; goto jmp_cmp;
case BPF_S_JMP_JGE_X: case BPF_JMP | BPF_JGE | BPF_X:
ctx->flags |= SEEN_X; ctx->flags |= SEEN_X;
/* pc += ( A >= X ) ? pc->jt : pc->jf */ /* pc += ( A >= X ) ? pc->jt : pc->jf */
condt = MIPS_COND_GE | MIPS_COND_X; condt = MIPS_COND_GE | MIPS_COND_X;
goto jmp_cmp; goto jmp_cmp;
case BPF_S_JMP_JGT_K: case BPF_JMP | BPF_JGT | BPF_K:
/* pc += ( A > K ) ? pc->jt : pc->jf */ /* pc += ( A > K ) ? pc->jt : pc->jf */
condt = MIPS_COND_GT | MIPS_COND_K; condt = MIPS_COND_GT | MIPS_COND_K;
goto jmp_cmp; goto jmp_cmp;
case BPF_S_JMP_JGT_X: case BPF_JMP | BPF_JGT | BPF_X:
ctx->flags |= SEEN_X; ctx->flags |= SEEN_X;
/* pc += ( A > X ) ? pc->jt : pc->jf */ /* pc += ( A > X ) ? pc->jt : pc->jf */
condt = MIPS_COND_GT | MIPS_COND_X; condt = MIPS_COND_GT | MIPS_COND_X;
...@@ -1167,7 +1162,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1167,7 +1162,7 @@ static int build_body(struct jit_ctx *ctx)
} }
} }
break; break;
case BPF_S_JMP_JSET_K: case BPF_JMP | BPF_JSET | BPF_K:
ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A; ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A;
/* pc += (A & K) ? pc -> jt : pc -> jf */ /* pc += (A & K) ? pc -> jt : pc -> jf */
emit_load_imm(r_s1, k, ctx); emit_load_imm(r_s1, k, ctx);
...@@ -1181,7 +1176,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1181,7 +1176,7 @@ static int build_body(struct jit_ctx *ctx)
emit_b(b_off, ctx); emit_b(b_off, ctx);
emit_nop(ctx); emit_nop(ctx);
break; break;
case BPF_S_JMP_JSET_X: case BPF_JMP | BPF_JSET | BPF_X:
ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A; ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A;
/* pc += (A & X) ? pc -> jt : pc -> jf */ /* pc += (A & X) ? pc -> jt : pc -> jf */
emit_and(r_s0, r_A, r_X, ctx); emit_and(r_s0, r_A, r_X, ctx);
...@@ -1194,7 +1189,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1194,7 +1189,7 @@ static int build_body(struct jit_ctx *ctx)
emit_b(b_off, ctx); emit_b(b_off, ctx);
emit_nop(ctx); emit_nop(ctx);
break; break;
case BPF_S_RET_A: case BPF_RET | BPF_A:
ctx->flags |= SEEN_A; ctx->flags |= SEEN_A;
if (i != prog->len - 1) if (i != prog->len - 1)
/* /*
...@@ -1204,7 +1199,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1204,7 +1199,7 @@ static int build_body(struct jit_ctx *ctx)
emit_b(b_imm(prog->len, ctx), ctx); emit_b(b_imm(prog->len, ctx), ctx);
emit_reg_move(r_ret, r_A, ctx); /* delay slot */ emit_reg_move(r_ret, r_A, ctx); /* delay slot */
break; break;
case BPF_S_RET_K: case BPF_RET | BPF_K:
/* /*
* It can emit two instructions so it does not fit on * It can emit two instructions so it does not fit on
* the delay slot. * the delay slot.
...@@ -1219,19 +1214,19 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1219,19 +1214,19 @@ static int build_body(struct jit_ctx *ctx)
emit_nop(ctx); emit_nop(ctx);
} }
break; break;
case BPF_S_MISC_TAX: case BPF_MISC | BPF_TAX:
/* X = A */ /* X = A */
ctx->flags |= SEEN_X | SEEN_A; ctx->flags |= SEEN_X | SEEN_A;
emit_jit_reg_move(r_X, r_A, ctx); emit_jit_reg_move(r_X, r_A, ctx);
break; break;
case BPF_S_MISC_TXA: case BPF_MISC | BPF_TXA:
/* A = X */ /* A = X */
ctx->flags |= SEEN_A | SEEN_X; ctx->flags |= SEEN_A | SEEN_X;
update_on_xread(ctx); update_on_xread(ctx);
emit_jit_reg_move(r_A, r_X, ctx); emit_jit_reg_move(r_A, r_X, ctx);
break; break;
/* AUX */ /* AUX */
case BPF_S_ANC_PROTOCOL: case BPF_ANC | SKF_AD_PROTOCOL:
/* A = ntohs(skb->protocol */ /* A = ntohs(skb->protocol */
ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_OFF | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
...@@ -1256,7 +1251,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1256,7 +1251,7 @@ static int build_body(struct jit_ctx *ctx)
} }
#endif #endif
break; break;
case BPF_S_ANC_CPU: case BPF_ANC | SKF_AD_CPU:
ctx->flags |= SEEN_A | SEEN_OFF; ctx->flags |= SEEN_A | SEEN_OFF;
/* A = current_thread_info()->cpu */ /* A = current_thread_info()->cpu */
BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info, BUILD_BUG_ON(FIELD_SIZEOF(struct thread_info,
...@@ -1265,7 +1260,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1265,7 +1260,7 @@ static int build_body(struct jit_ctx *ctx)
/* $28/gp points to the thread_info struct */ /* $28/gp points to the thread_info struct */
emit_load(r_A, 28, off, ctx); emit_load(r_A, 28, off, ctx);
break; break;
case BPF_S_ANC_IFINDEX: case BPF_ANC | SKF_AD_IFINDEX:
/* A = skb->dev->ifindex */ /* A = skb->dev->ifindex */
ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0; ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0;
off = offsetof(struct sk_buff, dev); off = offsetof(struct sk_buff, dev);
...@@ -1279,31 +1274,31 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1279,31 +1274,31 @@ static int build_body(struct jit_ctx *ctx)
off = offsetof(struct net_device, ifindex); off = offsetof(struct net_device, ifindex);
emit_load(r_A, r_s0, off, ctx); emit_load(r_A, r_s0, off, ctx);
break; break;
case BPF_S_ANC_MARK: case BPF_ANC | SKF_AD_MARK:
ctx->flags |= SEEN_SKB | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4); BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, mark) != 4);
off = offsetof(struct sk_buff, mark); off = offsetof(struct sk_buff, mark);
emit_load(r_A, r_skb, off, ctx); emit_load(r_A, r_skb, off, ctx);
break; break;
case BPF_S_ANC_RXHASH: case BPF_ANC | SKF_AD_RXHASH:
ctx->flags |= SEEN_SKB | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4); BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, hash) != 4);
off = offsetof(struct sk_buff, hash); off = offsetof(struct sk_buff, hash);
emit_load(r_A, r_skb, off, ctx); emit_load(r_A, r_skb, off, ctx);
break; break;
case BPF_S_ANC_VLAN_TAG: case BPF_ANC | SKF_AD_VLAN_TAG:
case BPF_S_ANC_VLAN_TAG_PRESENT: case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
vlan_tci) != 2); vlan_tci) != 2);
off = offsetof(struct sk_buff, vlan_tci); off = offsetof(struct sk_buff, vlan_tci);
emit_half_load(r_s0, r_skb, off, ctx); emit_half_load(r_s0, r_skb, off, ctx);
if (inst->code == BPF_S_ANC_VLAN_TAG) if (code == (BPF_ANC | SKF_AD_VLAN_TAG))
emit_and(r_A, r_s0, VLAN_VID_MASK, ctx); emit_and(r_A, r_s0, VLAN_VID_MASK, ctx);
else else
emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx); emit_and(r_A, r_s0, VLAN_TAG_PRESENT, ctx);
break; break;
case BPF_S_ANC_PKTTYPE: case BPF_ANC | SKF_AD_PKTTYPE:
off = pkt_type_offset(); off = pkt_type_offset();
if (off < 0) if (off < 0)
...@@ -1312,7 +1307,7 @@ static int build_body(struct jit_ctx *ctx) ...@@ -1312,7 +1307,7 @@ static int build_body(struct jit_ctx *ctx)
/* Keep only the last 3 bits */ /* Keep only the last 3 bits */
emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx); emit_andi(r_A, r_tmp, PKT_TYPE_MAX, ctx);
break; break;
case BPF_S_ANC_QUEUE: case BPF_ANC | SKF_AD_QUEUE:
ctx->flags |= SEEN_SKB | SEEN_A; ctx->flags |= SEEN_SKB | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff, BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
queue_mapping) != 2); queue_mapping) != 2);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册