bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: net: bpf: improve endian conversion
@ 2019-12-09 11:17 Russell King
  0 siblings, 0 replies; only message in thread
From: Russell King @ 2019-12-09 11:17 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: Shubham Bansal, Alexei Starovoitov, Martin KaFai Lau, Song Liu,
	Yonghong Song, Andrii Nakryiko, netdev, bpf, linux-arm-kernel

Make the endian conversion function easier to read by moving it out
of the big switch, and avoid doing anything if we're requested to
convert from a 64-bit LE value (we're LE anyway here.)

Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
 arch/arm/net/bpf_jit_32.c | 91 +++++++++++++++++++++------------------
 1 file changed, 50 insertions(+), 41 deletions(-)

diff --git a/arch/arm/net/bpf_jit_32.c b/arch/arm/net/bpf_jit_32.c
index cc29869d12a3..646ab5785ca4 100644
--- a/arch/arm/net/bpf_jit_32.c
+++ b/arch/arm/net/bpf_jit_32.c
@@ -1245,6 +1245,55 @@ static inline void emit_rev32(const u8 rd, const u8 rn, struct jit_ctx *ctx)
 #endif
 }
 
+static void emit_a32_endian(const s8 dst[], u8 code, s32 bits,
+			    struct jit_ctx *ctx)
+{
+	const s8 *tmp = bpf2a32[TMP_REG_1];
+	const s8 *tmp2 = bpf2a32[TMP_REG_2];
+	const s8 *rd;
+
+	/* Converting from LE and 64-bit value is a no-op. */
+	if (code == BPF_FROM_LE && bits == 64)
+		return;
+
+	rd = arm_bpf_get_reg64(dst, tmp, ctx);
+
+	if (code != BPF_FROM_LE) {
+		/* endian swap */
+		switch (imm) {
+		case 16:
+			emit_rev16(rd[1], rd[1], ctx);
+			break;
+		case 32:
+			emit_rev32(rd[1], rd[1], ctx);
+			break;
+		case 64:
+			emit_rev32(ARM_LR, rd[1], ctx);
+			emit_rev32(rd[1], rd[0], ctx);
+			emit(ARM_MOV_R(rd[0], ARM_LR), ctx);
+			break;
+		}
+	}
+
+	/* zero-extend size to 64-bit */
+	switch (imm) {
+	case 16:
+#if __LINUX_ARM_ARCH__ < 6
+		emit_a32_mov_i(tmp2[1], 0xffff, ctx);
+		emit(ARM_AND_R(rd[1], rd[1], tmp2[1]), ctx);
+#else /* ARMv6+ */
+		emit(ARM_UXTH(rd[1], rd[1]), ctx);
+#endif
+		/* FALLTHROUGH */
+	case 32:
+		if (!ctx->prog->aux->verifier_zext)
+			emit(ARM_MOV_I(rd[0], 0), ctx);
+		break;
+	}
+
+	arm_bpf_put_reg64(dst, rd, ctx);
+}
+
 // push the scratch stack register on top of the stack
 static inline void emit_push_r64(const s8 src[], struct jit_ctx *ctx)
 {
@@ -1523,47 +1572,7 @@ static int build_insn(const struct bpf_insn *insn, struct jit_ctx *ctx)
 	/* dst = htobe(dst) */
 	case BPF_ALU | BPF_END | BPF_FROM_LE:
 	case BPF_ALU | BPF_END | BPF_FROM_BE:
-		rd = arm_bpf_get_reg64(dst, tmp, ctx);
-		if (BPF_SRC(code) == BPF_FROM_LE)
-			goto emit_bswap_uxt;
-		switch (imm) {
-		case 16:
-			emit_rev16(rd[1], rd[1], ctx);
-			goto emit_bswap_uxt;
-		case 32:
-			emit_rev32(rd[1], rd[1], ctx);
-			goto emit_bswap_uxt;
-		case 64:
-			emit_rev32(ARM_LR, rd[1], ctx);
-			emit_rev32(rd[1], rd[0], ctx);
-			emit(ARM_MOV_R(rd[0], ARM_LR), ctx);
-			break;
-		}
-		goto exit;
-emit_bswap_uxt:
-		switch (imm) {
-		case 16:
-			/* zero-extend 16 bits into 64 bits */
-#if __LINUX_ARM_ARCH__ < 6
-			emit_a32_mov_i(tmp2[1], 0xffff, ctx);
-			emit(ARM_AND_R(rd[1], rd[1], tmp2[1]), ctx);
-#else /* ARMv6+ */
-			emit(ARM_UXTH(rd[1], rd[1]), ctx);
-#endif
-			if (!ctx->prog->aux->verifier_zext)
-				emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
-			break;
-		case 32:
-			/* zero-extend 32 bits into 64 bits */
-			if (!ctx->prog->aux->verifier_zext)
-				emit(ARM_EOR_R(rd[0], rd[0], rd[0]), ctx);
-			break;
-		case 64:
-			/* nop */
-			break;
-		}
-exit:
-		arm_bpf_put_reg64(dst, rd, ctx);
+		emit_a32_endian(dst, BPF_SRC(code), imm, ctx);
 		break;
 	/* dst = imm64 */
 	case BPF_LD | BPF_IMM | BPF_DW:
-- 
2.20.1


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2019-12-09 11:17 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-09 11:17 [PATCH] ARM: net: bpf: improve endian conversion Russell King

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).