From: Maxim Khmelevskii <max@linux.ibm.com>
To: Alexei Starovoitov <ast@kernel.org>,
Andrii Nakryiko <andrii@kernel.org>,
Daniel Borkmann <daniel@iogearbox.net>
Cc: bpf@vger.kernel.org, Ilya Leoshkevich <iii@linux.ibm.com>,
Heiko Carstens <hca@linux.ibm.com>,
Vasily Gorbik <gor@linux.ibm.com>,
Alexander Gordeev <agordeev@linux.ibm.com>
Subject: [PATCH bpf-next 1/3] s390/bpf: Add emit_ldx and emit_stx functions
Date: Thu, 23 Jul 2026 16:03:49 +0200 [thread overview]
Message-ID: <20260723140648.583055-6-max@linux.ibm.com> (raw)
In-Reply-To: <20260723140648.583055-5-max@linux.ibm.com>
Add new functions for load and store to reuse
them in the load-acquire and store-release logic.
Reviewed-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Maxim Khmelevskii <max@linux.ibm.com>
---
arch/s390/net/bpf_jit_comp.c | 167 +++++++++++++++++------------------
1 file changed, 82 insertions(+), 85 deletions(-)
diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
index 31749c0362ca..e3dc0df551a7 100644
--- a/arch/s390/net/bpf_jit_comp.c
+++ b/arch/s390/net/bpf_jit_comp.c
@@ -830,6 +830,72 @@ static int bpf_jit_probe_post(struct bpf_jit *jit, struct bpf_prog *fp,
return 0;
}
+static int emit_ldx(struct bpf_jit *jit, struct bpf_prog *fp, struct bpf_insn *insn)
+{
+ struct bpf_jit_probe probe;
+
+ bpf_jit_probe_init(&probe);
+ bpf_jit_probe_load_pre(jit, insn, &probe);
+
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B: /* dst = *(u8 *)(ul) (src + off) */
+ /* llgc %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0090, insn->dst_reg, insn->src_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_H: /* dst = *(u16 *)(ul) (src + off) */
+ /* llgh %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0091, insn->dst_reg, insn->src_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_W: /* dst = *(u32 *)(ul) (src + off) */
+ /* llgf %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0016, insn->dst_reg, insn->src_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
+ /* lg %dst,off(%src,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0004, insn->dst_reg, insn->src_reg,
+ probe.arena_reg, insn->off);
+ break;
+ }
+
+ return bpf_jit_probe_post(jit, fp, &probe);
+}
+
+static int emit_stx(struct bpf_jit *jit, struct bpf_prog *fp, struct bpf_insn *insn)
+{
+ struct bpf_jit_probe probe;
+
+ bpf_jit_probe_init(&probe);
+ bpf_jit_probe_store_pre(jit, insn, &probe);
+
+ switch (BPF_SIZE(insn->code)) {
+ case BPF_B: /* *(u8 *)(dst + off) = src_reg */
+ /* stcy %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0072, insn->src_reg, insn->dst_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_H: /* (u16 *)(dst + off) = src */
+ /* sthy %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0070, insn->src_reg, insn->dst_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_W: /* *(u32 *)(dst + off) = src */
+ /* sty %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0050, insn->src_reg, insn->dst_reg,
+ probe.arena_reg, insn->off);
+ break;
+ case BPF_DW: /* (u64 *)(dst + off) = src */
+ /* stg %src,off(%dst,%arena) */
+ EMIT6_DISP_LH(0xe3000000, 0x0024, insn->src_reg, insn->dst_reg,
+ probe.arena_reg, insn->off);
+ break;
+ }
+
+ return bpf_jit_probe_post(jit, fp, &probe);
+}
+
/*
* Sign- or zero-extend the register if necessary
*/
@@ -1477,44 +1543,13 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
*/
case BPF_STX | BPF_MEM | BPF_B: /* *(u8 *)(dst + off) = src_reg */
case BPF_STX | BPF_PROBE_MEM32 | BPF_B:
- bpf_jit_probe_store_pre(jit, insn, &probe);
- /* stcy %src,off(%dst,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0072, src_reg, dst_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- jit->seen |= SEEN_MEM;
- break;
case BPF_STX | BPF_MEM | BPF_H: /* (u16 *)(dst + off) = src */
case BPF_STX | BPF_PROBE_MEM32 | BPF_H:
- bpf_jit_probe_store_pre(jit, insn, &probe);
- /* sthy %src,off(%dst,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0070, src_reg, dst_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- jit->seen |= SEEN_MEM;
- break;
case BPF_STX | BPF_MEM | BPF_W: /* *(u32 *)(dst + off) = src */
case BPF_STX | BPF_PROBE_MEM32 | BPF_W:
- bpf_jit_probe_store_pre(jit, insn, &probe);
- /* sty %src,off(%dst,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0050, src_reg, dst_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- jit->seen |= SEEN_MEM;
- break;
case BPF_STX | BPF_MEM | BPF_DW: /* (u64 *)(dst + off) = src */
case BPF_STX | BPF_PROBE_MEM32 | BPF_DW:
- bpf_jit_probe_store_pre(jit, insn, &probe);
- /* stg %src,off(%dst,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0024, src_reg, dst_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
+ err = emit_stx(jit, fp, insn);
if (err < 0)
return err;
jit->seen |= SEEN_MEM;
@@ -1574,8 +1609,12 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
/*
* BPF_ATOMIC
*/
+ case BPF_STX | BPF_ATOMIC | BPF_B:
+ case BPF_STX | BPF_ATOMIC | BPF_H:
case BPF_STX | BPF_ATOMIC | BPF_DW:
case BPF_STX | BPF_ATOMIC | BPF_W:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_B:
+ case BPF_STX | BPF_PROBE_ATOMIC | BPF_H:
case BPF_STX | BPF_PROBE_ATOMIC | BPF_DW:
case BPF_STX | BPF_PROBE_ATOMIC | BPF_W:
{
@@ -1687,15 +1726,20 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
case BPF_LDX | BPF_MEM | BPF_B: /* dst = *(u8 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEM | BPF_B:
case BPF_LDX | BPF_PROBE_MEM32 | BPF_B:
- bpf_jit_probe_load_pre(jit, insn, &probe);
- /* llgc %dst,off(%src,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0090, dst_reg, src_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
+ case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
+ case BPF_LDX | BPF_PROBE_MEM | BPF_H:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_H:
+ case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
+ case BPF_LDX | BPF_PROBE_MEM | BPF_W:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
+ case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
+ case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
+ case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
+ err = emit_ldx(jit, fp, insn);
if (err < 0)
return err;
jit->seen |= SEEN_MEM;
- if (insn_is_zext(&insn[1]))
+ if (BPF_SIZE(insn->code) != BPF_DW && insn_is_zext(&insn[1]))
insn_count = 2;
break;
case BPF_LDX | BPF_MEMSX | BPF_B: /* dst = *(s8 *)(ul) (src + off) */
@@ -1708,20 +1752,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
return err;
jit->seen |= SEEN_MEM;
break;
- case BPF_LDX | BPF_MEM | BPF_H: /* dst = *(u16 *)(ul) (src + off) */
- case BPF_LDX | BPF_PROBE_MEM | BPF_H:
- case BPF_LDX | BPF_PROBE_MEM32 | BPF_H:
- bpf_jit_probe_load_pre(jit, insn, &probe);
- /* llgh %dst,off(%src,%arena) */
- EMIT6_DISP_LH(0xe3000000, 0x0091, dst_reg, src_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- jit->seen |= SEEN_MEM;
- if (insn_is_zext(&insn[1]))
- insn_count = 2;
- break;
case BPF_LDX | BPF_MEMSX | BPF_H: /* dst = *(s16 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEMSX | BPF_H:
bpf_jit_probe_load_pre(jit, insn, &probe);
@@ -1732,20 +1762,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
return err;
jit->seen |= SEEN_MEM;
break;
- case BPF_LDX | BPF_MEM | BPF_W: /* dst = *(u32 *)(ul) (src + off) */
- case BPF_LDX | BPF_PROBE_MEM | BPF_W:
- case BPF_LDX | BPF_PROBE_MEM32 | BPF_W:
- bpf_jit_probe_load_pre(jit, insn, &probe);
- /* llgf %dst,off(%src) */
- jit->seen |= SEEN_MEM;
- EMIT6_DISP_LH(0xe3000000, 0x0016, dst_reg, src_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- if (insn_is_zext(&insn[1]))
- insn_count = 2;
- break;
case BPF_LDX | BPF_MEMSX | BPF_W: /* dst = *(s32 *)(ul) (src + off) */
case BPF_LDX | BPF_PROBE_MEMSX | BPF_W:
bpf_jit_probe_load_pre(jit, insn, &probe);
@@ -1756,18 +1772,6 @@ static noinline int bpf_jit_insn(struct bpf_jit *jit, struct bpf_prog *fp,
if (err < 0)
return err;
break;
- case BPF_LDX | BPF_MEM | BPF_DW: /* dst = *(u64 *)(ul) (src + off) */
- case BPF_LDX | BPF_PROBE_MEM | BPF_DW:
- case BPF_LDX | BPF_PROBE_MEM32 | BPF_DW:
- bpf_jit_probe_load_pre(jit, insn, &probe);
- /* lg %dst,off(%src,%arena) */
- jit->seen |= SEEN_MEM;
- EMIT6_DISP_LH(0xe3000000, 0x0004, dst_reg, src_reg,
- probe.arena_reg, off);
- err = bpf_jit_probe_post(jit, fp, &probe);
- if (err < 0)
- return err;
- break;
/*
* BPF_JMP / CALL
*/
@@ -3028,13 +3032,6 @@ bool bpf_jit_supports_insn(struct bpf_insn *insn, bool in_arena)
if (!in_arena)
return true;
switch (insn->code) {
- case BPF_STX | BPF_ATOMIC | BPF_B:
- case BPF_STX | BPF_ATOMIC | BPF_H:
- case BPF_STX | BPF_ATOMIC | BPF_W:
- case BPF_STX | BPF_ATOMIC | BPF_DW:
- if (bpf_atomic_is_load_store(insn))
- return false;
- break;
case BPF_LDX | BPF_MEMSX | BPF_B:
case BPF_LDX | BPF_MEMSX | BPF_H:
case BPF_LDX | BPF_MEMSX | BPF_W:
--
2.55.0
next prev parent reply other threads:[~2026-07-23 14:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-23 14:03 [PATCH bpf-next 0/3] s390/bpf: Support load-acquire and store-release instructions Maxim Khmelevskii
2026-07-23 14:03 ` Maxim Khmelevskii [this message]
2026-07-23 15:08 ` [PATCH bpf-next 1/3] s390/bpf: Add emit_ldx and emit_stx functions bot+bpf-ci
2026-07-23 14:03 ` [PATCH bpf-next 2/3] s390/bpf: Support load-acquire and store-release instructions Maxim Khmelevskii
2026-07-23 14:03 ` [PATCH bpf-next 3/3] s390/bpf: Enable atomics tests for s390 Maxim Khmelevskii
2026-07-23 14:12 ` sashiko-bot
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=20260723140648.583055-6-max@linux.ibm.com \
--to=max@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=gor@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=iii@linux.ibm.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox