Skip to content

Commit 6562472

Browse files
mtardydylandreimerink
authored andcommitted
asm: add support for the may_goto insn and JCOND opcode
The `may_goto` instruction is a bit special and relatively new, from March 2024, added by 011832b97b31 ("bpf: Introduce may_goto instruction")[^1]. It uses the `BPF_JCOND` opcode `0xe0` with the source register being `BPF_MAY_GOTO = 0`. Note that this instruction is not documented in the latest instruction set kernel documentation[^2]. As I understand, the goal of this instruction is to be injected in loops (also potentially by LLVM) to offload the verifier responsibility of loop verification to a runtime check. The runtime check being decrementing a counter so far. [^1]: https://lore.kernel.org/bpf/20240306031929.42666-2-alexei.starovoitov@gmail.com [^2]: https://www.kernel.org/doc/html/v6.17/bpf/standardization/instruction-set.html#jump-instructions Co-Authored-By: Mahe Tardy <mahe.tardy@gmail.com> Signed-off-by: Dylan Reimerink <dylan.reimerink@isovalent.com>
1 parent dd42f89 commit 6562472

File tree

6 files changed

+22
-3
lines changed

6 files changed

+22
-3
lines changed

asm/instruction.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,9 @@ func (ins Instruction) Format(f fmt.State, c rune) {
396396
}
397397

398398
case cls.IsJump():
399-
fmt.Fprintf(f, "%v ", op)
400399
switch jop := op.JumpOp(); jop {
401400
case Call:
401+
fmt.Fprintf(f, "%v ", op)
402402
switch ins.Src {
403403
case PseudoCall:
404404
// bpf-to-bpf call
@@ -411,13 +411,23 @@ func (ins Instruction) Format(f fmt.State, c rune) {
411411
}
412412

413413
case Ja:
414+
fmt.Fprintf(f, "%v ", op)
414415
if ins.OpCode.Class() == Jump32Class {
415416
fmt.Fprintf(f, "imm: %d", ins.Constant)
416417
} else {
417418
fmt.Fprintf(f, "off: %d", ins.Offset)
418419
}
419420

421+
case JCOND:
422+
switch ins.Src {
423+
case PseudoMayGoto:
424+
fmt.Fprintf(f, "JCond may_goto off: %d", ins.Offset)
425+
default:
426+
fmt.Fprintf(f, "%v", op)
427+
}
428+
420429
default:
430+
fmt.Fprintf(f, "%v ", op)
421431
fmt.Fprintf(f, "dst: %s off: %d ", ins.Dst, ins.Offset)
422432
if op.Source() == ImmSource {
423433
fmt.Fprintf(f, "imm: %d", ins.Constant)

asm/instruction_test.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,8 @@ func TestISAv4(t *testing.T) {
393393
0xcb, 0x21, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, // store_release((u16 *)(r1 + 0x0), w2)
394394
0xc3, 0x21, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, // store_release((u32 *)(r1 + 0x0), w2)
395395
0xdb, 0x21, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, // store_release((u64 *)(r1 + 0x0), r2)
396+
397+
0xe5, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, // may_goto +30
396398
}
397399

398400
insns, err := AppendInstructions(nil, bytes.NewReader(rawInsns), binary.LittleEndian, platform.Linux)
@@ -427,6 +429,7 @@ func TestISAv4(t *testing.T) {
427429
"StXAtomicStRelH dst: r1 src: r2 off: 0",
428430
"StXAtomicStRelW dst: r1 src: r2 off: 0",
429431
"StXAtomicStRelDW dst: r1 src: r2 off: 0",
432+
"JCond may_goto off: 30",
430433
}
431434

432435
for i, ins := range insns {

asm/jump.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ const (
4444
JSLT JumpOp = 0xc0
4545
// JSLE jumps by offset if signed r <= signed imm
4646
JSLE JumpOp = 0xd0
47+
// JCOND is a conditional pseudo jump to encode the may_goto instruction
48+
JCOND JumpOp = 0xe0
4749
)
4850

4951
// Return emits an exit instruction.

asm/jump_string.go

Lines changed: 4 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

asm/opcode_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ func TestGetSetJumpOp(t *testing.T) {
4444
JLE,
4545
JSLT,
4646
JSLE,
47+
JCOND,
4748
} {
4849
test(Jump32Class, op, true)
4950
test(JumpClass, op, true)

asm/register.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ const (
4040
PseudoCall = R1 // BPF_PSEUDO_CALL
4141
PseudoFunc = R4 // BPF_PSEUDO_FUNC
4242
PseudoKfuncCall = R2 // BPF_PSEUDO_KFUNC_CALL
43+
PseudoMayGoto = R0 // BPF_MAY_GOTO
4344
)
4445

4546
func (r Register) String() string {

0 commit comments

Comments
 (0)