Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions patches/rhel8/0001-bpf-x64-Fix-a-jit-convergence-issue.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
From 12e840051b7bf1cf4701538bcfe19c69e30a3349 Mon Sep 17 00:00:00 2001
From: Yonghong Song <[email protected]>
Date: Sun, 25 Aug 2024 13:04:06 -0700
Subject: [PATCH] bpf, x64: Fix a jit convergence issue

Daniel Hodges reported a jit error when playing with a sched-ext
program. The error message is:
unexpected jmp_cond padding: -4 bytes

But further investigation shows the error is actual due to failed
convergence. The following are some analysis:

...
pass4, final_proglen=4391:
...
20e: 48 85 ff test rdi,rdi
211: 74 7d je 0x290
213: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
...
289: 48 85 ff test rdi,rdi
28c: 74 17 je 0x2a5
28e: e9 7f ff ff ff jmp 0x212
293: bf 03 00 00 00 mov edi,0x3

Note that insn at 0x211 is 2-byte cond jump insn for offset 0x7d (-125)
and insn at 0x28e is 5-byte jmp insn with offset -129.

pass5, final_proglen=4392:
...
20e: 48 85 ff test rdi,rdi
211: 0f 84 80 00 00 00 je 0x297
217: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
...
28d: 48 85 ff test rdi,rdi
290: 74 1a je 0x2ac
292: eb 84 jmp 0x218
294: bf 03 00 00 00 mov edi,0x3

Note that insn at 0x211 is 5-byte cond jump insn now since its offset
becomes 0x80 based on previous round (0x293 - 0x213 = 0x80).
At the same time, insn at 0x292 is a 2-byte insn since its offset is
-124.

pass6 will repeat the same code as in pass4. pass7 will repeat the same
code as in pass5, and so on. This will prevent eventual convergence.

Passes 1-14 are with padding = 0. At pass15, padding is 1 and related
insn looks like:

211: 0f 84 80 00 00 00 je 0x297
217: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
...
24d: 48 85 d2 test rdx,rdx

The similar code in pass14:
211: 74 7d je 0x290
213: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
...
249: 48 85 d2 test rdx,rdx
24c: 74 21 je 0x26f
24e: 48 01 f7 add rdi,rsi
...

Before generating the following insn,
250: 74 21 je 0x273
"padding = 1" enables some checking to ensure nops is either 0 or 4
where
#define INSN_SZ_DIFF (((addrs[i] - addrs[i - 1]) - (prog - temp)))
nops = INSN_SZ_DIFF - 2

In this specific case,
addrs[i] = 0x24e // from pass14
addrs[i-1] = 0x24d // from pass15
prog - temp = 3 // from 'test rdx,rdx' in pass15
so
nops = -4
and this triggers the failure.
Making jit prog convergable can fix the above error.

Reported-by: Daniel Hodges <[email protected]>
Signed-off-by: Yonghong Song <[email protected]>
---
arch/x86/net/bpf_jit_comp.c | 47 ++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)

diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 16b18554e..48f738224 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -56,6 +56,51 @@ static bool is_imm8(int value)
return value <= 127 && value >= -128;
}

+/*
+ * Let us limit the positive offset to be <= 124.
+ * This is to ensure eventual jit convergence For the following patterns:
+ * ...
+ * pass4, final_proglen=4391:
+ * ...
+ * 20e: 48 85 ff test rdi,rdi
+ * 211: 74 7d je 0x290
+ * 213: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
+ * ...
+ * 289: 48 85 ff test rdi,rdi
+ * 28c: 74 17 je 0x2a5
+ * 28e: e9 7f ff ff ff jmp 0x212
+ * 293: bf 03 00 00 00 mov edi,0x3
+ * Note that insn at 0x211 is 2-byte cond jump insn for offset 0x7d (-125)
+ * and insn at 0x28e is 5-byte jmp insn with offset -129.
+ *
+ * pass5, final_proglen=4392:
+ * ...
+ * 20e: 48 85 ff test rdi,rdi
+ * 211: 0f 84 80 00 00 00 je 0x297
+ * 217: 48 8b 77 00 mov rsi,QWORD PTR [rdi+0x0]
+ * ...
+ * 28d: 48 85 ff test rdi,rdi
+ * 290: 74 1a je 0x2ac
+ * 292: eb 84 jmp 0x218
+ * 294: bf 03 00 00 00 mov edi,0x3
+ * Note that insn at 0x211 is 5-byte cond jump insn now since its offset
+ * becomes 0x80 based on previous round (0x293 - 0x213 = 0x80).
+ * At the same time, insn at 0x292 is a 2-byte insn since its offset is
+ * -124.
+ *
+ * pass6 will repeat the same code as in pass4 and this will prevent
+ * eventual convergence.
+ *
+ * To fix this issue, we need to break je (2->6 bytes) <-> jmp (5->2 bytes)
+ * cycle in the above. Let us limit the positive offset for 8bit cond jump
+ * insn to mamximum 124 (0x7c). This way, the jmp insn will be always 2-bytes,
+ * and the jit pass can eventually converge.
+ */
+static bool is_imm8_cond_offset(int value)
+{
+ return value <= 124 && value >= -128;
+}
+
static bool is_simm32(s64 value)
{
return value == (s64)(s32)value;
@@ -1583,7 +1628,7 @@ st: if (is_imm8(insn->off))
return -EFAULT;
}
jmp_offset = addrs[i + insn->off] - addrs[i];
- if (is_imm8(jmp_offset)) {
+ if (is_imm8_cond_offset(jmp_offset)) {
if (jmp_padding) {
/* To keep the jmp_offset valid, the extra bytes are
* padded before the jump insn, so we subtract the
--
2.43.0

2 changes: 1 addition & 1 deletion versions/complexity-test/4.19
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/5.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/5.15
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/5.4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/6.1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/6.12
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/6.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/bpf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/bpf-net
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/bpf-next
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/rhel8.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/rhel8.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/complexity-test/rhel8.9
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/4.19
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/5.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/5.15
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/5.4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/6.1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/6.12
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/6.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/bpf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/bpf-net
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/bpf-next
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/rhel8.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/rhel8.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kernel-images/rhel8.9
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842
20250923.124500
2 changes: 1 addition & 1 deletion versions/kind/amd64/4.19
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/5.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/5.15
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/5.4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/6.1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/6.12
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/6.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/bpf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/bpf-net
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/bpf-next
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/rhel8.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/rhel8.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/amd64/rhel8.9
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-amd64
20250923.124500-amd64
2 changes: 1 addition & 1 deletion versions/kind/arm64/4.19
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/5.10
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/5.15
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/5.4
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/6.1
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/6.12
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/6.6
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/bpf
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/bpf-net
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64
2 changes: 1 addition & 1 deletion versions/kind/arm64/bpf-next
Original file line number Diff line number Diff line change
@@ -1 +1 @@
20250923.075842-arm64
20250923.124500-arm64