From: Marat Khalili <marat.khalili@huawei.com>
To: <dev@dpdk.org>, Konstantin Ananyev <konstantin.ananyev@huawei.com>
Subject: [PATCH 2/2] bpf: dump additional instructions
Date: Wed, 17 Dec 2025 17:20:36 +0000 [thread overview]
Message-ID: <20251217172037.59170-3-marat.khalili@huawei.com> (raw)
In-Reply-To: <20251217172037.59170-1-marat.khalili@huawei.com>
Fix issues with rte_bpf_dump not supporting or printing incorrectly some
instructions that lib/bpf supports, and add warnings when it doesn't:
* Conditional jump with condition between two registers was incorrectly
printed by rte_bpf_dump as one with condition between register and
immediate. Add missing handling of BPF_X flag.
* Call instruction was printed by rte_bpf_dump as conditional jump. Add
explicit handling for it.
* We only support stx and ldx instructions in BPF_MEM mode, but were not
checking the mode in rte_bpf_dump. Check for mode and only print
mnemonic if the mode is BPF_MEM, otherwise print an error.
* Atomic instructions were not previously supported by rte_bpf_dump. Add
necessary handling.
* Some instructions have variations with previously unused src_reg or
offset fields set to non-zero value. We do not support any of these
variations yet, and were printing them as a standard instruction.
Print small note after such instructions warning the user that this is
a variation.
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
lib/bpf/bpf_dump.c | 69 ++++++++++++++++++++++++++++++++++++++--------
1 file changed, 57 insertions(+), 12 deletions(-)
diff --git a/lib/bpf/bpf_dump.c b/lib/bpf/bpf_dump.c
index 6ee0e32b43..91bc7c0a7a 100644
--- a/lib/bpf/bpf_dump.c
+++ b/lib/bpf/bpf_dump.c
@@ -44,6 +44,19 @@ static const char *const jump_tbl[16] = {
[EBPF_CALL >> 4] = "call", [EBPF_EXIT >> 4] = "exit",
};
+static inline const char *
+atomic_op(int32_t imm)
+{
+ switch (imm) {
+ case BPF_ATOMIC_ADD:
+ return "xadd";
+ case BPF_ATOMIC_XCHG:
+ return "xchg";
+ default:
+ return NULL;
+ }
+}
+
RTE_EXPORT_SYMBOL(rte_bpf_dump)
void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
{
@@ -52,7 +65,7 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
for (i = 0; i < len; ++i) {
const struct ebpf_insn *ins = buf + i;
uint8_t cls = BPF_CLASS(ins->code);
- const char *op, *postfix = "";
+ const char *op, *postfix = "", *warning = "";
fprintf(f, " L%u:\t", i);
@@ -66,12 +79,15 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
/* fall through */
case EBPF_ALU64:
op = alu_op_tbl[BPF_OP_INDEX(ins->code)];
+ if (ins->off != 0)
+ /* Not yet supported variation with non-zero offset. */
+ warning = ", off != 0";
if (BPF_SRC(ins->code) == BPF_X)
- fprintf(f, "%s%s r%u, r%u\n", op, postfix, ins->dst_reg,
- ins->src_reg);
+ fprintf(f, "%s%s r%u, r%u%s\n", op, postfix, ins->dst_reg,
+ ins->src_reg, warning);
else
- fprintf(f, "%s%s r%u, #0x%x\n", op, postfix,
- ins->dst_reg, ins->imm);
+ fprintf(f, "%s%s r%u, #0x%x%s\n", op, postfix,
+ ins->dst_reg, ins->imm, warning);
break;
case BPF_LD:
op = "ld";
@@ -79,10 +95,13 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
if (ins->code == (BPF_LD | BPF_IMM | EBPF_DW)) {
uint64_t val;
+ if (ins->src_reg != 0)
+ /* Not yet supported variation with non-zero src. */
+ warning = ", src != 0";
val = (uint32_t)ins[0].imm |
(uint64_t)(uint32_t)ins[1].imm << 32;
- fprintf(f, "%s%s r%d, #0x%"PRIx64"\n",
- op, postfix, ins->dst_reg, val);
+ fprintf(f, "%s%s r%d, #0x%"PRIx64"%s\n",
+ op, postfix, ins->dst_reg, val, warning);
i++;
} else if (BPF_MODE(ins->code) == BPF_IMM)
fprintf(f, "%s%s r%d, #0x%x\n", op, postfix,
@@ -100,8 +119,12 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
case BPF_LDX:
op = "ldx";
postfix = size_tbl[BPF_SIZE_INDEX(ins->code)];
- fprintf(f, "%s%s r%d, [r%u + %d]\n", op, postfix, ins->dst_reg,
- ins->src_reg, ins->off);
+ if (BPF_MODE(ins->code) == BPF_MEM)
+ fprintf(f, "%s%s r%d, [r%u + %d]\n", op, postfix, ins->dst_reg,
+ ins->src_reg, ins->off);
+ else
+ fprintf(f, "// BUG: LDX opcode 0x%02x in eBPF insns\n",
+ ins->code);
break;
case BPF_ST:
op = "st";
@@ -114,7 +137,20 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
ins->code);
break;
case BPF_STX:
- op = "stx";
+ if (BPF_MODE(ins->code) == BPF_MEM)
+ op = "stx";
+ else if (BPF_MODE(ins->code) == EBPF_ATOMIC) {
+ op = atomic_op(ins->imm);
+ if (op == NULL) {
+ fprintf(f, "// BUG: ATOMIC operation 0x%x in eBPF insns\n",
+ ins->imm);
+ break;
+ }
+ } else {
+ fprintf(f, "// BUG: STX opcode 0x%02x in eBPF insns\n",
+ ins->code);
+ break;
+ }
postfix = size_tbl[BPF_SIZE_INDEX(ins->code)];
fprintf(f, "%s%s [r%d + %d], r%u\n", op, postfix,
ins->dst_reg, ins->off, ins->src_reg);
@@ -122,12 +158,21 @@ void rte_bpf_dump(FILE *f, const struct ebpf_insn *buf, uint32_t len)
#define L(pc, off) ((int)(pc) + 1 + (off))
case BPF_JMP:
op = jump_tbl[BPF_OP_INDEX(ins->code)];
+ if (ins->src_reg != 0)
+ /* Not yet supported variation with non-zero src w/o condition. */
+ warning = ", src != 0";
if (op == NULL)
fprintf(f, "invalid jump opcode: %#x\n", ins->code);
else if (BPF_OP(ins->code) == BPF_JA)
- fprintf(f, "%s L%d\n", op, L(i, ins->off));
+ fprintf(f, "%s L%d%s\n", op, L(i, ins->off), warning);
+ else if (BPF_OP(ins->code) == EBPF_CALL)
+ /* Call of helper function with index in immediate. */
+ fprintf(f, "%s #%u%s\n", op, ins->imm, warning);
else if (BPF_OP(ins->code) == EBPF_EXIT)
- fprintf(f, "%s\n", op);
+ fprintf(f, "%s%s\n", op, warning);
+ else if (BPF_SRC(ins->code) == BPF_X)
+ fprintf(f, "%s r%u, r%u, L%d\n", op, ins->dst_reg,
+ ins->src_reg, L(i, ins->off));
else
fprintf(f, "%s r%u, #0x%x, L%d\n", op, ins->dst_reg,
ins->imm, L(i, ins->off));
--
2.43.0
prev parent reply other threads:[~2025-12-17 17:21 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-17 17:20 [PATCH 0/2] bpf: add xchg and fix rte_bpf_dump Marat Khalili
2025-12-17 17:20 ` [PATCH 1/2] bpf: add atomic xchg support Marat Khalili
2025-12-17 17:20 ` Marat Khalili [this message]
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=20251217172037.59170-3-marat.khalili@huawei.com \
--to=marat.khalili@huawei.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@huawei.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;
as well as URLs for NNTP newsgroup(s).