bpf: Add helper macro bpf_addr_space_cast()
authorAlexei Starovoitov <ast@kernel.org>
Fri, 8 Mar 2024 01:08:09 +0000 (17:08 -0800)
committerAndrii Nakryiko <andrii@kernel.org>
Mon, 11 Mar 2024 22:43:42 +0000 (15:43 -0700)
Introduce helper macro bpf_addr_space_cast() that emits:
rX = rX
instruction with off = BPF_ADDR_SPACE_CAST
and encodes dest and src address_space-s into imm32.

It's useful with older LLVM that doesn't emit this insn automatically.

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/bpf/20240308010812.89848-12-alexei.starovoitov@gmail.com
tools/testing/selftests/bpf/bpf_experimental.h

index bc9a0832ae725a50af1c504e480bae3a3d485e82..a5b9df38c162595c8c63420d3eb425149eddeef7 100644 (file)
@@ -343,6 +343,49 @@ l_true:                                                                                            \
        asm volatile("%[reg]=%[reg]"::[reg]"r"((short)var))
 #endif
 
+/* emit instruction:
+ * rX = rX .off = BPF_ADDR_SPACE_CAST .imm32 = (dst_as << 16) | src_as
+ */
+#ifndef bpf_addr_space_cast
+#define bpf_addr_space_cast(var, dst_as, src_as)\
+       asm volatile(".byte 0xBF;               \
+                    .ifc %[reg], r0;           \
+                    .byte 0x00;                \
+                    .endif;                    \
+                    .ifc %[reg], r1;           \
+                    .byte 0x11;                \
+                    .endif;                    \
+                    .ifc %[reg], r2;           \
+                    .byte 0x22;                \
+                    .endif;                    \
+                    .ifc %[reg], r3;           \
+                    .byte 0x33;                \
+                    .endif;                    \
+                    .ifc %[reg], r4;           \
+                    .byte 0x44;                \
+                    .endif;                    \
+                    .ifc %[reg], r5;           \
+                    .byte 0x55;                \
+                    .endif;                    \
+                    .ifc %[reg], r6;           \
+                    .byte 0x66;                \
+                    .endif;                    \
+                    .ifc %[reg], r7;           \
+                    .byte 0x77;                \
+                    .endif;                    \
+                    .ifc %[reg], r8;           \
+                    .byte 0x88;                \
+                    .endif;                    \
+                    .ifc %[reg], r9;           \
+                    .byte 0x99;                \
+                    .endif;                    \
+                    .short %[off];             \
+                    .long %[as]"               \
+                    : [reg]"+r"(var)           \
+                    : [off]"i"(BPF_ADDR_SPACE_CAST) \
+                    , [as]"i"((dst_as << 16) | src_as));
+#endif
+
 /* Description
  *     Assert that a conditional expression is true.
  * Returns