All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yonghong Song <yhs@fb.com>
To: <bpf@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>,
	Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Fangrui Song <maskray@google.com>, <kernel-team@fb.com>
Subject: [PATCH bpf-next v2 05/15] bpf: Support new signed div/mod instructions.
Date: Wed, 12 Jul 2023 23:07:44 -0700	[thread overview]
Message-ID: <20230713060744.390929-1-yhs@fb.com> (raw)
In-Reply-To: <20230713060718.388258-1-yhs@fb.com>

Add interpreter/jit support for new signed div/mod insns.
The new signed div/mod instructions are encoded with
unsigned div/mod instructions plus insn->off == 1.
Also add basic verifier support to ensure new insns get
accepted.

Signed-off-by: Yonghong Song <yhs@fb.com>
---
 arch/x86/net/bpf_jit_comp.c | 27 +++++++----
 kernel/bpf/core.c           | 96 ++++++++++++++++++++++++++++++-------
 kernel/bpf/verifier.c       |  6 ++-
 3 files changed, 103 insertions(+), 26 deletions(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index adda5e7626b4..3176b60d25c7 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -1194,15 +1194,26 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image, u8 *rw_image
 				/* mov rax, dst_reg */
 				emit_mov_reg(&prog, is64, BPF_REG_0, dst_reg);
 
-			/*
-			 * xor edx, edx
-			 * equivalent to 'xor rdx, rdx', but one byte less
-			 */
-			EMIT2(0x31, 0xd2);
+			if (insn->off == 0) {
+				/*
+				 * xor edx, edx
+				 * equivalent to 'xor rdx, rdx', but one byte less
+				 */
+				EMIT2(0x31, 0xd2);
 
-			/* div src_reg */
-			maybe_emit_1mod(&prog, src_reg, is64);
-			EMIT2(0xF7, add_1reg(0xF0, src_reg));
+				/* div src_reg */
+				maybe_emit_1mod(&prog, src_reg, is64);
+				EMIT2(0xF7, add_1reg(0xF0, src_reg));
+			} else {
+				if (BPF_CLASS(insn->code) == BPF_ALU)
+					EMIT1(0x99); /* cltd */
+				else
+					EMIT2(0x48, 0x99); /* cqto */
+
+				/* idiv src_reg */
+				maybe_emit_1mod(&prog, src_reg, is64);
+				EMIT2(0xF7, add_1reg(0xF8, src_reg));
+			}
 
 			if (BPF_OP(insn->code) == BPF_MOD &&
 			    dst_reg != BPF_REG_3)
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 86bb412fee39..6f7134657935 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -1789,36 +1789,100 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)
 		(*(s64 *) &DST) >>= IMM;
 		CONT;
 	ALU64_MOD_X:
-		div64_u64_rem(DST, SRC, &AX);
-		DST = AX;
+		switch (OFF) {
+		case 0:
+			div64_u64_rem(DST, SRC, &AX);
+			DST = AX;
+			break;
+		case 1:
+			AX = div64_s64(DST, SRC);
+			DST = DST - AX * SRC;
+			break;
+		}
 		CONT;
 	ALU_MOD_X:
-		AX = (u32) DST;
-		DST = do_div(AX, (u32) SRC);
+		switch (OFF) {
+		case 0:
+			AX = (u32) DST;
+			DST = do_div(AX, (u32) SRC);
+			break;
+		case 1:
+			AX = (s32) DST;
+			DST = (u32)do_div(AX, (s32) SRC);
+			break;
+		}
 		CONT;
 	ALU64_MOD_K:
-		div64_u64_rem(DST, IMM, &AX);
-		DST = AX;
+		switch (OFF) {
+		case 0:
+			div64_u64_rem(DST, IMM, &AX);
+			DST = AX;
+			break;
+		case 1:
+			AX = div64_s64(DST, IMM);
+			DST = DST - AX * IMM;
+			break;
+		}
 		CONT;
 	ALU_MOD_K:
-		AX = (u32) DST;
-		DST = do_div(AX, (u32) IMM);
+		switch (OFF) {
+		case 0:
+			AX = (u32) DST;
+			DST = do_div(AX, (u32) IMM);
+			break;
+		case 1:
+			AX = (s32) DST;
+			DST = (u32)do_div(AX, (s32) IMM);
+			break;
+		}
 		CONT;
 	ALU64_DIV_X:
-		DST = div64_u64(DST, SRC);
+		switch (OFF) {
+		case 0:
+			DST = div64_u64(DST, SRC);
+			break;
+		case 1:
+			DST = div64_s64(DST, SRC);
+			break;
+		}
 		CONT;
 	ALU_DIV_X:
-		AX = (u32) DST;
-		do_div(AX, (u32) SRC);
-		DST = (u32) AX;
+		switch (OFF) {
+		case 0:
+			AX = (u32) DST;
+			do_div(AX, (u32) SRC);
+			DST = (u32) AX;
+			break;
+		case 1:
+			AX = (s32) DST;
+			do_div(AX, (s32) SRC);
+			DST = (u32) AX;
+			break;
+		}
 		CONT;
 	ALU64_DIV_K:
-		DST = div64_u64(DST, IMM);
+		switch (OFF) {
+		case 0:
+			DST = div64_u64(DST, IMM);
+			break;
+		case 1:
+			DST = div64_s64(DST, IMM);
+			break;
+		}
 		CONT;
 	ALU_DIV_K:
-		AX = (u32) DST;
-		do_div(AX, (u32) IMM);
-		DST = (u32) AX;
+		switch (OFF) {
+		case 0:
+			AX = (u32) DST;
+			do_div(AX, (u32) IMM);
+			DST = (u32) AX;
+			break;
+		case 1:
+			AX = (s32) DST;
+			do_div(AX, (s32) IMM);
+			DST = (u32) AX;
+			break;
+		}
 		CONT;
 	ALU_END_TO_BE:
 		switch (IMM) {
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 22ba0744547b..b606c8ed5470 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13192,7 +13192,8 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
 	} else {	/* all other ALU ops: and, sub, xor, add, ... */
 
 		if (BPF_SRC(insn->code) == BPF_X) {
-			if (insn->imm != 0 || insn->off != 0) {
+			if (insn->imm != 0 || insn->off > 1 ||
+			    (insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
 				verbose(env, "BPF_ALU uses reserved fields\n");
 				return -EINVAL;
 			}
@@ -13201,7 +13202,8 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
 			if (err)
 				return err;
 		} else {
-			if (insn->src_reg != BPF_REG_0 || insn->off != 0) {
+			if (insn->src_reg != BPF_REG_0 || insn->off > 1 ||
+			    (insn->off == 1 && opcode != BPF_MOD && opcode != BPF_DIV)) {
 				verbose(env, "BPF_ALU uses reserved fields\n");
 				return -EINVAL;
 			}
-- 
2.34.1


  parent reply	other threads:[~2023-07-13  6:08 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-07-13  6:07 [PATCH bpf-next v2 00/15] bpf: Support new insns from cpu v4 Yonghong Song
2023-07-13  6:07 ` [PATCH bpf-next v2 01/15] bpf: Support new sign-extension load insns Yonghong Song
2023-07-14 18:13   ` Alexei Starovoitov
2023-07-14 23:22     ` Yonghong Song
2023-07-17  1:39   ` Eduard Zingerman
2023-07-19  0:15   ` Eduard Zingerman
2023-07-19  2:28     ` Yonghong Song
2023-07-13  6:07 ` [PATCH bpf-next v2 02/15] bpf: Fix sign-extension ctx member accesses Yonghong Song
2023-07-17  1:40   ` Eduard Zingerman
2023-07-19  0:40     ` Yonghong Song
2023-07-13  6:07 ` [PATCH bpf-next v2 03/15] bpf: Support new sign-extension mov insns Yonghong Song
2023-07-17  1:41   ` Eduard Zingerman
2023-07-19  1:17     ` Yonghong Song
2023-07-19 12:53       ` Eduard Zingerman
2023-07-19 15:59         ` Fangrui Song
2023-07-19 16:57           ` Eduard Zingerman
2023-07-13  6:07 ` [PATCH bpf-next v2 04/15] bpf: Support new unconditional bswap instruction Yonghong Song
2023-07-17  1:42   ` Eduard Zingerman
2023-07-19  1:22     ` Yonghong Song
2023-07-13  6:07 ` Yonghong Song [this message]
2023-07-18 23:00   ` [PATCH bpf-next v2 05/15] bpf: Support new signed div/mod instructions Eduard Zingerman
2023-07-19  2:30     ` Yonghong Song
2023-07-19  2:44       ` Alexei Starovoitov
2023-07-19  6:57         ` Yonghong Song
2023-07-13  6:07 ` [PATCH bpf-next v2 06/15] bpf: Fix jit blinding with new sdiv/smov insns Yonghong Song
2023-07-13  6:07 ` [PATCH bpf-next v2 07/15] bpf: Support new 32bit offset jmp instruction Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 08/15] selftests/bpf: Add a cpuv4 test runner for cpu=v4 testing Yonghong Song
2023-07-13  6:18   ` Fangrui Song
2023-07-13  6:25     ` Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 09/15] selftests/bpf: Add unit tests for new sign-extension load insns Yonghong Song
2023-07-18 23:06   ` Eduard Zingerman
2023-07-13  6:08 ` [PATCH bpf-next v2 10/15] selftests/bpf: Add unit tests for new sign-extension mov insns Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 11/15] selftests/bpf: Add unit tests for new bswap insns Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 12/15] selftests/bpf: Add unit tests for new sdiv/smod insns Yonghong Song
2023-07-18 23:10   ` Eduard Zingerman
2023-07-13  6:08 ` [PATCH bpf-next v2 13/15] selftests/bpf: Add unit tests for new gotol insn Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 14/15] selftests/bpf: Test ldsx with more complex cases Yonghong Song
2023-07-13  6:08 ` [PATCH bpf-next v2 15/15] docs/bpf: Add documentation for new instructions Yonghong Song
2023-07-14 18:28   ` Alexei Starovoitov
2023-07-14 23:26     ` Yonghong Song
2023-07-14 23:33   ` Dave Thaler
2023-07-14 23:33     ` [Bpf] " Dave Thaler
2023-07-15  0:23     ` Alexei Starovoitov
2023-07-15  0:23       ` [Bpf] " Alexei Starovoitov
2023-07-14 23:34   ` Dave Thaler
2023-07-14 23:34     ` [Bpf] " Dave Thaler
2023-07-17  1:39 ` [PATCH bpf-next v2 00/15] bpf: Support new insns from cpu v4 Eduard Zingerman
2023-07-17 16:56   ` Alexei Starovoitov
2023-07-17 17:04     ` Eduard Zingerman
2023-07-17 21:52   ` Yonghong Song
2023-07-21 14:56     ` Jose E. Marchesi
2023-07-24  0:17       ` Jose E. Marchesi
2023-07-24  1:04         ` Jose E. Marchesi
2023-07-24  2:35           ` Yonghong Song

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230713060744.390929-1-yhs@fb.com \
    --to=yhs@fb.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=kernel-team@fb.com \
    --cc=maskray@google.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.