Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ad152bd6 authored by Markos Chandras's avatar Markos Chandras Committed by Ralf Baechle
Browse files

MIPS: BPF: Free up some callee-saved registers



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: default avatarMarkos 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: default avatarRalf Baechle <ralf@linux-mips.org>
parent de5792a4
Loading
Loading
Loading
Loading
+15 −20
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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)
@@ -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],
@@ -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);
			/*
@@ -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;
@@ -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;
@@ -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);
			}
@@ -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);
				}
@@ -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
@@ -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);
@@ -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);
@@ -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 */
@@ -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);
@@ -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);
+2 −0
Original line number Diff line number Diff line
@@ -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