Skip to content

Commit

Permalink
MIPS: BPF: Free up some callee-saved registers
Browse files Browse the repository at this point in the history
Move the two scratch registers from s0 and s1 to t4 and t5 in order
to free up some callee-saved registers. We will use these callee-saved
registers to store some permanent data on them in a subsequent patch.

Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Cc: netdev@vger.kernel.org
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Daniel Borkmann <dborkman@redhat.com>
Cc: Hannes Frederic Sowa <hannes@stressinduktion.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-mips@linux-mips.org
Patchwork: http://patchwork.linux-mips.org/patch/10525/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
Markos Chandras authored and Ralf Baechle committed Jun 21, 2015
1 parent de5792a commit ad152bd
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 20 deletions.
35 changes: 15 additions & 20 deletions arch/mips/net/bpf_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,6 @@

/* ABI
*
* s0 1st scratch register
* s1 2nd scratch register
* s2 offset register
* s3 BPF register A
* s4 BPF register X
* s5 *skb
Expand Down Expand Up @@ -88,13 +85,13 @@
* any of the $s0-$s6 registers will only be preserved if
* they are going to actually be used.
*/
#define r_s0 MIPS_R_S0 /* scratch reg 1 */
#define r_s1 MIPS_R_S1 /* scratch reg 2 */
#define r_off MIPS_R_S2
#define r_A MIPS_R_S3
#define r_X MIPS_R_S4
#define r_skb MIPS_R_S5
#define r_M MIPS_R_S6
#define r_s0 MIPS_R_T4 /* scratch reg 1 */
#define r_s1 MIPS_R_T5 /* scratch reg 2 */
#define r_tmp_imm MIPS_R_T6 /* No need to preserve this */
#define r_tmp MIPS_R_T7 /* No need to preserve this */
#define r_zero MIPS_R_ZERO
Expand All @@ -108,8 +105,6 @@
#define SEEN_SREG_SFT (BPF_MEMWORDS + 1)
#define SEEN_SREG_BASE (1 << SEEN_SREG_SFT)
#define SEEN_SREG(x) (SEEN_SREG_BASE << (x))
#define SEEN_S0 SEEN_SREG(0)
#define SEEN_S1 SEEN_SREG(1)
#define SEEN_OFF SEEN_SREG(2)
#define SEEN_A SEEN_SREG(3)
#define SEEN_X SEEN_SREG(4)
Expand Down Expand Up @@ -813,7 +808,7 @@ static int build_body(struct jit_ctx *ctx)
b_imm(prog->len, ctx), ctx);
emit_reg_move(r_ret, r_zero, ctx);

ctx->flags |= SEEN_CALL | SEEN_OFF | SEEN_S0 |
ctx->flags |= SEEN_CALL | SEEN_OFF |
SEEN_SKB | SEEN_A;

emit_load_func(r_s0, (ptr)load_func[load_order],
Expand Down Expand Up @@ -879,7 +874,7 @@ static int build_body(struct jit_ctx *ctx)
return -ENOTSUPP;

/* X <- 4 * (P[k:1] & 0xf) */
ctx->flags |= SEEN_X | SEEN_CALL | SEEN_S0 | SEEN_SKB;
ctx->flags |= SEEN_X | SEEN_CALL | SEEN_SKB;
/* Load offset to a1 */
emit_load_func(r_s0, (ptr)jit_get_skb_b, ctx);
/*
Expand Down Expand Up @@ -943,7 +938,7 @@ static int build_body(struct jit_ctx *ctx)
case BPF_ALU | BPF_MUL | BPF_K:
/* A *= K */
/* Load K to scratch register before MUL */
ctx->flags |= SEEN_A | SEEN_S0;
ctx->flags |= SEEN_A;
emit_load_imm(r_s0, k, ctx);
emit_mul(r_A, r_A, r_s0, ctx);
break;
Expand All @@ -961,7 +956,7 @@ static int build_body(struct jit_ctx *ctx)
emit_srl(r_A, r_A, k, ctx);
break;
}
ctx->flags |= SEEN_A | SEEN_S0;
ctx->flags |= SEEN_A;
emit_load_imm(r_s0, k, ctx);
emit_div(r_A, r_s0, ctx);
break;
Expand All @@ -971,7 +966,7 @@ static int build_body(struct jit_ctx *ctx)
ctx->flags |= SEEN_A;
emit_jit_reg_move(r_A, r_zero, ctx);
} else {
ctx->flags |= SEEN_A | SEEN_S0;
ctx->flags |= SEEN_A;
emit_load_imm(r_s0, k, ctx);
emit_mod(r_A, r_s0, ctx);
}
Expand Down Expand Up @@ -1085,10 +1080,10 @@ static int build_body(struct jit_ctx *ctx)
if ((condt & MIPS_COND_GE) ||
(condt & MIPS_COND_GT)) {
if (condt & MIPS_COND_K) { /* K */
ctx->flags |= SEEN_S0 | SEEN_A;
ctx->flags |= SEEN_A;
emit_sltiu(r_s0, r_A, k, ctx);
} else { /* X */
ctx->flags |= SEEN_S0 | SEEN_A |
ctx->flags |= SEEN_A |
SEEN_X;
emit_sltu(r_s0, r_A, r_X, ctx);
}
Expand All @@ -1100,7 +1095,7 @@ static int build_body(struct jit_ctx *ctx)
/* A > (K|X) ? scratch = 0 */
if (condt & MIPS_COND_GT) {
/* Checking for equality */
ctx->flags |= SEEN_S0 | SEEN_A | SEEN_X;
ctx->flags |= SEEN_A | SEEN_X;
if (condt & MIPS_COND_K)
emit_load_imm(r_s0, k, ctx);
else
Expand All @@ -1123,7 +1118,7 @@ static int build_body(struct jit_ctx *ctx)
} else {
/* A == K|X */
if (condt & MIPS_COND_K) { /* K */
ctx->flags |= SEEN_S0 | SEEN_A;
ctx->flags |= SEEN_A;
emit_load_imm(r_s0, k, ctx);
/* jump true */
b_off = b_imm(i + inst->jt + 1, ctx);
Expand Down Expand Up @@ -1153,7 +1148,7 @@ static int build_body(struct jit_ctx *ctx)
}
break;
case BPF_JMP | BPF_JSET | BPF_K:
ctx->flags |= SEEN_S0 | SEEN_S1 | SEEN_A;
ctx->flags |= SEEN_A;
/* pc += (A & K) ? pc -> jt : pc -> jf */
emit_load_imm(r_s1, k, ctx);
emit_and(r_s0, r_A, r_s1, ctx);
Expand All @@ -1167,7 +1162,7 @@ static int build_body(struct jit_ctx *ctx)
emit_nop(ctx);
break;
case BPF_JMP | BPF_JSET | BPF_X:
ctx->flags |= SEEN_S0 | SEEN_X | SEEN_A;
ctx->flags |= SEEN_X | SEEN_A;
/* pc += (A & X) ? pc -> jt : pc -> jf */
emit_and(r_s0, r_A, r_X, ctx);
/* jump true */
Expand Down Expand Up @@ -1251,7 +1246,7 @@ static int build_body(struct jit_ctx *ctx)
break;
case BPF_ANC | SKF_AD_IFINDEX:
/* A = skb->dev->ifindex */
ctx->flags |= SEEN_SKB | SEEN_A | SEEN_S0;
ctx->flags |= SEEN_SKB | SEEN_A;
off = offsetof(struct sk_buff, dev);
/* Load *dev pointer */
emit_load_ptr(r_s0, r_skb, off, ctx);
Expand All @@ -1278,7 +1273,7 @@ static int build_body(struct jit_ctx *ctx)
break;
case BPF_ANC | SKF_AD_VLAN_TAG:
case BPF_ANC | SKF_AD_VLAN_TAG_PRESENT:
ctx->flags |= SEEN_SKB | SEEN_S0 | SEEN_A;
ctx->flags |= SEEN_SKB | SEEN_A;
BUILD_BUG_ON(FIELD_SIZEOF(struct sk_buff,
vlan_tci) != 2);
off = offsetof(struct sk_buff, vlan_tci);
Expand Down
2 changes: 2 additions & 0 deletions arch/mips/net/bpf_jit.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#define MIPS_R_V1 3
#define MIPS_R_A0 4
#define MIPS_R_A1 5
#define MIPS_R_T4 12
#define MIPS_R_T5 13
#define MIPS_R_T6 14
#define MIPS_R_T7 15
#define MIPS_R_S0 16
Expand Down

0 comments on commit ad152bd

Please sign in to comment.