* [PATCH bpf-next v2] bpf, mips: Add BPF_MEMSX support to the JITs
@ 2026-09-12 18:06 Nicholas Dudar
0 siblings, 0 replies; only message in thread
From: Nicholas Dudar @ 2026-09-12 18:06 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, memxor, johan.almbladh, paulburton,
tsbogend
Cc: martin.lau, song, yonghong.song, jolsa, emil, ihor.solodrai, bpf,
linux-mips, linux-kernel
The MIPS JITs reject BPF_MEMSX loads, preventing programs that use them
from running where JIT compilation is required.
Codex-assisted analysis of public test output identified the missing
MEMSX support.
Add signed byte, half-word and word loads using lb, lh and lw. On
MIPS64 these produce the full result. On MIPS32, propagate the loaded
word's sign into the high word after the required load delay. Keep
signed loads separate from ordinary loads, which can clear the high
word in the load-delay slot.
Suggested-by: Johan Almbladh <johan.almbladh@anyfinetworks.com>
Assisted-by: Codex:gpt-6
Signed-off-by: Nicholas Dudar <main.kalliope@gmail.com>
---
Changes in v2:
- Keep unsigned LDX and signed LDSX as separate complete emitters.
- Drop the helper-only preparatory patch from v1.
This patch depends on SDIV/SMOD v4 and MOVSX v3, in that order.
Enabling MEMSX lets mixed programs reach JIT execution, so their
signed arithmetic and register moves must also be implemented.
https://lore.kernel.org/bpf/20260911213340.3767930-1-main.kalliope@gmail.com/
https://lore.kernel.org/bpf/20260912041220.444715-1-main.kalliope@gmail.com/
I ran the full test_bpf suite on both the prerequisite stack and this patch
under QEMU Malta, using little-endian MIPS32 R2 and MIPS64 R2. An out-of-tree
fixture strengthens the signed/unsigned load comparisons and adds negative
and sign-clear loads with dst == src. All five MEMSX tests move from JIT
rejection to passing: MIPS32 goes from 1050/14 to 1055/9 pass/fail, and
MIPS64 from 1049/14 to 1054/9. The remaining failures are 8 BSWAP and
1 JMP32_JA cases. No other test verdict changes.
Additional test_bpf fixtures passed on MIPS32 R2 big-endian and
MIPS64 R2 little-endian, covering signed boundaries, aliasing,
R6-R9 preservation across a helper call, and large signed offsets.
JIT disassembly confirmed the load and register-save sequences.
These tests exercise the JIT directly, bypassing the verifier.
Earlier comparisons covered MIPS32 R1/R2/R6 and MIPS64 R2 in both byte
orders, plus MIPS64 R6 little-endian. Those results predate this rebase;
the signed-load emitters and their delay/clobber helpers are identical.
No physical hardware or MIPS I CPU was tested.
Link to v1:
https://lore.kernel.org/bpf/20260821024640.1601299-1-main.kalliope@gmail.com/
arch/mips/net/bpf_jit_comp32.c | 29 +++++++++++++++++++++++++++++
arch/mips/net/bpf_jit_comp64.c | 26 ++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/arch/mips/net/bpf_jit_comp32.c b/arch/mips/net/bpf_jit_comp32.c
index 8f1ab851863fc9aaa4a107dcd3633c5f51f219ea..f72cd21eb5ccbb6eaba15439958c12eb072b3900 100644
--- a/arch/mips/net/bpf_jit_comp32.c
+++ b/arch/mips/net/bpf_jit_comp32.c
@@ -757,6 +757,29 @@ static void emit_ldx(struct jit_context *ctx,
clobber_reg64(ctx, dst);
}
+/* Load operation with sign extension: dst = *(signed size *)(src + off) */
+static void emit_ldsx(struct jit_context *ctx,
+ const u8 dst[], u8 src, s16 off, u8 size)
+{
+ switch (size) {
+ /* Load a byte */
+ case BPF_B:
+ emit(ctx, lb, lo(dst), off, src);
+ break;
+ /* Load a half word */
+ case BPF_H:
+ emit(ctx, lh, lo(dst), off, src);
+ break;
+ /* Load a word */
+ case BPF_W:
+ emit(ctx, lw, lo(dst), off, src);
+ break;
+ }
+ emit_load_delay(ctx);
+ emit(ctx, sra, hi(dst), lo(dst), 31);
+ clobber_reg64(ctx, dst);
+}
+
/* Store operation: *(size *)(dst + off) = src */
static void emit_stx(struct jit_context *ctx,
const u8 dst, const u8 src[], s16 off, u8 size)
@@ -1728,6 +1751,12 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_LDX | BPF_MEM | BPF_DW:
emit_ldx(ctx, dst, lo(src), off, BPF_SIZE(code));
break;
+ /* LDSX: dst = *(signed size *)(src + off) */
+ case BPF_LDX | BPF_MEMSX | BPF_W:
+ case BPF_LDX | BPF_MEMSX | BPF_H:
+ case BPF_LDX | BPF_MEMSX | BPF_B:
+ emit_ldsx(ctx, dst, lo(src), off, BPF_SIZE(code));
+ break;
/* ST: *(size *)(dst + off) = imm */
case BPF_ST | BPF_MEM | BPF_W:
case BPF_ST | BPF_MEM | BPF_H:
diff --git a/arch/mips/net/bpf_jit_comp64.c b/arch/mips/net/bpf_jit_comp64.c
index 4507841a922484cda126e57d52d6a2924ef33a72..7bba0d4b0b2c04a742dec6234e4c6e610532e132 100644
--- a/arch/mips/net/bpf_jit_comp64.c
+++ b/arch/mips/net/bpf_jit_comp64.c
@@ -431,6 +431,26 @@ static void emit_ldx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size)
clobber_reg(ctx, dst);
}
+/* Load operation with sign extension: dst = *(signed size *)(src + off) */
+static void emit_ldsx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size)
+{
+ switch (size) {
+ /* Load a byte */
+ case BPF_B:
+ emit(ctx, lb, dst, off, src);
+ break;
+ /* Load a half word */
+ case BPF_H:
+ emit(ctx, lh, dst, off, src);
+ break;
+ /* Load a word */
+ case BPF_W:
+ emit(ctx, lw, dst, off, src);
+ break;
+ }
+ clobber_reg(ctx, dst);
+}
+
/* Store operation: *(size *)(dst + off) = src */
static void emit_stx(struct jit_context *ctx, u8 dst, u8 src, s16 off, u8 size)
{
@@ -903,6 +923,12 @@ int build_insn(const struct bpf_insn *insn, struct jit_context *ctx)
case BPF_LDX | BPF_MEM | BPF_DW:
emit_ldx(ctx, dst, src, off, BPF_SIZE(code));
break;
+ /* LDSX: dst = *(signed size *)(src + off) */
+ case BPF_LDX | BPF_MEMSX | BPF_W:
+ case BPF_LDX | BPF_MEMSX | BPF_H:
+ case BPF_LDX | BPF_MEMSX | BPF_B:
+ emit_ldsx(ctx, dst, src, off, BPF_SIZE(code));
+ break;
/* ST: *(size *)(dst + off) = imm */
case BPF_ST | BPF_MEM | BPF_W:
case BPF_ST | BPF_MEM | BPF_H:
base-commit: c1ff425d625eb2a4d2967e9889b85f202f24eb5d
prerequisite-patch-id: aa8ca3f50fc4b0160c5fdba43a92e4b7ec3f2e07
prerequisite-patch-id: 9f324d79755bae54c56ce6c90769acc8595c9ad6
prerequisite-patch-id: 35236f563c0536859077709d52b345b696e5c26e
prerequisite-patch-id: c0f282b0e57ecd60e9582fb1e89e4b3112ae7893
prerequisite-patch-id: 528eee53fa86686e7e69fa8a12c605b386381a33
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-09-12 18:06 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 18:06 [PATCH bpf-next v2] bpf, mips: Add BPF_MEMSX support to the JITs Nicholas Dudar
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox