* max<min after jset
@ 2023-11-21 17:32 Tao Lyu
2023-11-22 0:25 ` Yonghong Song
2023-11-28 4:16 ` max<min after jset Yonghong Song
0 siblings, 2 replies; 10+ messages in thread
From: Tao Lyu @ 2023-11-21 17:32 UTC (permalink / raw)
To: andrii, ast, daniel, song, yonghong.song, haoluo, martin.lau
Cc: bpf, sanidhya.kashyap, mathias.payer, meng.xu.cs, Tao Lyu
Hi,
The eBPF program shown below leads to an reversed min and max
after insn 6 "if w0 & 0x894b6a55 goto +2",
whic means max < min.
Here is the introduction how it happens.
Before insn 6,
the range of r0 expressed by the min and max field is
min1 = 884670597, max1 = 900354100
And the range expressed by the var_off=(0x34000000; 0x1ff5fbf))
is min2=872415232, max2=905928639.
---min2-----------------------min1-----max1-----max2---
Here we can see that the range expressed by var_off is wider than that of min and max.
When verifying insn6,
it first uses the var_off and immediate "0x894b6a55" to
calculate the new var_off=(0x34b00000; 0x415aa).
The range expressed by the new var_off is:
min3=883949568, max3=884217258
---min2-----min3-----max3-----min1-----max1-----max2---
And then it will calculate the new min and max by:
(1) new-min = MAX(min3, min1) = min1
(2) new-max = MIN(max3, max1) = max3
---min2-----min3-----max3-----min1-----max1-----max2---
"new-max" "new-min"
Now, the new-max becomes less than the new min.
Notably, [min1, max1] can never make "w0 & 0x894b6a55 == 0"
and thus cannot goes the fall-through branch.
In other words, actually the fall-trough branch is a dead path.
BTW, I cannot successfully compile this instruciton "if w0 != 0 goto +2;\"
in the c inline assembly code.
So I can only attach the bytecodes.
Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
---
.../selftests/bpf/verifier/jset_reversed_range.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
create mode 100644 tools/testing/selftests/bpf/verifier/jset_reversed_range.c
diff --git a/tools/testing/selftests/bpf/verifier/jset_reversed_range.c b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
new file mode 100644
index 000000000000..734f492a2a96
--- /dev/null
+++ b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
@@ -0,0 +1,15 @@
+{
+ "BPF_JSET: incorrect scalar range",
+ .insns = {
+ BPF_MOV64_IMM(BPF_REG_5, 100),
+ BPF_ALU64_IMM(BPF_DIV, BPF_REG_5, 3),
+ BPF_ALU32_IMM(BPF_RSH, BPF_REG_5, 7),
+ BPF_ALU64_IMM(BPF_AND, BPF_REG_5, -386969681),
+ BPF_ALU64_IMM(BPF_SUB, BPF_REG_5, -884670597),
+ BPF_MOV32_REG(BPF_REG_0, BPF_REG_5),
+ BPF_JMP32_IMM(BPF_JSET, BPF_REG_0, 0x894b6a55, 1),
+ BPF_MOV64_IMM(BPF_REG_0, 1),
+ BPF_MOV64_IMM(BPF_REG_0, 0),
+ BPF_EXIT_INSN(),
+ },
+},
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: max<min after jset
2023-11-21 17:32 max<min after jset Tao Lyu
@ 2023-11-22 0:25 ` Yonghong Song
2023-11-22 14:40 ` [PATCH] C inlined assembly for reproducing max<min Tao Lyu
2023-11-28 4:16 ` max<min after jset Yonghong Song
1 sibling, 1 reply; 10+ messages in thread
From: Yonghong Song @ 2023-11-22 0:25 UTC (permalink / raw)
To: Tao Lyu, andrii, ast, daniel, song, haoluo, martin.lau
Cc: bpf, sanidhya.kashyap, mathias.payer, meng.xu.cs
On 11/21/23 12:32 PM, Tao Lyu wrote:
> Hi,
>
> The eBPF program shown below leads to an reversed min and max
> after insn 6 "if w0 & 0x894b6a55 goto +2",
> whic means max < min.
>
> Here is the introduction how it happens.
>
> Before insn 6,
> the range of r0 expressed by the min and max field is
> min1 = 884670597, max1 = 900354100
> And the range expressed by the var_off=(0x34000000; 0x1ff5fbf))
> is min2=872415232, max2=905928639.
>
> ---min2-----------------------min1-----max1-----max2---
>
> Here we can see that the range expressed by var_off is wider than that of min and max.
>
> When verifying insn6,
> it first uses the var_off and immediate "0x894b6a55" to
> calculate the new var_off=(0x34b00000; 0x415aa).
> The range expressed by the new var_off is:
> min3=883949568, max3=884217258
>
> ---min2-----min3-----max3-----min1-----max1-----max2---
>
> And then it will calculate the new min and max by:
> (1) new-min = MAX(min3, min1) = min1
> (2) new-max = MIN(max3, max1) = max3
>
> ---min2-----min3-----max3-----min1-----max1-----max2---
> "new-max" "new-min"
>
> Now, the new-max becomes less than the new min.
>
> Notably, [min1, max1] can never make "w0 & 0x894b6a55 == 0"
> and thus cannot goes the fall-through branch.
> In other words, actually the fall-trough branch is a dead path.
>
> BTW, I cannot successfully compile this instruciton "if w0 != 0 goto +2;\"
> in the c inline assembly code.
The format "if w0 != 0 goto +2;\" should be supported by recent clang compiler.
Which clang version you are using? Maybe try clang 15/16? Could you also
post the C inline assembly code here so we can investigate?
> So I can only attach the bytecodes.
>
> Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
> ---
> .../selftests/bpf/verifier/jset_reversed_range.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/verifier/jset_reversed_range.c
>
> diff --git a/tools/testing/selftests/bpf/verifier/jset_reversed_range.c b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
> new file mode 100644
> index 000000000000..734f492a2a96
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
> @@ -0,0 +1,15 @@
> +{
> + "BPF_JSET: incorrect scalar range",
> + .insns = {
> + BPF_MOV64_IMM(BPF_REG_5, 100),
> + BPF_ALU64_IMM(BPF_DIV, BPF_REG_5, 3),
> + BPF_ALU32_IMM(BPF_RSH, BPF_REG_5, 7),
> + BPF_ALU64_IMM(BPF_AND, BPF_REG_5, -386969681),
> + BPF_ALU64_IMM(BPF_SUB, BPF_REG_5, -884670597),
> + BPF_MOV32_REG(BPF_REG_0, BPF_REG_5),
> + BPF_JMP32_IMM(BPF_JSET, BPF_REG_0, 0x894b6a55, 1),
> + BPF_MOV64_IMM(BPF_REG_0, 1),
> + BPF_MOV64_IMM(BPF_REG_0, 0),
> + BPF_EXIT_INSN(),
> + },
> +},
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] C inlined assembly for reproducing max<min
2023-11-22 0:25 ` Yonghong Song
@ 2023-11-22 14:40 ` Tao Lyu
2023-11-22 18:08 ` Yonghong Song
0 siblings, 1 reply; 10+ messages in thread
From: Tao Lyu @ 2023-11-22 14:40 UTC (permalink / raw)
To: yonghong.song
Cc: andrii, ast, bpf, daniel, haoluo, martin.lau, mathias.payer,
meng.xu.cs, sanidhya.kashyap, song, tao.lyu
Hi Yonghong,
Thanks for your reply.
The C inlined assembly code is attached.
I'm using clang-16, but it still fails.
Best,
Tao
Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
---
.../selftests/bpf/prog_tests/verifier.c | 2 ++
.../selftests/bpf/progs/verifier_range.c | 25 +++++++++++++++++++
2 files changed, 27 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/verifier_range.c
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index e5c61aa6604a..3a5d746f392d 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -77,6 +77,7 @@
#include "verifier_xadd.skel.h"
#include "verifier_xdp.skel.h"
#include "verifier_xdp_direct_packet_access.skel.h"
+#include "verifier_range.skel.h"
#define MAX_ENTRIES 11
@@ -184,6 +185,7 @@ void test_verifier_var_off(void) { RUN(verifier_var_off); }
void test_verifier_xadd(void) { RUN(verifier_xadd); }
void test_verifier_xdp(void) { RUN(verifier_xdp); }
void test_verifier_xdp_direct_packet_access(void) { RUN(verifier_xdp_direct_packet_access); }
+void test_verifier_range(void) { RUN(verifier_range); }
static int init_test_val_map(struct bpf_object *obj, char *map_name)
{
diff --git a/tools/testing/selftests/bpf/progs/verifier_range.c b/tools/testing/selftests/bpf/progs/verifier_range.c
new file mode 100644
index 000000000000..27597eb8135c
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_range.c
@@ -0,0 +1,25 @@
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+SEC("?tc")
+__log_level(2)
+int test_verifier_range(void)
+{
+ asm volatile (
+ "r5 = 100; \
+ r5 /= 3; \
+ w5 >>= 7; \
+ r5 &= -386969681; \
+ r5 -= -884670597; \
+ w0 = w5; \
+ if w0 & 0x894b6a55 goto +2; \
+ r2 = 1; \
+ r2 = 1; \
+ r0 = 0; \
+ "
+ );
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] C inlined assembly for reproducing max<min
2023-11-22 14:40 ` [PATCH] C inlined assembly for reproducing max<min Tao Lyu
@ 2023-11-22 18:08 ` Yonghong Song
2023-11-22 18:15 ` Alexei Starovoitov
0 siblings, 1 reply; 10+ messages in thread
From: Yonghong Song @ 2023-11-22 18:08 UTC (permalink / raw)
To: Tao Lyu
Cc: andrii, ast, bpf, daniel, haoluo, martin.lau, mathias.payer,
meng.xu.cs, sanidhya.kashyap, song
On 11/22/23 9:40 AM, Tao Lyu wrote:
> Hi Yonghong,
>
> Thanks for your reply.
> The C inlined assembly code is attached.
> I'm using clang-16, but it still fails.
>
> Best,
> Tao
>
> Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
> ---
> .../selftests/bpf/prog_tests/verifier.c | 2 ++
> .../selftests/bpf/progs/verifier_range.c | 25 +++++++++++++++++++
> 2 files changed, 27 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/progs/verifier_range.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
> index e5c61aa6604a..3a5d746f392d 100644
> --- a/tools/testing/selftests/bpf/prog_tests/verifier.c
> +++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
> @@ -77,6 +77,7 @@
> #include "verifier_xadd.skel.h"
> #include "verifier_xdp.skel.h"
> #include "verifier_xdp_direct_packet_access.skel.h"
> +#include "verifier_range.skel.h"
>
> #define MAX_ENTRIES 11
>
> @@ -184,6 +185,7 @@ void test_verifier_var_off(void) { RUN(verifier_var_off); }
> void test_verifier_xadd(void) { RUN(verifier_xadd); }
> void test_verifier_xdp(void) { RUN(verifier_xdp); }
> void test_verifier_xdp_direct_packet_access(void) { RUN(verifier_xdp_direct_packet_access); }
> +void test_verifier_range(void) { RUN(verifier_range); }
>
> static int init_test_val_map(struct bpf_object *obj, char *map_name)
> {
> diff --git a/tools/testing/selftests/bpf/progs/verifier_range.c b/tools/testing/selftests/bpf/progs/verifier_range.c
> new file mode 100644
> index 000000000000..27597eb8135c
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/progs/verifier_range.c
> @@ -0,0 +1,25 @@
> +#include <linux/bpf.h>
> +#include <bpf/bpf_helpers.h>
> +#include "bpf_misc.h"
> +
> +SEC("?tc")
> +__log_level(2)
> +int test_verifier_range(void)
> +{
> + asm volatile (
> + "r5 = 100; \
> + r5 /= 3; \
> + w5 >>= 7; \
> + r5 &= -386969681; \
> + r5 -= -884670597; \
> + w0 = w5; \
> + if w0 & 0x894b6a55 goto +2; \
So actually it is 'if w0 & 0x894b6a55 goto +2' failed
the compilation.
Indeed, the above operation is not supported in llvm.
See
https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFInstrFormats.td#L62-L74
the missing BPFJumpOp<0x4> which corresponds to JSET.
The following llvm patch (on top of llvm-project main branch):
diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
index 841d97efc01c..6ed83d877ac0 100644
--- a/llvm/lib/Target/BPF/BPFInstrFormats.td
+++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
@@ -63,6 +63,7 @@ def BPF_JA : BPFJumpOp<0x0>;
def BPF_JEQ : BPFJumpOp<0x1>;
def BPF_JGT : BPFJumpOp<0x2>;
def BPF_JGE : BPFJumpOp<0x3>;
+def BPF_JSET : BPFJumpOp<0x4>;
def BPF_JNE : BPFJumpOp<0x5>;
def BPF_JSGT : BPFJumpOp<0x6>;
def BPF_JSGE : BPFJumpOp<0x7>;
diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 305cbbd34d27..9e75f35efe70 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
let BPFClass = BPF_JMP32;
}
+class JSET_RR<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+ (outs),
+ (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $src goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<4> src;
+ bits<16> BrDst;
+
+ let Inst{55-52} = src;
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let BPFClass = BPF_JMP;
+}
+
+class JSET_RI<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+ (outs),
+ (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $imm goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<16> BrDst;
+ bits<32> imm;
+
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let Inst{31-0} = imm;
+ let BPFClass = BPF_JMP;
+}
+
+class JSET_RR_32<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+ (outs),
+ (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $src goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<4> src;
+ bits<16> BrDst;
+
+ let Inst{55-52} = src;
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let BPFClass = BPF_JMP32;
+}
+
+class JSET_RI_32<string OpcodeStr>
+ : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+ (outs),
+ (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
+ "if $dst "#OpcodeStr#" $imm goto $BrDst",
+ []> {
+ bits<4> dst;
+ bits<16> BrDst;
+ bits<32> imm;
+
+ let Inst{51-48} = dst;
+ let Inst{47-32} = BrDst;
+ let Inst{31-0} = imm;
+ let BPFClass = BPF_JMP32;
+}
+
multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
@@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
+def JSET_RR : JSET_RR<"&">;
+def JSET_RI : JSET_RI<"&">;
+def JSET_RR_32 : JSET_RR_32<"&">;
+def JSET_RI_32 : JSET_RI_32<"&">;
}
// ALU instructions
can solve your inline asm issue. We will discuss whether llvm compiler
should be implementing this instruction from source or not.
> + r2 = 1; \
> + r2 = 1; \
> + r0 = 0; \
> + "
> + );
> + return 0;
> +}
> +
> +char _license[] SEC("license") = "GPL";
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH] C inlined assembly for reproducing max<min
2023-11-22 18:08 ` Yonghong Song
@ 2023-11-22 18:15 ` Alexei Starovoitov
2023-11-22 18:37 ` Jose E. Marchesi
2023-11-22 18:39 ` Eduard Zingerman
0 siblings, 2 replies; 10+ messages in thread
From: Alexei Starovoitov @ 2023-11-22 18:15 UTC (permalink / raw)
To: Yonghong Song, Jose E. Marchesi, Eddy Z
Cc: Tao Lyu, Andrii Nakryiko, Alexei Starovoitov, bpf,
Daniel Borkmann, Hao Luo, Martin KaFai Lau, mathias.payer,
meng.xu.cs, sanidhya.kashyap, Song Liu
On Wed, Nov 22, 2023 at 10:08 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>
> > +SEC("?tc")
> > +__log_level(2)
> > +int test_verifier_range(void)
> > +{
> > + asm volatile (
> > + "r5 = 100; \
> > + r5 /= 3; \
> > + w5 >>= 7; \
> > + r5 &= -386969681; \
> > + r5 -= -884670597; \
> > + w0 = w5; \
> > + if w0 & 0x894b6a55 goto +2; \
>
> So actually it is 'if w0 & 0x894b6a55 goto +2' failed
> the compilation.
>
> Indeed, the above operation is not supported in llvm.
> See
> https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFInstrFormats.td#L62-L74
> the missing BPFJumpOp<0x4> which corresponds to JSET.
>
> The following llvm patch (on top of llvm-project main branch):
>
> diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
> index 841d97efc01c..6ed83d877ac0 100644
> --- a/llvm/lib/Target/BPF/BPFInstrFormats.td
> +++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
> @@ -63,6 +63,7 @@ def BPF_JA : BPFJumpOp<0x0>;
> def BPF_JEQ : BPFJumpOp<0x1>;
> def BPF_JGT : BPFJumpOp<0x2>;
> def BPF_JGE : BPFJumpOp<0x3>;
> +def BPF_JSET : BPFJumpOp<0x4>;
> def BPF_JNE : BPFJumpOp<0x5>;
> def BPF_JSGT : BPFJumpOp<0x6>;
> def BPF_JSGE : BPFJumpOp<0x7>;
> diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
> index 305cbbd34d27..9e75f35efe70 100644
> --- a/llvm/lib/Target/BPF/BPFInstrInfo.td
> +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
> @@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
> let BPFClass = BPF_JMP32;
> }
>
> +class JSET_RR<string OpcodeStr>
> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
> + (outs),
> + (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
> + "if $dst "#OpcodeStr#" $src goto $BrDst",
> + []> {
> + bits<4> dst;
> + bits<4> src;
> + bits<16> BrDst;
> +
> + let Inst{55-52} = src;
> + let Inst{51-48} = dst;
> + let Inst{47-32} = BrDst;
> + let BPFClass = BPF_JMP;
> +}
> +
> +class JSET_RI<string OpcodeStr>
> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
> + (outs),
> + (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
> + []> {
> + bits<4> dst;
> + bits<16> BrDst;
> + bits<32> imm;
> +
> + let Inst{51-48} = dst;
> + let Inst{47-32} = BrDst;
> + let Inst{31-0} = imm;
> + let BPFClass = BPF_JMP;
> +}
> +
> +class JSET_RR_32<string OpcodeStr>
> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
> + (outs),
> + (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
> + "if $dst "#OpcodeStr#" $src goto $BrDst",
> + []> {
> + bits<4> dst;
> + bits<4> src;
> + bits<16> BrDst;
> +
> + let Inst{55-52} = src;
> + let Inst{51-48} = dst;
> + let Inst{47-32} = BrDst;
> + let BPFClass = BPF_JMP32;
> +}
> +
> +class JSET_RI_32<string OpcodeStr>
> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
> + (outs),
> + (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
> + []> {
> + bits<4> dst;
> + bits<16> BrDst;
> + bits<32> imm;
> +
> + let Inst{51-48} = dst;
> + let Inst{47-32} = BrDst;
> + let Inst{31-0} = imm;
> + let BPFClass = BPF_JMP32;
> +}
> +
> multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
> def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
> def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
> @@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
> defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
> defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
> defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
> +def JSET_RR : JSET_RR<"&">;
> +def JSET_RI : JSET_RI<"&">;
> +def JSET_RR_32 : JSET_RR_32<"&">;
> +def JSET_RI_32 : JSET_RI_32<"&">;
> }
>
> // ALU instructions
>
> can solve your inline asm issue. We will discuss whether llvm compiler
> should be implementing this instruction from source or not.
I'd say 'yes'. clang/llvm should support such asm syntax.
Jose, Eduard,
Thoughts?
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] C inlined assembly for reproducing max<min
2023-11-22 18:15 ` Alexei Starovoitov
@ 2023-11-22 18:37 ` Jose E. Marchesi
2023-11-22 18:51 ` Yonghong Song
2023-11-22 18:39 ` Eduard Zingerman
1 sibling, 1 reply; 10+ messages in thread
From: Jose E. Marchesi @ 2023-11-22 18:37 UTC (permalink / raw)
To: Alexei Starovoitov
Cc: Yonghong Song, Eddy Z, Tao Lyu, Andrii Nakryiko,
Alexei Starovoitov, bpf, Daniel Borkmann, Hao Luo,
Martin KaFai Lau, mathias.payer, meng.xu.cs, sanidhya.kashyap,
Song Liu
> On Wed, Nov 22, 2023 at 10:08 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>>
>> > +SEC("?tc")
>> > +__log_level(2)
>> > +int test_verifier_range(void)
>> > +{
>> > + asm volatile (
>> > + "r5 = 100; \
>> > + r5 /= 3; \
>> > + w5 >>= 7; \
>> > + r5 &= -386969681; \
>> > + r5 -= -884670597; \
>> > + w0 = w5; \
>> > + if w0 & 0x894b6a55 goto +2; \
>>
>> So actually it is 'if w0 & 0x894b6a55 goto +2' failed
>> the compilation.
>>
>> Indeed, the above operation is not supported in llvm.
>> See
>> https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFInstrFormats.td#L62-L74
>> the missing BPFJumpOp<0x4> which corresponds to JSET.
>>
>> The following llvm patch (on top of llvm-project main branch):
>>
>> diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
>> index 841d97efc01c..6ed83d877ac0 100644
>> --- a/llvm/lib/Target/BPF/BPFInstrFormats.td
>> +++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
>> @@ -63,6 +63,7 @@ def BPF_JA : BPFJumpOp<0x0>;
>> def BPF_JEQ : BPFJumpOp<0x1>;
>> def BPF_JGT : BPFJumpOp<0x2>;
>> def BPF_JGE : BPFJumpOp<0x3>;
>> +def BPF_JSET : BPFJumpOp<0x4>;
>> def BPF_JNE : BPFJumpOp<0x5>;
>> def BPF_JSGT : BPFJumpOp<0x6>;
>> def BPF_JSGE : BPFJumpOp<0x7>;
>> diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
>> index 305cbbd34d27..9e75f35efe70 100644
>> --- a/llvm/lib/Target/BPF/BPFInstrInfo.td
>> +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
>> @@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
>> let BPFClass = BPF_JMP32;
>> }
>>
>> +class JSET_RR<string OpcodeStr>
>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
>> + (outs),
>> + (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
>> + "if $dst "#OpcodeStr#" $src goto $BrDst",
>> + []> {
>> + bits<4> dst;
>> + bits<4> src;
>> + bits<16> BrDst;
>> +
>> + let Inst{55-52} = src;
>> + let Inst{51-48} = dst;
>> + let Inst{47-32} = BrDst;
>> + let BPFClass = BPF_JMP;
>> +}
>> +
>> +class JSET_RI<string OpcodeStr>
>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
>> + (outs),
>> + (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
>> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
>> + []> {
>> + bits<4> dst;
>> + bits<16> BrDst;
>> + bits<32> imm;
>> +
>> + let Inst{51-48} = dst;
>> + let Inst{47-32} = BrDst;
>> + let Inst{31-0} = imm;
>> + let BPFClass = BPF_JMP;
>> +}
>> +
>> +class JSET_RR_32<string OpcodeStr>
>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
>> + (outs),
>> + (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
>> + "if $dst "#OpcodeStr#" $src goto $BrDst",
>> + []> {
>> + bits<4> dst;
>> + bits<4> src;
>> + bits<16> BrDst;
>> +
>> + let Inst{55-52} = src;
>> + let Inst{51-48} = dst;
>> + let Inst{47-32} = BrDst;
>> + let BPFClass = BPF_JMP32;
>> +}
>> +
>> +class JSET_RI_32<string OpcodeStr>
>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
>> + (outs),
>> + (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
>> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
>> + []> {
>> + bits<4> dst;
>> + bits<16> BrDst;
>> + bits<32> imm;
>> +
>> + let Inst{51-48} = dst;
>> + let Inst{47-32} = BrDst;
>> + let Inst{31-0} = imm;
>> + let BPFClass = BPF_JMP32;
>> +}
>> +
>> multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
>> def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
>> def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
>> @@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
>> defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
>> defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
>> defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
>> +def JSET_RR : JSET_RR<"&">;
>> +def JSET_RI : JSET_RI<"&">;
>> +def JSET_RR_32 : JSET_RR_32<"&">;
>> +def JSET_RI_32 : JSET_RI_32<"&">;
>> }
>>
>> // ALU instructions
>>
>> can solve your inline asm issue. We will discuss whether llvm compiler
>> should be implementing this instruction from source or not.
>
> I'd say 'yes'. clang/llvm should support such asm syntax.
>
> Jose, Eduard,
> Thoughts?
We already support it in GAS:
$ echo 'if w0 & 0x894b6a55 goto +2' | bpf-unknown-none-as -mdialect=pseudoc -
$ bpf-unknown-none-objdump -M hex,pseudoc -d a.out
a.out: file format elf64-bpfle
Disassembly of section .text:
0000000000000000 <.text>:
0: 46 00 02 00 55 6a 4b 89 if w0&0x894b6a55 goto 0x2
We weren't aware we were diverging with llvm by doing so. We support
syntax for all the conditional jump instructions using the following
operators:
BPF_JEQ ==
BPF_JGT >
BPF_JSGT s>
BPF_JGE >=
BPF_JSGE s>=
BPF_JLT <
BPF_JLST s<
BPF_JLE <=
BPF_JSLE s<=
BPF_JSET &
BPF_JNE !=
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] C inlined assembly for reproducing max<min
2023-11-22 18:15 ` Alexei Starovoitov
2023-11-22 18:37 ` Jose E. Marchesi
@ 2023-11-22 18:39 ` Eduard Zingerman
1 sibling, 0 replies; 10+ messages in thread
From: Eduard Zingerman @ 2023-11-22 18:39 UTC (permalink / raw)
To: Alexei Starovoitov, Yonghong Song, Jose E. Marchesi
Cc: Tao Lyu, Andrii Nakryiko, Alexei Starovoitov, bpf,
Daniel Borkmann, Hao Luo, Martin KaFai Lau, mathias.payer,
meng.xu.cs, sanidhya.kashyap, Song Liu
On Wed, 2023-11-22 at 10:15 -0800, Alexei Starovoitov wrote:
[...]
> > multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
> > def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
> > def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
> > @@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
> > defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
> > defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
> > defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
> > +def JSET_RR : JSET_RR<"&">;
> > +def JSET_RI : JSET_RI<"&">;
> > +def JSET_RR_32 : JSET_RR_32<"&">;
> > +def JSET_RI_32 : JSET_RI_32<"&">;
> > }
> >
> > // ALU instructions
> >
> > can solve your inline asm issue. We will discuss whether llvm compiler
> > should be implementing this instruction from source or not.
>
> I'd say 'yes'. clang/llvm should support such asm syntax.
>
> Jose, Eduard,
> Thoughts?
I agree, since instruction is documented it should have assembly
representation. All other instructions from instruction-set.rst seem
to have one.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] C inlined assembly for reproducing max<min
2023-11-22 18:37 ` Jose E. Marchesi
@ 2023-11-22 18:51 ` Yonghong Song
0 siblings, 0 replies; 10+ messages in thread
From: Yonghong Song @ 2023-11-22 18:51 UTC (permalink / raw)
To: Jose E. Marchesi, Alexei Starovoitov
Cc: Eddy Z, Tao Lyu, Andrii Nakryiko, Alexei Starovoitov, bpf,
Daniel Borkmann, Hao Luo, Martin KaFai Lau, mathias.payer,
meng.xu.cs, sanidhya.kashyap, Song Liu
On 11/22/23 1:37 PM, Jose E. Marchesi wrote:
>> On Wed, Nov 22, 2023 at 10:08 AM Yonghong Song <yonghong.song@linux.dev> wrote:
>>>> +SEC("?tc")
>>>> +__log_level(2)
>>>> +int test_verifier_range(void)
>>>> +{
>>>> + asm volatile (
>>>> + "r5 = 100; \
>>>> + r5 /= 3; \
>>>> + w5 >>= 7; \
>>>> + r5 &= -386969681; \
>>>> + r5 -= -884670597; \
>>>> + w0 = w5; \
>>>> + if w0 & 0x894b6a55 goto +2; \
>>> So actually it is 'if w0 & 0x894b6a55 goto +2' failed
>>> the compilation.
>>>
>>> Indeed, the above operation is not supported in llvm.
>>> See
>>> https://github.com/llvm/llvm-project/blob/main/llvm/lib/Target/BPF/BPFInstrFormats.td#L62-L74
>>> the missing BPFJumpOp<0x4> which corresponds to JSET.
>>>
>>> The following llvm patch (on top of llvm-project main branch):
>>>
>>> diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
>>> index 841d97efc01c..6ed83d877ac0 100644
>>> --- a/llvm/lib/Target/BPF/BPFInstrFormats.td
>>> +++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
>>> @@ -63,6 +63,7 @@ def BPF_JA : BPFJumpOp<0x0>;
>>> def BPF_JEQ : BPFJumpOp<0x1>;
>>> def BPF_JGT : BPFJumpOp<0x2>;
>>> def BPF_JGE : BPFJumpOp<0x3>;
>>> +def BPF_JSET : BPFJumpOp<0x4>;
>>> def BPF_JNE : BPFJumpOp<0x5>;
>>> def BPF_JSGT : BPFJumpOp<0x6>;
>>> def BPF_JSGE : BPFJumpOp<0x7>;
>>> diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
>>> index 305cbbd34d27..9e75f35efe70 100644
>>> --- a/llvm/lib/Target/BPF/BPFInstrInfo.td
>>> +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
>>> @@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
>>> let BPFClass = BPF_JMP32;
>>> }
>>>
>>> +class JSET_RR<string OpcodeStr>
>>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
>>> + (outs),
>>> + (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
>>> + "if $dst "#OpcodeStr#" $src goto $BrDst",
>>> + []> {
>>> + bits<4> dst;
>>> + bits<4> src;
>>> + bits<16> BrDst;
>>> +
>>> + let Inst{55-52} = src;
>>> + let Inst{51-48} = dst;
>>> + let Inst{47-32} = BrDst;
>>> + let BPFClass = BPF_JMP;
>>> +}
>>> +
>>> +class JSET_RI<string OpcodeStr>
>>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
>>> + (outs),
>>> + (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
>>> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
>>> + []> {
>>> + bits<4> dst;
>>> + bits<16> BrDst;
>>> + bits<32> imm;
>>> +
>>> + let Inst{51-48} = dst;
>>> + let Inst{47-32} = BrDst;
>>> + let Inst{31-0} = imm;
>>> + let BPFClass = BPF_JMP;
>>> +}
>>> +
>>> +class JSET_RR_32<string OpcodeStr>
>>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
>>> + (outs),
>>> + (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
>>> + "if $dst "#OpcodeStr#" $src goto $BrDst",
>>> + []> {
>>> + bits<4> dst;
>>> + bits<4> src;
>>> + bits<16> BrDst;
>>> +
>>> + let Inst{55-52} = src;
>>> + let Inst{51-48} = dst;
>>> + let Inst{47-32} = BrDst;
>>> + let BPFClass = BPF_JMP32;
>>> +}
>>> +
>>> +class JSET_RI_32<string OpcodeStr>
>>> + : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
>>> + (outs),
>>> + (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
>>> + "if $dst "#OpcodeStr#" $imm goto $BrDst",
>>> + []> {
>>> + bits<4> dst;
>>> + bits<16> BrDst;
>>> + bits<32> imm;
>>> +
>>> + let Inst{51-48} = dst;
>>> + let Inst{47-32} = BrDst;
>>> + let Inst{31-0} = imm;
>>> + let BPFClass = BPF_JMP32;
>>> +}
>>> +
>>> multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
>>> def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
>>> def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
>>> @@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
>>> defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
>>> defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
>>> defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
>>> +def JSET_RR : JSET_RR<"&">;
>>> +def JSET_RI : JSET_RI<"&">;
>>> +def JSET_RR_32 : JSET_RR_32<"&">;
>>> +def JSET_RI_32 : JSET_RI_32<"&">;
>>> }
>>>
>>> // ALU instructions
>>>
>>> can solve your inline asm issue. We will discuss whether llvm compiler
>>> should be implementing this instruction from source or not.
>> I'd say 'yes'. clang/llvm should support such asm syntax.
>>
>> Jose, Eduard,
>> Thoughts?
> We already support it in GAS:
>
>
> $ echo 'if w0 & 0x894b6a55 goto +2' | bpf-unknown-none-as -mdialect=pseudoc -
> $ bpf-unknown-none-objdump -M hex,pseudoc -d a.out
>
> a.out: file format elf64-bpfle
>
>
> Disassembly of section .text:
>
> 0000000000000000 <.text>:
> 0: 46 00 02 00 55 6a 4b 89 if w0&0x894b6a55 goto 0x2
>
>
> We weren't aware we were diverging with llvm by doing so. We support
> syntax for all the conditional jump instructions using the following
> operators:
>
> BPF_JEQ ==
> BPF_JGT >
> BPF_JSGT s>
> BPF_JGE >=
> BPF_JSGE s>=
> BPF_JLT <
> BPF_JLST s<
> BPF_JLE <=
> BPF_JSLE s<=
> BPF_JSET &
> BPF_JNE !=
Sounds good. Eduard inthe other thread has similar opinion. Will add asm support in llvm soon.
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: max<min after jset
2023-11-21 17:32 max<min after jset Tao Lyu
2023-11-22 0:25 ` Yonghong Song
@ 2023-11-28 4:16 ` Yonghong Song
2023-12-02 10:44 ` [PATCH] C inlined assembly for reproducing max<min Tao Lyu
1 sibling, 1 reply; 10+ messages in thread
From: Yonghong Song @ 2023-11-28 4:16 UTC (permalink / raw)
To: Tao Lyu, andrii, ast, daniel, song, haoluo, martin.lau
Cc: bpf, sanidhya.kashyap, mathias.payer, meng.xu.cs
On 11/21/23 12:32 PM, Tao Lyu wrote:
> Hi,
>
> The eBPF program shown below leads to an reversed min and max
> after insn 6 "if w0 & 0x894b6a55 goto +2",
> whic means max < min.
>
> Here is the introduction how it happens.
>
> Before insn 6,
> the range of r0 expressed by the min and max field is
> min1 = 884670597, max1 = 900354100
> And the range expressed by the var_off=(0x34000000; 0x1ff5fbf))
> is min2=872415232, max2=905928639.
>
> ---min2-----------------------min1-----max1-----max2---
>
> Here we can see that the range expressed by var_off is wider than that of min and max.
>
> When verifying insn6,
> it first uses the var_off and immediate "0x894b6a55" to
> calculate the new var_off=(0x34b00000; 0x415aa).
> The range expressed by the new var_off is:
> min3=883949568, max3=884217258
>
> ---min2-----min3-----max3-----min1-----max1-----max2---
>
> And then it will calculate the new min and max by:
> (1) new-min = MAX(min3, min1) = min1
> (2) new-max = MIN(max3, max1) = max3
>
> ---min2-----min3-----max3-----min1-----max1-----max2---
> "new-max" "new-min"
>
> Now, the new-max becomes less than the new min.
>
> Notably, [min1, max1] can never make "w0 & 0x894b6a55 == 0"
> and thus cannot goes the fall-through branch.
> In other words, actually the fall-trough branch is a dead path.
>
> BTW, I cannot successfully compile this instruciton "if w0 != 0 goto +2;\"
> in the c inline assembly code.
> So I can only attach the bytecodes.
>
> Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
> ---
> .../selftests/bpf/verifier/jset_reversed_range.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/verifier/jset_reversed_range.c
>
> diff --git a/tools/testing/selftests/bpf/verifier/jset_reversed_range.c b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
> new file mode 100644
> index 000000000000..734f492a2a96
> --- /dev/null
> +++ b/tools/testing/selftests/bpf/verifier/jset_reversed_range.c
> @@ -0,0 +1,15 @@
> +{
> + "BPF_JSET: incorrect scalar range",
> + .insns = {
> + BPF_MOV64_IMM(BPF_REG_5, 100),
> + BPF_ALU64_IMM(BPF_DIV, BPF_REG_5, 3),
> + BPF_ALU32_IMM(BPF_RSH, BPF_REG_5, 7),
> + BPF_ALU64_IMM(BPF_AND, BPF_REG_5, -386969681),
> + BPF_ALU64_IMM(BPF_SUB, BPF_REG_5, -884670597),
> + BPF_MOV32_REG(BPF_REG_0, BPF_REG_5),
> + BPF_JMP32_IMM(BPF_JSET, BPF_REG_0, 0x894b6a55, 1),
> + BPF_MOV64_IMM(BPF_REG_0, 1),
> + BPF_MOV64_IMM(BPF_REG_0, 0),
> + BPF_EXIT_INSN(),
> + },
> +},
Tao Lyu,
The llvm patch to support BPF_JSET asm has been merged into upstream.
https://github.com/yonghong-song/llvm-project/commit/e247e6ff272ce70003ca67f62be178f332f9de0f
Now you can write inline asm code with BPF_JSET insn with latest llvm18.
If you intend to submit a patch to the kernel, please guard the test case
with
#if __clang_major__ >= 18
This should also facilitate to add inline asm test cases with BPF_JSET
in bpf selftests.
Thanks,
Yonghong
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH] C inlined assembly for reproducing max<min
2023-11-28 4:16 ` max<min after jset Yonghong Song
@ 2023-12-02 10:44 ` Tao Lyu
0 siblings, 0 replies; 10+ messages in thread
From: Tao Lyu @ 2023-12-02 10:44 UTC (permalink / raw)
To: yonghong.song; +Cc: andrii, ast, bpf, daniel, haoluo, martin.lau, song, tao.lyu
Hi,
We discussed the max<min issue in [1].
But it cannot reproduced with a C inlined assembly test,
as llvm doesn't support 'jset' assembly.
Thanks to Yonghong's patch [2],
it is now supported in the latest llvm-18.
So, I resubmit the C inlined assembly test for the max<min issue here again.
[1] https://lore.kernel.org/bpf/20231121173206.3594040-1-tao.lyu@epfl.ch/
[2] https://github.com/yonghong-song/llvm-project/commit/e247e6ff272ce70003ca67f62be178f332f9de0f
Signed-off-by: Tao Lyu <tao.lyu@epfl.ch>
---
.../selftests/bpf/prog_tests/verifier.c | 2 ++
.../selftests/bpf/progs/verifier_range.c | 29 +++++++++++++++++++
2 files changed, 31 insertions(+)
create mode 100644 tools/testing/selftests/bpf/progs/verifier_range.c
diff --git a/tools/testing/selftests/bpf/prog_tests/verifier.c b/tools/testing/selftests/bpf/prog_tests/verifier.c
index e5c61aa6604a..3a5d746f392d 100644
--- a/tools/testing/selftests/bpf/prog_tests/verifier.c
+++ b/tools/testing/selftests/bpf/prog_tests/verifier.c
@@ -77,6 +77,7 @@
#include "verifier_xadd.skel.h"
#include "verifier_xdp.skel.h"
#include "verifier_xdp_direct_packet_access.skel.h"
+#include "verifier_range.skel.h"
#define MAX_ENTRIES 11
@@ -184,6 +185,7 @@ void test_verifier_var_off(void) { RUN(verifier_var_off); }
void test_verifier_xadd(void) { RUN(verifier_xadd); }
void test_verifier_xdp(void) { RUN(verifier_xdp); }
void test_verifier_xdp_direct_packet_access(void) { RUN(verifier_xdp_direct_packet_access); }
+void test_verifier_range(void) { RUN(verifier_range); }
static int init_test_val_map(struct bpf_object *obj, char *map_name)
{
diff --git a/tools/testing/selftests/bpf/progs/verifier_range.c b/tools/testing/selftests/bpf/progs/verifier_range.c
new file mode 100644
index 000000000000..affe09117b0f
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/verifier_range.c
@@ -0,0 +1,29 @@
+#include <linux/bpf.h>
+#include <bpf/bpf_helpers.h>
+#include "bpf_misc.h"
+
+#if __clang_major__ >= 18
+
+SEC("?tc")
+__log_level(2)
+int test_verifier_range(void)
+{
+ asm volatile (
+ "r5 = 100; \
+ r5 /= 3; \
+ w5 >>= 7; \
+ r5 &= -386969681; \
+ r5 -= -884670597; \
+ w0 = w5; \
+ if w0 & 0x894b6a55 goto +2; \
+ r2 = 1; \
+ r2 = 1; \
+ r0 = 0; \
+ "
+ );
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+
+#endif
--
2.25.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2023-12-02 10:44 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-21 17:32 max<min after jset Tao Lyu
2023-11-22 0:25 ` Yonghong Song
2023-11-22 14:40 ` [PATCH] C inlined assembly for reproducing max<min Tao Lyu
2023-11-22 18:08 ` Yonghong Song
2023-11-22 18:15 ` Alexei Starovoitov
2023-11-22 18:37 ` Jose E. Marchesi
2023-11-22 18:51 ` Yonghong Song
2023-11-22 18:39 ` Eduard Zingerman
2023-11-28 4:16 ` max<min after jset Yonghong Song
2023-12-02 10:44 ` [PATCH] C inlined assembly for reproducing max<min Tao Lyu
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox