* [PATCH bpf-next 0/2] Factor common x86 JIT code
@ 2020-06-29 9:33 Tobias Klauser
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
2020-06-29 9:33 ` [PATCH bpf-next 2/2] bpf, x86: Factor out get_cond_jmp_opcode and use for 64bit x86 Tobias Klauser
0 siblings, 2 replies; 6+ messages in thread
From: Tobias Klauser @ 2020-06-29 9:33 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Wang YanQing; +Cc: bpf, netdev, x86
Factor out code common for 32-bit and 64-bit x86 BPF JITs.
Tobias Klauser (2):
bpf, x86: Factor common x86 JIT code
bpf, x86: Factor out get_cond_jmp_opcode and use for 64bit x86
MAINTAINERS | 3 +-
arch/x86/net/Makefile | 4 +-
arch/x86/net/bpf_jit.h | 97 ++++++++++
arch/x86/net/bpf_jit_comp32.c | 178 ++----------------
.../net/{bpf_jit_comp.c => bpf_jit_comp64.c} | 130 +------------
arch/x86/net/bpf_jit_core.c | 76 ++++++++
6 files changed, 194 insertions(+), 294 deletions(-)
create mode 100644 arch/x86/net/bpf_jit.h
rename arch/x86/net/{bpf_jit_comp.c => bpf_jit_comp64.c} (94%)
create mode 100644 arch/x86/net/bpf_jit_core.c
--
2.27.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH bpf-next 1/2] bpf, x86: Factor common x86 JIT code
2020-06-29 9:33 [PATCH bpf-next 0/2] Factor common x86 JIT code Tobias Klauser
@ 2020-06-29 9:33 ` Tobias Klauser
2020-06-29 17:48 ` Alexei Starovoitov
` (2 more replies)
2020-06-29 9:33 ` [PATCH bpf-next 2/2] bpf, x86: Factor out get_cond_jmp_opcode and use for 64bit x86 Tobias Klauser
1 sibling, 3 replies; 6+ messages in thread
From: Tobias Klauser @ 2020-06-29 9:33 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Wang YanQing; +Cc: bpf, netdev, x86
Factor out code common for 32-bit and 64-bit x86 BPF JITs to bpf_jit.h
Also follow other architectures and rename bpf_jit_comp.c to
bpf_jit_comp64.c to be more explicit.
Also adjust the file matching pattern in MAINTAINERS such that the
common x86 files are included for both the 32-bit and 64-bit BPF JIT
sections.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
MAINTAINERS | 3 +-
arch/x86/net/Makefile | 2 +-
arch/x86/net/bpf_jit.h | 93 ++++++++++++
arch/x86/net/bpf_jit_comp32.c | 135 ++++--------------
.../net/{bpf_jit_comp.c => bpf_jit_comp64.c} | 84 +----------
5 files changed, 123 insertions(+), 194 deletions(-)
create mode 100644 arch/x86/net/bpf_jit.h
rename arch/x86/net/{bpf_jit_comp.c => bpf_jit_comp64.c} (96%)
diff --git a/MAINTAINERS b/MAINTAINERS
index 301330e02bca..509e0c6a9590 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3326,7 +3326,8 @@ M: Wang YanQing <udknight@gmail.com>
L: netdev@vger.kernel.org
L: bpf@vger.kernel.org
S: Maintained
-F: arch/x86/net/bpf_jit_comp32.c
+F: arch/x86/net/
+X: arch/x86/net/bpf_jit_comp64.c
BPF JIT for X86 64-BIT
M: Alexei Starovoitov <ast@kernel.org>
diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile
index 383c87300b0d..bf71548fad2c 100644
--- a/arch/x86/net/Makefile
+++ b/arch/x86/net/Makefile
@@ -6,5 +6,5 @@
ifeq ($(CONFIG_X86_32),y)
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
else
- obj-$(CONFIG_BPF_JIT) += bpf_jit_comp.o
+ obj-$(CONFIG_BPF_JIT) += bpf_jit_comp64.o
endif
diff --git a/arch/x86/net/bpf_jit.h b/arch/x86/net/bpf_jit.h
new file mode 100644
index 000000000000..44cbab10962a
--- /dev/null
+++ b/arch/x86/net/bpf_jit.h
@@ -0,0 +1,93 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Common functionality for x86 32-bit and 64-bit BPF JIT compilers
+ */
+#ifndef _BPF_JIT_H
+#define _BPF_JIT_H
+
+#include <linux/bpf.h>
+
+static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
+{
+ if (len == 1)
+ *ptr = bytes;
+ else if (len == 2)
+ *(u16 *)ptr = bytes;
+ else {
+ *(u32 *)ptr = bytes;
+ barrier();
+ }
+ return ptr + len;
+}
+
+#define EMIT(bytes, len) \
+ do { prog = emit_code(prog, bytes, len); cnt += len; } while (0)
+
+#define EMIT1(b1) EMIT(b1, 1)
+#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
+#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
+#define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
+
+#define EMIT1_off32(b1, off) \
+ do { EMIT1(b1); EMIT(off, 4); } while (0)
+#define EMIT2_off32(b1, b2, off) \
+ do { EMIT2(b1, b2); EMIT(off, 4); } while (0)
+#define EMIT3_off32(b1, b2, b3, off) \
+ do { EMIT3(b1, b2, b3); EMIT(off, 4); } while (0)
+#define EMIT4_off32(b1, b2, b3, b4, off) \
+ do { EMIT4(b1, b2, b3, b4); EMIT(off, 4); } while (0)
+
+static inline bool is_imm8(int value)
+{
+ return value <= 127 && value >= -128;
+}
+
+static inline bool is_simm32(s64 value)
+{
+ return value == (s64)(s32)value;
+}
+
+static inline int bpf_size_to_x86_bytes(int bpf_size)
+{
+ if (bpf_size == BPF_W)
+ return 4;
+ else if (bpf_size == BPF_H)
+ return 2;
+ else if (bpf_size == BPF_B)
+ return 1;
+ else if (bpf_size == BPF_DW)
+ return 4; /* imm32 */
+ else
+ return 0;
+}
+
+/*
+ * List of x86 cond jumps opcodes (. + s8)
+ * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
+ */
+#define X86_JB 0x72
+#define X86_JAE 0x73
+#define X86_JE 0x74
+#define X86_JNE 0x75
+#define X86_JBE 0x76
+#define X86_JA 0x77
+#define X86_JL 0x7C
+#define X86_JGE 0x7D
+#define X86_JLE 0x7E
+#define X86_JG 0x7F
+
+/* Maximum number of bytes emitted while JITing one eBPF insn */
+#define BPF_MAX_INSN_SIZE 128
+#define BPF_INSN_SAFETY 64
+
+static inline void jit_fill_hole(void *area, unsigned int size)
+{
+ /* Fill whole space with INT3 instructions */
+ memset(area, 0xcc, size);
+}
+
+struct jit_context {
+ int cleanup_addr; /* Epilogue code offset */
+};
+
+#endif /* _BPF_JIT_H */
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
index 96fde03aa987..aabb44e08737 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -16,6 +16,7 @@
#include <asm/set_memory.h>
#include <asm/nospec-branch.h>
#include <linux/bpf.h>
+#include "bpf_jit.h"
/*
* eBPF prog stack layout:
@@ -47,49 +48,8 @@
* low
*/
-static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
-{
- if (len == 1)
- *ptr = bytes;
- else if (len == 2)
- *(u16 *)ptr = bytes;
- else {
- *(u32 *)ptr = bytes;
- barrier();
- }
- return ptr + len;
-}
-
-#define EMIT(bytes, len) \
- do { prog = emit_code(prog, bytes, len); cnt += len; } while (0)
-
-#define EMIT1(b1) EMIT(b1, 1)
-#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
-#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
-#define EMIT4(b1, b2, b3, b4) \
- EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
-
-#define EMIT1_off32(b1, off) \
- do { EMIT1(b1); EMIT(off, 4); } while (0)
-#define EMIT2_off32(b1, b2, off) \
- do { EMIT2(b1, b2); EMIT(off, 4); } while (0)
-#define EMIT3_off32(b1, b2, b3, off) \
- do { EMIT3(b1, b2, b3); EMIT(off, 4); } while (0)
-#define EMIT4_off32(b1, b2, b3, b4, off) \
- do { EMIT4(b1, b2, b3, b4); EMIT(off, 4); } while (0)
-
#define jmp_label(label, jmp_insn_len) (label - cnt - jmp_insn_len)
-static bool is_imm8(int value)
-{
- return value <= 127 && value >= -128;
-}
-
-static bool is_simm32(s64 value)
-{
- return value == (s64) (s32) value;
-}
-
#define STACK_OFFSET(k) (k)
#define TCALL_CNT (MAX_BPF_JIT_REG + 0) /* Tail Call Count */
@@ -102,21 +62,6 @@ static bool is_simm32(s64 value)
#define IA32_EBP (0x5)
#define IA32_ESP (0x4)
-/*
- * List of x86 cond jumps opcodes (. + s8)
- * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
- */
-#define IA32_JB 0x72
-#define IA32_JAE 0x73
-#define IA32_JE 0x74
-#define IA32_JNE 0x75
-#define IA32_JBE 0x76
-#define IA32_JA 0x77
-#define IA32_JL 0x7C
-#define IA32_JGE 0x7D
-#define IA32_JLE 0x7E
-#define IA32_JG 0x7F
-
#define COND_JMP_OPCODE_INVALID (0xFF)
/*
@@ -196,12 +141,6 @@ static u8 add_2reg(u8 byte, u32 dst_reg, u32 src_reg)
return byte + dst_reg + (src_reg << 3);
}
-static void jit_fill_hole(void *area, unsigned int size)
-{
- /* Fill whole space with int3 instructions */
- memset(area, 0xcc, size);
-}
-
static inline void emit_ia32_mov_i(const u8 dst, const u32 val, bool dstk,
u8 **pprog)
{
@@ -760,7 +699,7 @@ static inline void emit_ia32_lsh_r64(const u8 dst[], const u8 src[],
/* cmp ecx,32 */
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
/* skip the next two instructions (4 bytes) when < 32 */
- EMIT2(IA32_JB, 4);
+ EMIT2(X86_JB, 4);
/* mov dreg_hi,dreg_lo */
EMIT2(0x89, add_2reg(0xC0, dreg_hi, dreg_lo));
@@ -813,7 +752,7 @@ static inline void emit_ia32_arsh_r64(const u8 dst[], const u8 src[],
/* cmp ecx,32 */
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
/* skip the next two instructions (5 bytes) when < 32 */
- EMIT2(IA32_JB, 5);
+ EMIT2(X86_JB, 5);
/* mov dreg_lo,dreg_hi */
EMIT2(0x89, add_2reg(0xC0, dreg_lo, dreg_hi));
@@ -866,7 +805,7 @@ static inline void emit_ia32_rsh_r64(const u8 dst[], const u8 src[], bool dstk,
/* cmp ecx,32 */
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), 32);
/* skip the next two instructions (4 bytes) when < 32 */
- EMIT2(IA32_JB, 4);
+ EMIT2(X86_JB, 4);
/* mov dreg_lo,dreg_hi */
EMIT2(0x89, add_2reg(0xC0, dreg_lo, dreg_hi));
@@ -1168,28 +1107,6 @@ static inline void emit_ia32_mul_i64(const u8 dst[], const u32 val,
*pprog = prog;
}
-static int bpf_size_to_x86_bytes(int bpf_size)
-{
- if (bpf_size == BPF_W)
- return 4;
- else if (bpf_size == BPF_H)
- return 2;
- else if (bpf_size == BPF_B)
- return 1;
- else if (bpf_size == BPF_DW)
- return 4; /* imm32 */
- else
- return 0;
-}
-
-struct jit_context {
- int cleanup_addr; /* Epilogue code offset */
-};
-
-/* Maximum number of bytes emitted while JITing one eBPF insn */
-#define BPF_MAX_INSN_SIZE 128
-#define BPF_INSN_SAFETY 64
-
#define PROLOGUE_SIZE 35
/*
@@ -1304,7 +1221,7 @@ static void emit_bpf_tail_call(u8 **pprog)
EMIT3(0x39, add_2reg(0x40, IA32_EAX, IA32_EDX),
offsetof(struct bpf_array, map.max_entries));
/* jbe out */
- EMIT2(IA32_JBE, jmp_label(jmp_label1, 2));
+ EMIT2(X86_JBE, jmp_label(jmp_label1, 2));
/*
* if (tail_call_cnt > MAX_TAIL_CALL_CNT)
@@ -1317,12 +1234,12 @@ static void emit_bpf_tail_call(u8 **pprog)
/* cmp edx,hi */
EMIT3(0x83, add_1reg(0xF8, IA32_EBX), hi);
- EMIT2(IA32_JNE, 3);
+ EMIT2(X86_JNE, 3);
/* cmp ecx,lo */
EMIT3(0x83, add_1reg(0xF8, IA32_ECX), lo);
/* ja out */
- EMIT2(IA32_JAE, jmp_label(jmp_label1, 2));
+ EMIT2(X86_JAE, jmp_label(jmp_label1, 2));
/* add eax,0x1 */
EMIT3(0x83, add_1reg(0xC0, IA32_ECX), 0x01);
@@ -1345,7 +1262,7 @@ static void emit_bpf_tail_call(u8 **pprog)
/* test edx,edx */
EMIT2(0x85, add_2reg(0xC0, IA32_EDX, IA32_EDX));
/* je out */
- EMIT2(IA32_JE, jmp_label(jmp_label1, 2));
+ EMIT2(X86_JE, jmp_label(jmp_label1, 2));
/* goto *(prog->bpf_func + prologue_size); */
/* mov edx, dword ptr [edx + 32] */
@@ -1397,59 +1314,59 @@ static u8 get_cond_jmp_opcode(const u8 op, bool is_cmp_lo)
/* Convert BPF opcode to x86 */
switch (op) {
case BPF_JEQ:
- jmp_cond = IA32_JE;
+ jmp_cond = X86_JE;
break;
case BPF_JSET:
case BPF_JNE:
- jmp_cond = IA32_JNE;
+ jmp_cond = X86_JNE;
break;
case BPF_JGT:
/* GT is unsigned '>', JA in x86 */
- jmp_cond = IA32_JA;
+ jmp_cond = X86_JA;
break;
case BPF_JLT:
/* LT is unsigned '<', JB in x86 */
- jmp_cond = IA32_JB;
+ jmp_cond = X86_JB;
break;
case BPF_JGE:
/* GE is unsigned '>=', JAE in x86 */
- jmp_cond = IA32_JAE;
+ jmp_cond = X86_JAE;
break;
case BPF_JLE:
/* LE is unsigned '<=', JBE in x86 */
- jmp_cond = IA32_JBE;
+ jmp_cond = X86_JBE;
break;
case BPF_JSGT:
if (!is_cmp_lo)
/* Signed '>', GT in x86 */
- jmp_cond = IA32_JG;
+ jmp_cond = X86_JG;
else
/* GT is unsigned '>', JA in x86 */
- jmp_cond = IA32_JA;
+ jmp_cond = X86_JA;
break;
case BPF_JSLT:
if (!is_cmp_lo)
/* Signed '<', LT in x86 */
- jmp_cond = IA32_JL;
+ jmp_cond = X86_JL;
else
/* LT is unsigned '<', JB in x86 */
- jmp_cond = IA32_JB;
+ jmp_cond = X86_JB;
break;
case BPF_JSGE:
if (!is_cmp_lo)
/* Signed '>=', GE in x86 */
- jmp_cond = IA32_JGE;
+ jmp_cond = X86_JGE;
else
/* GE is unsigned '>=', JAE in x86 */
- jmp_cond = IA32_JAE;
+ jmp_cond = X86_JAE;
break;
case BPF_JSLE:
if (!is_cmp_lo)
/* Signed '<=', LE in x86 */
- jmp_cond = IA32_JLE;
+ jmp_cond = X86_JLE;
else
/* LE is unsigned '<=', JBE in x86 */
- jmp_cond = IA32_JBE;
+ jmp_cond = X86_JBE;
break;
default: /* to silence GCC warning */
jmp_cond = COND_JMP_OPCODE_INVALID;
@@ -1972,7 +1889,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
if (is_jmp64) {
/* cmp dreg_hi,sreg_hi */
EMIT2(0x39, add_2reg(0xC0, dreg_hi, sreg_hi));
- EMIT2(IA32_JNE, 2);
+ EMIT2(X86_JNE, 2);
}
/* cmp dreg_lo,sreg_lo */
EMIT2(0x39, add_2reg(0xC0, dreg_lo, sreg_lo));
@@ -2007,7 +1924,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
/* cmp dreg_hi,sreg_hi */
EMIT2(0x39, add_2reg(0xC0, dreg_hi, sreg_hi));
- EMIT2(IA32_JNE, 10);
+ EMIT2(X86_JNE, 10);
/* cmp dreg_lo,sreg_lo */
EMIT2(0x39, add_2reg(0xC0, dreg_lo, sreg_lo));
goto emit_cond_jmp_signed;
@@ -2139,7 +2056,7 @@ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
EMIT2_off32(0xC7, add_1reg(0xC0, IA32_EBX), hi);
/* cmp dreg_hi,sreg_hi */
EMIT2(0x39, add_2reg(0xC0, dreg_hi, sreg_hi));
- EMIT2(IA32_JNE, 2);
+ EMIT2(X86_JNE, 2);
}
/* cmp dreg_lo,sreg_lo */
EMIT2(0x39, add_2reg(0xC0, dreg_lo, sreg_lo));
@@ -2184,7 +2101,7 @@ emit_cond_jmp: jmp_cond = get_cond_jmp_opcode(BPF_OP(code), false);
EMIT2_off32(0xC7, add_1reg(0xC0, IA32_EBX), hi);
/* cmp dreg_hi,sreg_hi */
EMIT2(0x39, add_2reg(0xC0, dreg_hi, sreg_hi));
- EMIT2(IA32_JNE, 10);
+ EMIT2(X86_JNE, 10);
/* cmp dreg_lo,sreg_lo */
EMIT2(0x39, add_2reg(0xC0, dreg_lo, sreg_lo));
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp64.c
similarity index 96%
rename from arch/x86/net/bpf_jit_comp.c
rename to arch/x86/net/bpf_jit_comp64.c
index 42b6709e6dc7..e8d0f784ab14 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp64.c
@@ -16,46 +16,7 @@
#include <asm/nospec-branch.h>
#include <asm/text-patching.h>
#include <asm/asm-prototypes.h>
-
-static u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
-{
- if (len == 1)
- *ptr = bytes;
- else if (len == 2)
- *(u16 *)ptr = bytes;
- else {
- *(u32 *)ptr = bytes;
- barrier();
- }
- return ptr + len;
-}
-
-#define EMIT(bytes, len) \
- do { prog = emit_code(prog, bytes, len); cnt += len; } while (0)
-
-#define EMIT1(b1) EMIT(b1, 1)
-#define EMIT2(b1, b2) EMIT((b1) + ((b2) << 8), 2)
-#define EMIT3(b1, b2, b3) EMIT((b1) + ((b2) << 8) + ((b3) << 16), 3)
-#define EMIT4(b1, b2, b3, b4) EMIT((b1) + ((b2) << 8) + ((b3) << 16) + ((b4) << 24), 4)
-
-#define EMIT1_off32(b1, off) \
- do { EMIT1(b1); EMIT(off, 4); } while (0)
-#define EMIT2_off32(b1, b2, off) \
- do { EMIT2(b1, b2); EMIT(off, 4); } while (0)
-#define EMIT3_off32(b1, b2, b3, off) \
- do { EMIT3(b1, b2, b3); EMIT(off, 4); } while (0)
-#define EMIT4_off32(b1, b2, b3, b4, off) \
- do { EMIT4(b1, b2, b3, b4); EMIT(off, 4); } while (0)
-
-static bool is_imm8(int value)
-{
- return value <= 127 && value >= -128;
-}
-
-static bool is_simm32(s64 value)
-{
- return value == (s64)(s32)value;
-}
+#include "bpf_jit.h"
static bool is_uimm32(u64 value)
{
@@ -69,35 +30,6 @@ static bool is_uimm32(u64 value)
EMIT3(add_2mod(0x48, DST, SRC), 0x89, add_2reg(0xC0, DST, SRC)); \
} while (0)
-static int bpf_size_to_x86_bytes(int bpf_size)
-{
- if (bpf_size == BPF_W)
- return 4;
- else if (bpf_size == BPF_H)
- return 2;
- else if (bpf_size == BPF_B)
- return 1;
- else if (bpf_size == BPF_DW)
- return 4; /* imm32 */
- else
- return 0;
-}
-
-/*
- * List of x86 cond jumps opcodes (. + s8)
- * Add 0x10 (and an extra 0x0f) to generate far jumps (. + s32)
- */
-#define X86_JB 0x72
-#define X86_JAE 0x73
-#define X86_JE 0x74
-#define X86_JNE 0x75
-#define X86_JBE 0x76
-#define X86_JA 0x77
-#define X86_JL 0x7C
-#define X86_JGE 0x7D
-#define X86_JLE 0x7E
-#define X86_JG 0x7F
-
/* Pick a register outside of BPF range for JIT internal work */
#define AUX_REG (MAX_BPF_JIT_REG + 1)
#define X86_REG_R9 (MAX_BPF_JIT_REG + 2)
@@ -205,20 +137,6 @@ static u8 add_2reg(u8 byte, u32 dst_reg, u32 src_reg)
return byte + reg2hex[dst_reg] + (reg2hex[src_reg] << 3);
}
-static void jit_fill_hole(void *area, unsigned int size)
-{
- /* Fill whole space with INT3 instructions */
- memset(area, 0xcc, size);
-}
-
-struct jit_context {
- int cleanup_addr; /* Epilogue code offset */
-};
-
-/* Maximum number of bytes emitted while JITing one eBPF insn */
-#define BPF_MAX_INSN_SIZE 128
-#define BPF_INSN_SAFETY 64
-
/* Number of bytes emit_patch() needs to generate instructions */
#define X86_PATCH_SIZE 5
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH bpf-next 2/2] bpf, x86: Factor out get_cond_jmp_opcode and use for 64bit x86
2020-06-29 9:33 [PATCH bpf-next 0/2] Factor common x86 JIT code Tobias Klauser
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
@ 2020-06-29 9:33 ` Tobias Klauser
1 sibling, 0 replies; 6+ messages in thread
From: Tobias Klauser @ 2020-06-29 9:33 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann, Wang YanQing; +Cc: bpf, netdev, x86
Factor out get_cond_jmp_opcode from bpf_jit_comp64.c and use it in
bpf_jit_comp64.c instead of open-coding it.
Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
---
arch/x86/net/Makefile | 2 +
arch/x86/net/bpf_jit.h | 4 ++
arch/x86/net/bpf_jit_comp32.c | 71 --------------------------------
arch/x86/net/bpf_jit_comp64.c | 46 ++-------------------
arch/x86/net/bpf_jit_core.c | 76 +++++++++++++++++++++++++++++++++++
5 files changed, 85 insertions(+), 114 deletions(-)
create mode 100644 arch/x86/net/bpf_jit_core.c
diff --git a/arch/x86/net/Makefile b/arch/x86/net/Makefile
index bf71548fad2c..541544cab139 100644
--- a/arch/x86/net/Makefile
+++ b/arch/x86/net/Makefile
@@ -3,6 +3,8 @@
# Arch-specific network modules
#
+obj-$(CONFIG_BPF_JIT) += bpf_jit_core.o
+
ifeq ($(CONFIG_X86_32),y)
obj-$(CONFIG_BPF_JIT) += bpf_jit_comp32.o
else
diff --git a/arch/x86/net/bpf_jit.h b/arch/x86/net/bpf_jit.h
index 44cbab10962a..355d96bfe9b3 100644
--- a/arch/x86/net/bpf_jit.h
+++ b/arch/x86/net/bpf_jit.h
@@ -76,6 +76,10 @@ static inline int bpf_size_to_x86_bytes(int bpf_size)
#define X86_JLE 0x7E
#define X86_JG 0x7F
+#define COND_JMP_OPCODE_INVALID (0xFF)
+
+u8 get_cond_jmp_opcode(const u8 op, bool is_cmp_lo);
+
/* Maximum number of bytes emitted while JITing one eBPF insn */
#define BPF_MAX_INSN_SIZE 128
#define BPF_INSN_SAFETY 64
diff --git a/arch/x86/net/bpf_jit_comp32.c b/arch/x86/net/bpf_jit_comp32.c
index aabb44e08737..90738fade68e 100644
--- a/arch/x86/net/bpf_jit_comp32.c
+++ b/arch/x86/net/bpf_jit_comp32.c
@@ -62,8 +62,6 @@
#define IA32_EBP (0x5)
#define IA32_ESP (0x4)
-#define COND_JMP_OPCODE_INVALID (0xFF)
-
/*
* Map eBPF registers to IA32 32bit registers or stack scratch space.
*
@@ -1307,75 +1305,6 @@ static inline void emit_push_r64(const u8 src[], u8 **pprog)
*pprog = prog;
}
-static u8 get_cond_jmp_opcode(const u8 op, bool is_cmp_lo)
-{
- u8 jmp_cond;
-
- /* Convert BPF opcode to x86 */
- switch (op) {
- case BPF_JEQ:
- jmp_cond = X86_JE;
- break;
- case BPF_JSET:
- case BPF_JNE:
- jmp_cond = X86_JNE;
- break;
- case BPF_JGT:
- /* GT is unsigned '>', JA in x86 */
- jmp_cond = X86_JA;
- break;
- case BPF_JLT:
- /* LT is unsigned '<', JB in x86 */
- jmp_cond = X86_JB;
- break;
- case BPF_JGE:
- /* GE is unsigned '>=', JAE in x86 */
- jmp_cond = X86_JAE;
- break;
- case BPF_JLE:
- /* LE is unsigned '<=', JBE in x86 */
- jmp_cond = X86_JBE;
- break;
- case BPF_JSGT:
- if (!is_cmp_lo)
- /* Signed '>', GT in x86 */
- jmp_cond = X86_JG;
- else
- /* GT is unsigned '>', JA in x86 */
- jmp_cond = X86_JA;
- break;
- case BPF_JSLT:
- if (!is_cmp_lo)
- /* Signed '<', LT in x86 */
- jmp_cond = X86_JL;
- else
- /* LT is unsigned '<', JB in x86 */
- jmp_cond = X86_JB;
- break;
- case BPF_JSGE:
- if (!is_cmp_lo)
- /* Signed '>=', GE in x86 */
- jmp_cond = X86_JGE;
- else
- /* GE is unsigned '>=', JAE in x86 */
- jmp_cond = X86_JAE;
- break;
- case BPF_JSLE:
- if (!is_cmp_lo)
- /* Signed '<=', LE in x86 */
- jmp_cond = X86_JLE;
- else
- /* LE is unsigned '<=', JBE in x86 */
- jmp_cond = X86_JBE;
- break;
- default: /* to silence GCC warning */
- jmp_cond = COND_JMP_OPCODE_INVALID;
- break;
- }
-
- return jmp_cond;
-}
-
static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
int oldproglen, struct jit_context *ctx)
{
diff --git a/arch/x86/net/bpf_jit_comp64.c b/arch/x86/net/bpf_jit_comp64.c
index e8d0f784ab14..40462fe869f6 100644
--- a/arch/x86/net/bpf_jit_comp64.c
+++ b/arch/x86/net/bpf_jit_comp64.c
@@ -1122,50 +1122,10 @@ xadd: if (is_imm8(insn->off))
else
EMIT2_off32(0x81, add_1reg(0xF8, dst_reg), imm32);
-emit_cond_jmp: /* Convert BPF opcode to x86 */
- switch (BPF_OP(insn->code)) {
- case BPF_JEQ:
- jmp_cond = X86_JE;
- break;
- case BPF_JSET:
- case BPF_JNE:
- jmp_cond = X86_JNE;
- break;
- case BPF_JGT:
- /* GT is unsigned '>', JA in x86 */
- jmp_cond = X86_JA;
- break;
- case BPF_JLT:
- /* LT is unsigned '<', JB in x86 */
- jmp_cond = X86_JB;
- break;
- case BPF_JGE:
- /* GE is unsigned '>=', JAE in x86 */
- jmp_cond = X86_JAE;
- break;
- case BPF_JLE:
- /* LE is unsigned '<=', JBE in x86 */
- jmp_cond = X86_JBE;
- break;
- case BPF_JSGT:
- /* Signed '>', GT in x86 */
- jmp_cond = X86_JG;
- break;
- case BPF_JSLT:
- /* Signed '<', LT in x86 */
- jmp_cond = X86_JL;
- break;
- case BPF_JSGE:
- /* Signed '>=', GE in x86 */
- jmp_cond = X86_JGE;
- break;
- case BPF_JSLE:
- /* Signed '<=', LE in x86 */
- jmp_cond = X86_JLE;
- break;
- default: /* to silence GCC warning */
+emit_cond_jmp:
+ jmp_cond = get_cond_jmp_opcode(BPF_OP(insn->code), false);
+ if (jmp_cond == COND_JMP_OPCODE_INVALID)
return -EFAULT;
- }
jmp_offset = addrs[i + insn->off] - addrs[i];
if (is_imm8(jmp_offset)) {
EMIT2(jmp_cond, jmp_offset);
diff --git a/arch/x86/net/bpf_jit_core.c b/arch/x86/net/bpf_jit_core.c
new file mode 100644
index 000000000000..a4991d36b517
--- /dev/null
+++ b/arch/x86/net/bpf_jit_core.c
@@ -0,0 +1,76 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Common functionality for x86 32bit and 64bit BPF JIT compilers
+ */
+
+#include <linux/bpf.h>
+#include "bpf_jit.h"
+
+u8 get_cond_jmp_opcode(const u8 op, bool is_cmp_lo)
+{
+ u8 jmp_cond;
+
+ /* Convert BPF opcode to x86 */
+ switch (op) {
+ case BPF_JEQ:
+ jmp_cond = X86_JE;
+ break;
+ case BPF_JSET:
+ case BPF_JNE:
+ jmp_cond = X86_JNE;
+ break;
+ case BPF_JGT:
+ /* GT is unsigned '>', JA in x86 */
+ jmp_cond = X86_JA;
+ break;
+ case BPF_JLT:
+ /* LT is unsigned '<', JB in x86 */
+ jmp_cond = X86_JB;
+ break;
+ case BPF_JGE:
+ /* GE is unsigned '>=', JAE in x86 */
+ jmp_cond = X86_JAE;
+ break;
+ case BPF_JLE:
+ /* LE is unsigned '<=', JBE in x86 */
+ jmp_cond = X86_JBE;
+ break;
+ case BPF_JSGT:
+ if (!is_cmp_lo)
+ /* Signed '>', GT in x86 */
+ jmp_cond = X86_JG;
+ else
+ /* GT is unsigned '>', JA in x86 */
+ jmp_cond = X86_JA;
+ break;
+ case BPF_JSLT:
+ if (!is_cmp_lo)
+ /* Signed '<', LT in x86 */
+ jmp_cond = X86_JL;
+ else
+ /* LT is unsigned '<', JB in x86 */
+ jmp_cond = X86_JB;
+ break;
+ case BPF_JSGE:
+ if (!is_cmp_lo)
+ /* Signed '>=', GE in x86 */
+ jmp_cond = X86_JGE;
+ else
+ /* GE is unsigned '>=', JAE in x86 */
+ jmp_cond = X86_JAE;
+ break;
+ case BPF_JSLE:
+ if (!is_cmp_lo)
+ /* Signed '<=', LE in x86 */
+ jmp_cond = X86_JLE;
+ else
+ /* LE is unsigned '<=', JBE in x86 */
+ jmp_cond = X86_JBE;
+ break;
+ default: /* to silence GCC warning */
+ jmp_cond = COND_JMP_OPCODE_INVALID;
+ break;
+ }
+
+ return jmp_cond;
+}
--
2.27.0
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf, x86: Factor common x86 JIT code
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
@ 2020-06-29 17:48 ` Alexei Starovoitov
2020-06-30 5:20 ` kernel test robot
2020-07-11 3:13 ` kernel test robot
2 siblings, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2020-06-29 17:48 UTC (permalink / raw)
To: Tobias Klauser
Cc: Alexei Starovoitov, Daniel Borkmann, Wang YanQing, bpf,
Network Development, X86 ML
On Mon, Jun 29, 2020 at 2:33 AM Tobias Klauser <tklauser@distanz.ch> wrote:
>
> Factor out code common for 32-bit and 64-bit x86 BPF JITs to bpf_jit.h
>
> Also follow other architectures and rename bpf_jit_comp.c to
> bpf_jit_comp64.c to be more explicit.
>
> Also adjust the file matching pattern in MAINTAINERS such that the
> common x86 files are included for both the 32-bit and 64-bit BPF JIT
> sections.
>
> Signed-off-by: Tobias Klauser <tklauser@distanz.ch>
> ---
> MAINTAINERS | 3 +-
> arch/x86/net/Makefile | 2 +-
> arch/x86/net/bpf_jit.h | 93 ++++++++++++
> arch/x86/net/bpf_jit_comp32.c | 135 ++++--------------
> .../net/{bpf_jit_comp.c => bpf_jit_comp64.c} | 84 +----------
> 5 files changed, 123 insertions(+), 194 deletions(-)
> create mode 100644 arch/x86/net/bpf_jit.h
> rename arch/x86/net/{bpf_jit_comp.c => bpf_jit_comp64.c} (96%)
I don't see any value in such refactoring.
Looks like code churn to me.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf, x86: Factor common x86 JIT code
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
2020-06-29 17:48 ` Alexei Starovoitov
@ 2020-06-30 5:20 ` kernel test robot
2020-07-11 3:13 ` kernel test robot
2 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2020-06-30 5:20 UTC (permalink / raw)
To: Tobias Klauser, Alexei Starovoitov, Daniel Borkmann, Wang YanQing
Cc: kbuild-all, clang-built-linux, bpf, netdev, x86
[-- Attachment #1: Type: text/plain, Size: 23130 bytes --]
Hi Tobias,
I love your patch! Perhaps something to improve:
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Tobias-Klauser/bpf-x86-Factor-common-x86-JIT-code/20200630-045932
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: x86_64-randconfig-a002-20200630 (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project cf1d04484344be52ada8178e41d18fd15a9b880c)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
arch/x86/purgatory/purgatory.c:57:6: warning: no previous prototype for function 'warn' [-Wmissing-prototypes]
void warn(const char *msg) {}
^
arch/x86/purgatory/purgatory.c:57:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void warn(const char *msg) {}
^
static
1 warning generated.
>> arch/x86/net/bpf_jit_comp64.c:1713:5: warning: no previous prototype for function 'arch_prepare_bpf_dispatcher' [-Wmissing-prototypes]
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
arch/x86/net/bpf_jit_comp64.c:1713:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
static
arch/x86/mm/init.c:81:6: warning: no previous prototype for function 'x86_has_pat_wp' [-Wmissing-prototypes]
bool x86_has_pat_wp(void)
^
arch/x86/mm/init.c:81:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
bool x86_has_pat_wp(void)
^
static
arch/x86/mm/init.c:86:22: warning: no previous prototype for function 'pgprot2cachemode' [-Wmissing-prototypes]
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
arch/x86/mm/init.c:86:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
static
In file included from arch/x86/boot/compressed/string.c:11:
arch/x86/boot/compressed/../string.c:43:5: warning: no previous prototype for function 'bcmp' [-Wmissing-prototypes]
int bcmp(const void *s1, const void *s2, size_t len)
^
arch/x86/boot/compressed/../string.c:43:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int bcmp(const void *s1, const void *s2, size_t len)
^
static
arch/x86/boot/compressed/../string.c:145:6: warning: no previous prototype for function 'simple_strtol' [-Wmissing-prototypes]
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
arch/x86/boot/compressed/../string.c:145:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
static
arch/x86/boot/compressed/string.c:53:7: warning: no previous prototype for function 'memmove' [-Wmissing-prototypes]
void *memmove(void *dest, const void *src, size_t n)
^
arch/x86/boot/compressed/string.c:53:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void *memmove(void *dest, const void *src, size_t n)
^
static
3 warnings generated.
2 warnings generated.
1 warning generated.
arch/x86/entry/common.c:274:24: warning: no previous prototype for function 'prepare_exit_to_usermode' [-Wmissing-prototypes]
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
arch/x86/entry/common.c:274:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
static
arch/x86/entry/common.c:336:24: warning: no previous prototype for function 'syscall_return_slowpath' [-Wmissing-prototypes]
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
arch/x86/entry/common.c:336:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
static
arch/x86/entry/vdso/vgetcpu.c:14:1: warning: no previous prototype for function '__vdso_getcpu' [-Wmissing-prototypes]
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
^
arch/x86/entry/vdso/vgetcpu.c:13:9: note: declare 'static' if the function is not intended to be used outside of this translation unit
notrace long
^
static
1 warning generated.
2 warnings generated.
arch/x86/kernel/i8259.c:237: warning: Function parameter or member 'trigger' not described in 'restore_ELCR'
arch/x86/mm/ioremap.c:737:17: warning: no previous prototype for function 'early_memremap_pgprot_adjust' [-Wmissing-prototypes]
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
arch/x86/mm/ioremap.c:737:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
static
arch/x86/mm/extable.c:26:16: warning: no previous prototype for function 'ex_handler_default' [-Wmissing-prototypes]
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:26:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:36:16: warning: no previous prototype for function 'ex_handler_fault' [-Wmissing-prototypes]
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:36:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:57:16: warning: no previous prototype for function 'ex_handler_fprestore' [-Wmissing-prototypes]
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:57:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:72:16: warning: no previous prototype for function 'ex_handler_uaccess' [-Wmissing-prototypes]
__visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
^
--
arch/x86/purgatory/purgatory.c:57:6: warning: no previous prototype for function 'warn' [-Wmissing-prototypes]
void warn(const char *msg) {}
^
arch/x86/purgatory/purgatory.c:57:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void warn(const char *msg) {}
^
static
1 warning generated.
>> arch/x86/net/bpf_jit_comp64.c:1713:5: warning: no previous prototype for function 'arch_prepare_bpf_dispatcher' [-Wmissing-prototypes]
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
arch/x86/net/bpf_jit_comp64.c:1713:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
static
arch/x86/mm/init.c:81:6: warning: no previous prototype for function 'x86_has_pat_wp' [-Wmissing-prototypes]
bool x86_has_pat_wp(void)
^
arch/x86/mm/init.c:81:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
bool x86_has_pat_wp(void)
^
static
arch/x86/mm/init.c:86:22: warning: no previous prototype for function 'pgprot2cachemode' [-Wmissing-prototypes]
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
arch/x86/mm/init.c:86:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
static
In file included from arch/x86/boot/compressed/string.c:11:
arch/x86/boot/compressed/../string.c:43:5: warning: no previous prototype for function 'bcmp' [-Wmissing-prototypes]
int bcmp(const void *s1, const void *s2, size_t len)
^
arch/x86/boot/compressed/../string.c:43:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int bcmp(const void *s1, const void *s2, size_t len)
^
static
arch/x86/boot/compressed/../string.c:145:6: warning: no previous prototype for function 'simple_strtol' [-Wmissing-prototypes]
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
arch/x86/boot/compressed/../string.c:145:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
static
arch/x86/boot/compressed/string.c:53:7: warning: no previous prototype for function 'memmove' [-Wmissing-prototypes]
void *memmove(void *dest, const void *src, size_t n)
^
arch/x86/boot/compressed/string.c:53:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void *memmove(void *dest, const void *src, size_t n)
^
static
3 warnings generated.
2 warnings generated.
1 warning generated.
arch/x86/entry/common.c:274:24: warning: no previous prototype for function 'prepare_exit_to_usermode' [-Wmissing-prototypes]
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
arch/x86/entry/common.c:274:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
static
arch/x86/entry/common.c:336:24: warning: no previous prototype for function 'syscall_return_slowpath' [-Wmissing-prototypes]
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
arch/x86/entry/common.c:336:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
static
arch/x86/entry/vdso/vgetcpu.c:14:1: warning: no previous prototype for function '__vdso_getcpu' [-Wmissing-prototypes]
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
^
arch/x86/entry/vdso/vgetcpu.c:13:9: note: declare 'static' if the function is not intended to be used outside of this translation unit
notrace long
^
static
1 warning generated.
2 warnings generated.
arch/x86/kernel/i8259.c:237: warning: Function parameter or member 'trigger' not described in 'restore_ELCR'
arch/x86/mm/ioremap.c:737:17: warning: no previous prototype for function 'early_memremap_pgprot_adjust' [-Wmissing-prototypes]
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
arch/x86/mm/ioremap.c:737:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
static
arch/x86/mm/extable.c:26:16: warning: no previous prototype for function 'ex_handler_default' [-Wmissing-prototypes]
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:26:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:36:16: warning: no previous prototype for function 'ex_handler_fault' [-Wmissing-prototypes]
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:36:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:57:16: warning: no previous prototype for function 'ex_handler_fprestore' [-Wmissing-prototypes]
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:57:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:72:16: warning: no previous prototype for function 'ex_handler_uaccess' [-Wmissing-prototypes]
__visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
^
--
>> arch/x86/net/bpf_jit_comp64.c:1713:5: warning: no previous prototype for function 'arch_prepare_bpf_dispatcher' [-Wmissing-prototypes]
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
arch/x86/net/bpf_jit_comp64.c:1713:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
static
1 warning generated.
--
arch/x86/purgatory/purgatory.c:57:6: warning: no previous prototype for function 'warn' [-Wmissing-prototypes]
void warn(const char *msg) {}
^
arch/x86/purgatory/purgatory.c:57:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void warn(const char *msg) {}
^
static
1 warning generated.
arch/x86/mm/init.c:81:6: warning: no previous prototype for function 'x86_has_pat_wp' [-Wmissing-prototypes]
bool x86_has_pat_wp(void)
^
arch/x86/mm/init.c:81:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
bool x86_has_pat_wp(void)
^
static
arch/x86/mm/init.c:86:22: warning: no previous prototype for function 'pgprot2cachemode' [-Wmissing-prototypes]
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
arch/x86/mm/init.c:86:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
enum page_cache_mode pgprot2cachemode(pgprot_t pgprot)
^
static
>> arch/x86/net/bpf_jit_comp64.c:1713:5: warning: no previous prototype for function 'arch_prepare_bpf_dispatcher' [-Wmissing-prototypes]
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
arch/x86/net/bpf_jit_comp64.c:1713:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
^
static
arch/x86/entry/common.c:274:24: warning: no previous prototype for function 'prepare_exit_to_usermode' [-Wmissing-prototypes]
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
arch/x86/entry/common.c:274:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void prepare_exit_to_usermode(struct pt_regs *regs)
^
static
arch/x86/entry/common.c:336:24: warning: no previous prototype for function 'syscall_return_slowpath' [-Wmissing-prototypes]
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
arch/x86/entry/common.c:336:19: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible noinstr void syscall_return_slowpath(struct pt_regs *regs)
^
static
2 warnings generated.
2 warnings generated.
In file included from arch/x86/boot/compressed/string.c:11:
arch/x86/boot/compressed/../string.c:43:5: warning: no previous prototype for function 'bcmp' [-Wmissing-prototypes]
int bcmp(const void *s1, const void *s2, size_t len)
^
arch/x86/boot/compressed/../string.c:43:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int bcmp(const void *s1, const void *s2, size_t len)
^
static
arch/x86/boot/compressed/../string.c:145:6: warning: no previous prototype for function 'simple_strtol' [-Wmissing-prototypes]
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
arch/x86/boot/compressed/../string.c:145:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
long simple_strtol(const char *cp, char **endp, unsigned int base)
^
static
arch/x86/boot/compressed/string.c:53:7: warning: no previous prototype for function 'memmove' [-Wmissing-prototypes]
void *memmove(void *dest, const void *src, size_t n)
^
arch/x86/boot/compressed/string.c:53:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void *memmove(void *dest, const void *src, size_t n)
^
static
3 warnings generated.
arch/x86/entry/vdso/vgetcpu.c:14:1: warning: no previous prototype for function '__vdso_getcpu' [-Wmissing-prototypes]
__vdso_getcpu(unsigned *cpu, unsigned *node, struct getcpu_cache *unused)
^
arch/x86/entry/vdso/vgetcpu.c:13:9: note: declare 'static' if the function is not intended to be used outside of this translation unit
notrace long
^
static
1 warning generated.
1 warning generated.
arch/x86/kernel/i8259.c:237: warning: Function parameter or member 'trigger' not described in 'restore_ELCR'
arch/x86/mm/ioremap.c:737:17: warning: no previous prototype for function 'early_memremap_pgprot_adjust' [-Wmissing-prototypes]
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
arch/x86/mm/ioremap.c:737:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
pgprot_t __init early_memremap_pgprot_adjust(resource_size_t phys_addr,
^
static
1 warning generated.
arch/x86/mm/extable.c:26:16: warning: no previous prototype for function 'ex_handler_default' [-Wmissing-prototypes]
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:26:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_default(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:36:16: warning: no previous prototype for function 'ex_handler_fault' [-Wmissing-prototypes]
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:36:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fault(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:57:16: warning: no previous prototype for function 'ex_handler_fprestore' [-Wmissing-prototypes]
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:57:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_fprestore(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:72:16: warning: no previous prototype for function 'ex_handler_uaccess' [-Wmissing-prototypes]
__visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:72:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_uaccess(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:83:16: warning: no previous prototype for function 'ex_handler_rdmsr_unsafe' [-Wmissing-prototypes]
__visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
^
arch/x86/mm/extable.c:83:11: note: declare 'static' if the function is not intended to be used outside of this translation unit
__visible bool ex_handler_rdmsr_unsafe(const struct exception_table_entry *fixup,
^
static
arch/x86/mm/extable.c:100:16: warning: no previous prototype for function 'ex_handler_wrmsr_unsafe' [-Wmissing-prototypes]
__visible bool ex_handler_wrmsr_unsafe(const struct exception_table_entry *fixup,
vim +/arch_prepare_bpf_dispatcher +1713 arch/x86/net/bpf_jit_comp64.c
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1712
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 @1713 int arch_prepare_bpf_dispatcher(void *image, s64 *funcs, int num_funcs)
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1714 {
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1715 u8 *prog = image;
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1716
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1717 sort(funcs, num_funcs, sizeof(funcs[0]), cmp_ips, NULL);
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1718 return emit_bpf_dispatcher(&prog, 0, num_funcs - 1, funcs);
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1719 }
75ccbef6369e94 arch/x86/net/bpf_jit_comp.c Björn Töpel 2019-12-13 1720
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 41690 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH bpf-next 1/2] bpf, x86: Factor common x86 JIT code
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
2020-06-29 17:48 ` Alexei Starovoitov
2020-06-30 5:20 ` kernel test robot
@ 2020-07-11 3:13 ` kernel test robot
2 siblings, 0 replies; 6+ messages in thread
From: kernel test robot @ 2020-07-11 3:13 UTC (permalink / raw)
To: Tobias Klauser, Alexei Starovoitov, Daniel Borkmann, Wang YanQing
Cc: kbuild-all, bpf, netdev, x86
[-- Attachment #1: Type: text/plain, Size: 9532 bytes --]
Hi Tobias,
I love your patch! Perhaps something to improve:
[auto build test WARNING on bpf-next/master]
url: https://github.com/0day-ci/linux/commits/Tobias-Klauser/bpf-x86-Factor-common-x86-JIT-code/20200630-045932
base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: x86_64-randconfig-s022-20200710 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-14) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.2-37-gc9676a3b-dirty
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
sparse warnings: (new ones prefixed by >>)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (e58948 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (e58948 becomes 8948)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (ec8148 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (ec8148 becomes 8148)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5541 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5641 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5741 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (d289 becomes 89)
>> arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (1c5639 becomes 39)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (1c5639 becomes 5639)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (2b76 becomes 76)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (858b becomes 8b)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (fffffddc becomes dc)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (20f883 becomes 83)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (20f883 becomes f883)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (2077 becomes 77)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (1c083 becomes 83)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (1c083 becomes c083)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (8589 becomes 89)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (fffffddc becomes dc)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (d6848b48 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (d6848b48 becomes 8b48)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (190 becomes 90)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c08548 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (c08548 becomes 8548)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (a74 becomes 74)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (30408b48 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (30408b48 becomes 8b48)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (19c08348 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (19c08348 becomes 8348)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (e0ff becomes ff)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (858b becomes 8b)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (fffffddc becomes dc)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (20f883 becomes 83)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (20f883 becomes f883)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (e77 becomes 77)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (1c083 becomes 83)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (1c083 becomes c083)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (8589 becomes 89)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (fffffddc becomes dc)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (8966 becomes 66)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c3c749 becomes 49)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (c3c749 becomes c749)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (d231 becomes 31)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (f3f749 becomes 49)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (f3f749 becomes f749)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (f3f741 becomes 41)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (f3f741 becomes f741)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (d38949 becomes 49)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (d38949 becomes 8949)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c38949 becomes 49)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (c38949 becomes 8949)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (b70f45 becomes 45)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (b70f45 becomes f45)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (b70f becomes f)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (f41 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (b70f45 becomes 45)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (b70f45 becomes f45)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (b70f becomes f)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c641 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c74166 becomes 66)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (c74166 becomes 4166)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c766 becomes 66)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (c741 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (1f0 becomes f0)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5f41 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5e41 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (5d41 becomes 41)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (f87d8348 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (f87d8348 becomes 8348)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (e58948 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (e58948 becomes 8948)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (8c48348 becomes 48)
arch/x86/net/bpf_jit.h:15:31: sparse: sparse: cast truncates bits from constant value (8c48348 becomes 8348)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (e2ff becomes ff)
arch/x86/net/bpf_jit.h:13:24: sparse: sparse: cast truncates bits from constant value (8f0f becomes f)
vim +13 arch/x86/net/bpf_jit.h
9
10 static inline u8 *emit_code(u8 *ptr, u32 bytes, unsigned int len)
11 {
12 if (len == 1)
> 13 *ptr = bytes;
14 else if (len == 2)
15 *(u16 *)ptr = bytes;
16 else {
17 *(u32 *)ptr = bytes;
18 barrier();
19 }
20 return ptr + len;
21 }
22
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 34446 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2020-07-11 3:48 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-29 9:33 [PATCH bpf-next 0/2] Factor common x86 JIT code Tobias Klauser
2020-06-29 9:33 ` [PATCH bpf-next 1/2] bpf, x86: " Tobias Klauser
2020-06-29 17:48 ` Alexei Starovoitov
2020-06-30 5:20 ` kernel test robot
2020-07-11 3:13 ` kernel test robot
2020-06-29 9:33 ` [PATCH bpf-next 2/2] bpf, x86: Factor out get_cond_jmp_opcode and use for 64bit x86 Tobias Klauser
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).