Context |
Check |
Description |
bpf/vmtest-bpf-next-PR |
success
|
PR summary
|
bpf/vmtest-bpf-next-VM_Test-2 |
success
|
Logs for Unittests
|
bpf/vmtest-bpf-next-VM_Test-0 |
success
|
Logs for Lint
|
bpf/vmtest-bpf-next-VM_Test-1 |
success
|
Logs for ShellCheck
|
bpf/vmtest-bpf-next-VM_Test-4 |
success
|
Logs for aarch64-gcc / build / build for aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-5 |
success
|
Logs for aarch64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-3 |
success
|
Logs for Validate matrix.py
|
bpf/vmtest-bpf-next-VM_Test-10 |
success
|
Logs for aarch64-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-12 |
success
|
Logs for s390x-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-8 |
success
|
Logs for aarch64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-6 |
success
|
Logs for aarch64-gcc / test (test_maps, false, 360) / test_maps on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-7 |
success
|
Logs for aarch64-gcc / test (test_progs, false, 360) / test_progs on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-11 |
success
|
Logs for s390x-gcc / build / build for s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-9 |
success
|
Logs for aarch64-gcc / test (test_verifier, false, 360) / test_verifier on aarch64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-15 |
success
|
Logs for s390x-gcc / test (test_verifier, false, 360) / test_verifier on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-16 |
success
|
Logs for s390x-gcc / veristat
|
bpf/vmtest-bpf-next-VM_Test-18 |
success
|
Logs for x86_64-gcc / build / build for x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-17 |
success
|
Logs for set-matrix
|
bpf/vmtest-bpf-next-VM_Test-19 |
success
|
Logs for x86_64-gcc / build-release
|
bpf/vmtest-bpf-next-VM_Test-25 |
success
|
Logs for x86_64-gcc / test (test_verifier, false, 360) / test_verifier on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-24 |
success
|
Logs for x86_64-gcc / test (test_progs_parallel, true, 30) / test_progs_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-27 |
success
|
Logs for x86_64-llvm-17 / build / build for x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-26 |
success
|
Logs for x86_64-gcc / veristat / veristat on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-28 |
success
|
Logs for x86_64-llvm-17 / build-release / build for x86_64 with llvm-17-O2
|
bpf/vmtest-bpf-next-VM_Test-29 |
success
|
Logs for x86_64-llvm-17 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-30 |
success
|
Logs for x86_64-llvm-17 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-31 |
success
|
Logs for x86_64-llvm-17 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-32 |
success
|
Logs for x86_64-llvm-17 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-17
|
bpf/vmtest-bpf-next-VM_Test-33 |
success
|
Logs for x86_64-llvm-17 / veristat
|
bpf/vmtest-bpf-next-VM_Test-34 |
success
|
Logs for x86_64-llvm-18 / build / build for x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-35 |
success
|
Logs for x86_64-llvm-18 / build-release / build for x86_64 with llvm-18-O2
|
bpf/vmtest-bpf-next-VM_Test-36 |
success
|
Logs for x86_64-llvm-18 / test (test_maps, false, 360) / test_maps on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-38 |
success
|
Logs for x86_64-llvm-18 / test (test_progs_cpuv4, false, 360) / test_progs_cpuv4 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-37 |
success
|
Logs for x86_64-llvm-18 / test (test_progs, false, 360) / test_progs on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-39 |
success
|
Logs for x86_64-llvm-18 / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-40 |
success
|
Logs for x86_64-llvm-18 / test (test_verifier, false, 360) / test_verifier on x86_64 with llvm-18
|
bpf/vmtest-bpf-next-VM_Test-41 |
success
|
Logs for x86_64-llvm-18 / veristat
|
bpf/vmtest-bpf-next-VM_Test-20 |
success
|
Logs for x86_64-gcc / test (test_maps, false, 360) / test_maps on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-23 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32_parallel, true, 30) / test_progs_no_alu32_parallel on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-21 |
success
|
Logs for x86_64-gcc / test (test_progs, false, 360) / test_progs on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-22 |
success
|
Logs for x86_64-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on x86_64 with gcc
|
bpf/vmtest-bpf-next-VM_Test-14 |
success
|
Logs for s390x-gcc / test (test_progs_no_alu32, false, 360) / test_progs_no_alu32 on s390x with gcc
|
bpf/vmtest-bpf-next-VM_Test-13 |
success
|
Logs for s390x-gcc / test (test_progs, false, 360) / test_progs on s390x with gcc
|
netdev/series_format |
success
|
Posting correctly formatted
|
netdev/tree_selection |
success
|
Clearly marked for bpf-next, async
|
netdev/ynl |
success
|
Generated files up to date;
no warnings/errors;
no diff in generated;
|
netdev/fixes_present |
success
|
Fixes tag not required for -next series
|
netdev/header_inline |
success
|
No static functions without inline keyword in header files
|
netdev/build_32bit |
success
|
Errors and warnings before: 7 this patch: 7
|
netdev/build_tools |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/cc_maintainers |
warning
|
15 maintainers not CCed: mykolal@fb.com sdf@fomichev.me llvm@lists.linux.dev haoluo@google.com shuah@kernel.org jolsa@kernel.org ndesaulniers@google.com nathan@kernel.org linux-kselftest@vger.kernel.org justinstitt@google.com song@kernel.org cupertino.miranda@oracle.com morbo@google.com kpsingh@kernel.org john.fastabend@gmail.com
|
netdev/build_clang |
success
|
Errors and warnings before: 7 this patch: 7
|
netdev/verify_signedoff |
success
|
Signed-off-by tag matches author and committer
|
netdev/deprecated_api |
success
|
None detected
|
netdev/check_selftest |
success
|
No net selftest shell script
|
netdev/verify_fixes |
success
|
No Fixes tag
|
netdev/build_allmodconfig_warn |
success
|
Errors and warnings before: 7 this patch: 7
|
netdev/checkpatch |
warning
|
CHECK: spaces preferred around that '|' (ctx:VxV)
WARNING: line length of 100 exceeds 80 columns
WARNING: line length of 113 exceeds 80 columns
WARNING: line length of 81 exceeds 80 columns
WARNING: line length of 82 exceeds 80 columns
WARNING: line length of 84 exceeds 80 columns
WARNING: line length of 85 exceeds 80 columns
WARNING: line length of 86 exceeds 80 columns
WARNING: line length of 87 exceeds 80 columns
WARNING: line length of 89 exceeds 80 columns
WARNING: line length of 91 exceeds 80 columns
WARNING: line length of 97 exceeds 80 columns
WARNING: line length of 98 exceeds 80 columns
|
netdev/build_clang_rust |
success
|
No Rust files in patch. Skipping build
|
netdev/kdoc |
success
|
Errors and warnings before: 0 this patch: 0
|
netdev/source_inline |
success
|
Was 0 now: 0
|
@@ -90,6 +90,8 @@
#define __arch_x86_64 __arch("X86_64")
#define __arch_arm64 __arch("ARM64")
#define __arch_riscv64 __arch("RISCV64")
+#define __jit_x86(basic_regex) __attribute__((btf_decl_tag("comment:test_jit_x86=" basic_regex)))
+#define __jit_x86_unpriv(basic_regex) __attribute__((btf_decl_tag("comment:test_jit_x86_unpriv=" basic_regex)))
/* Convenience macro for use with 'asm volatile' blocks */
#define __naked __attribute__((naked))
@@ -10,6 +10,7 @@
#include "disasm_helpers.h"
#include "unpriv_helpers.h"
#include "cap_helpers.h"
+#include "jit_disasm_helpers.h"
#define str_has_pfx(str, pfx) \
(strncmp(str, pfx, __builtin_constant_p(pfx) ? sizeof(pfx) - 1 : strlen(pfx)) == 0)
@@ -35,6 +36,8 @@
#define TEST_TAG_AUXILIARY_UNPRIV "comment:test_auxiliary_unpriv"
#define TEST_BTF_PATH "comment:test_btf_path="
#define TEST_TAG_ARCH "comment:test_arch="
+#define TEST_TAG_JIT_X86_PFX "comment:test_jit_x86="
+#define TEST_TAG_JIT_X86_PFX_UNPRIV "comment:test_jit_x86_unpriv="
/* Warning: duplicated in bpf_misc.h */
#define POINTER_VALUE 0xcafe4all
@@ -53,10 +56,18 @@ enum mode {
UNPRIV = 2
};
+enum arch {
+ ARCH_X86_64 = 1,
+ ARCH_ARM64 = 2,
+ ARCH_RISCV64 = 3,
+ ARCH_MAX
+};
+
struct expect_msg {
const char *substr; /* substring match */
const char *regex_str; /* regex-based match */
regex_t regex;
+ int regex_flags;
};
struct expected_msgs {
@@ -69,6 +80,7 @@ struct test_subspec {
bool expect_failure;
struct expected_msgs expect_msgs;
struct expected_msgs expect_xlated;
+ struct expected_msgs jited[ARCH_MAX];
int retval;
bool execute;
};
@@ -120,11 +132,17 @@ static void free_msgs(struct expected_msgs *msgs)
static void free_test_spec(struct test_spec *spec)
{
+ int i;
+
/* Deallocate expect_msgs arrays. */
free_msgs(&spec->priv.expect_msgs);
free_msgs(&spec->unpriv.expect_msgs);
free_msgs(&spec->priv.expect_xlated);
free_msgs(&spec->unpriv.expect_xlated);
+ for (i = 0; i < ARCH_MAX; ++i) {
+ free_msgs(&spec->priv.jited[i]);
+ free_msgs(&spec->unpriv.jited[i]);
+ }
free(spec->priv.name);
free(spec->unpriv.name);
@@ -132,7 +150,8 @@ static void free_test_spec(struct test_spec *spec)
spec->unpriv.name = NULL;
}
-static int push_msg(const char *substr, const char *regex_str, struct expected_msgs *msgs)
+static int __push_msg(const char *substr, const char *regex_str, int regex_flags,
+ struct expected_msgs *msgs)
{
void *tmp;
int regcomp_res;
@@ -151,10 +170,12 @@ static int push_msg(const char *substr, const char *regex_str, struct expected_m
if (substr) {
msg->substr = substr;
msg->regex_str = NULL;
+ msg->regex_flags = 0;
} else {
msg->regex_str = regex_str;
msg->substr = NULL;
- regcomp_res = regcomp(&msg->regex, regex_str, REG_EXTENDED|REG_NEWLINE);
+ msg->regex_flags = regex_flags;
+ regcomp_res = regcomp(&msg->regex, regex_str, regex_flags|REG_NEWLINE);
if (regcomp_res != 0) {
regerror(regcomp_res, &msg->regex, error_msg, sizeof(error_msg));
PRINT_FAIL("Regexp compilation error in '%s': '%s'\n",
@@ -167,6 +188,35 @@ static int push_msg(const char *substr, const char *regex_str, struct expected_m
return 0;
}
+static int clone_msgs(struct expected_msgs *from, struct expected_msgs *to)
+{
+ struct expect_msg *msg;
+ int i, err;
+
+ for (i = 0; i < from->cnt; i++) {
+ msg = &from->patterns[i];
+ err = __push_msg(msg->substr, msg->regex_str, msg->regex_flags, to);
+ if (err)
+ return err;
+ }
+ return 0;
+}
+
+static int push_msg(const char *substr, struct expected_msgs *msgs)
+{
+ return __push_msg(substr, NULL, 0, msgs);
+}
+
+static int push_extended_regex(const char *regex_str, struct expected_msgs *msgs)
+{
+ return __push_msg(NULL, regex_str, REG_EXTENDED, msgs);
+}
+
+static int push_basic_regex(const char *regex_str, struct expected_msgs *msgs)
+{
+ return __push_msg(NULL, regex_str, 0, msgs);
+}
+
static int parse_int(const char *str, int *val, const char *name)
{
char *end;
@@ -215,12 +265,6 @@ static void update_flags(int *flags, int flag, bool clear)
*flags |= flag;
}
-enum arch {
- ARCH_X86_64 = 0x1,
- ARCH_ARM64 = 0x2,
- ARCH_RISCV64 = 0x4,
-};
-
/* Uses btf_decl_tag attributes to describe the expected test
* behavior, see bpf_misc.h for detailed description of each attribute
* and attribute combinations.
@@ -292,37 +336,49 @@ static int parse_test_spec(struct test_loader *tester,
spec->mode_mask |= UNPRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX)) {
msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX) - 1;
- err = push_msg(msg, NULL, &spec->priv.expect_msgs);
+ err = push_msg(msg, &spec->priv.expect_msgs);
if (err)
goto cleanup;
spec->mode_mask |= PRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_MSG_PFX_UNPRIV)) {
msg = s + sizeof(TEST_TAG_EXPECT_MSG_PFX_UNPRIV) - 1;
- err = push_msg(msg, NULL, &spec->unpriv.expect_msgs);
+ err = push_msg(msg, &spec->unpriv.expect_msgs);
if (err)
goto cleanup;
spec->mode_mask |= UNPRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX)) {
msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX) - 1;
- err = push_msg(NULL, msg, &spec->priv.expect_msgs);
+ err = push_extended_regex(msg, &spec->priv.expect_msgs);
if (err)
goto cleanup;
spec->mode_mask |= PRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_REGEX_PFX_UNPRIV)) {
msg = s + sizeof(TEST_TAG_EXPECT_REGEX_PFX_UNPRIV) - 1;
- err = push_msg(NULL, msg, &spec->unpriv.expect_msgs);
+ err = push_extended_regex(msg, &spec->unpriv.expect_msgs);
+ if (err)
+ goto cleanup;
+ spec->mode_mask |= UNPRIV;
+ } else if (str_has_pfx(s, TEST_TAG_JIT_X86_PFX)) {
+ msg = s + sizeof(TEST_TAG_JIT_X86_PFX) - 1;
+ err = push_basic_regex(msg, &spec->priv.jited[ARCH_X86_64]);
+ if (err)
+ goto cleanup;
+ spec->mode_mask |= PRIV;
+ } else if (str_has_pfx(s, TEST_TAG_JIT_X86_PFX_UNPRIV)) {
+ msg = s + sizeof(TEST_TAG_JIT_X86_PFX_UNPRIV) - 1;
+ err = push_basic_regex(msg, &spec->unpriv.jited[ARCH_X86_64]);
if (err)
goto cleanup;
spec->mode_mask |= UNPRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX)) {
msg = s + sizeof(TEST_TAG_EXPECT_XLATED_PFX) - 1;
- err = push_msg(msg, NULL, &spec->priv.expect_xlated);
+ err = push_msg(msg, &spec->priv.expect_xlated);
if (err)
goto cleanup;
spec->mode_mask |= PRIV;
} else if (str_has_pfx(s, TEST_TAG_EXPECT_XLATED_PFX_UNPRIV)) {
msg = s + sizeof(TEST_TAG_EXPECT_XLATED_PFX_UNPRIV) - 1;
- err = push_msg(msg, NULL, &spec->unpriv.expect_xlated);
+ err = push_msg(msg, &spec->unpriv.expect_xlated);
if (err)
goto cleanup;
spec->mode_mask |= UNPRIV;
@@ -376,11 +432,11 @@ static int parse_test_spec(struct test_loader *tester,
} else if (str_has_pfx(s, TEST_TAG_ARCH)) {
val = s + sizeof(TEST_TAG_ARCH) - 1;
if (strcmp(val, "X86_64") == 0) {
- arch_mask |= ARCH_X86_64;
+ arch_mask |= 1u << ARCH_X86_64;
} else if (strcmp(val, "ARM64") == 0) {
- arch_mask |= ARCH_ARM64;
+ arch_mask |= 1u << ARCH_ARM64;
} else if (strcmp(val, "RISCV64") == 0) {
- arch_mask |= ARCH_RISCV64;
+ arch_mask |= 1u << ARCH_RISCV64;
} else {
PRINT_FAIL("bad arch spec: '%s'", val);
err = -EINVAL;
@@ -434,26 +490,13 @@ static int parse_test_spec(struct test_loader *tester,
spec->unpriv.execute = spec->priv.execute;
}
- if (spec->unpriv.expect_msgs.cnt == 0) {
- for (i = 0; i < spec->priv.expect_msgs.cnt; i++) {
- struct expect_msg *msg = &spec->priv.expect_msgs.patterns[i];
-
- err = push_msg(msg->substr, msg->regex_str,
- &spec->unpriv.expect_msgs);
- if (err)
- goto cleanup;
- }
- }
- if (spec->unpriv.expect_xlated.cnt == 0) {
- for (i = 0; i < spec->priv.expect_xlated.cnt; i++) {
- struct expect_msg *msg = &spec->priv.expect_xlated.patterns[i];
-
- err = push_msg(msg->substr, msg->regex_str,
- &spec->unpriv.expect_xlated);
- if (err)
- goto cleanup;
- }
- }
+ if (spec->unpriv.expect_msgs.cnt == 0)
+ clone_msgs(&spec->priv.expect_msgs, &spec->unpriv.expect_msgs);
+ if (spec->unpriv.expect_xlated.cnt == 0)
+ clone_msgs(&spec->priv.expect_xlated, &spec->unpriv.expect_xlated);
+ for (i = 0; i < ARCH_MAX; ++i)
+ if (spec->unpriv.jited[i].cnt == 0)
+ clone_msgs(&spec->priv.jited[i], &spec->unpriv.jited[i]);
}
spec->valid = true;
@@ -508,6 +551,13 @@ static void emit_xlated(const char *xlated, bool force)
fprintf(stdout, "XLATED:\n=============\n%s=============\n", xlated);
}
+static void emit_jited(const char *jited, bool force)
+{
+ if (!force && env.verbosity == VERBOSE_NONE)
+ return;
+ fprintf(stdout, "JITED:\n=============\n%s=============\n", jited);
+}
+
static void validate_msgs(char *log_buf, struct expected_msgs *msgs,
void (*emit_fn)(const char *buf, bool force))
{
@@ -702,18 +752,16 @@ static int get_xlated_program_text(int prog_fd, char *text, size_t text_sz)
return err;
}
-static bool run_on_current_arch(int arch_mask)
+static int get_current_arch(void)
{
- if (arch_mask == 0)
- return true;
#if defined(__x86_64__)
- return arch_mask & ARCH_X86_64;
+ return ARCH_X86_64;
#elif defined(__aarch64__)
- return arch_mask & ARCH_ARM64;
+ return ARCH_ARM64;
#elif defined(__riscv) && __riscv_xlen == 64
- return arch_mask & ARCH_RISCV64;
+ return ARCH_RISCV64;
#endif
- return false;
+ return -1;
}
/* this function is forced noinline and has short generic name to look better
@@ -732,15 +780,16 @@ void run_subtest(struct test_loader *tester,
struct bpf_program *tprog = NULL, *tprog_iter;
struct test_spec *spec_iter;
struct cap_state caps = {};
+ int retval, err, i, arch;
struct bpf_object *tobj;
struct bpf_map *map;
- int retval, err, i;
bool should_load;
if (!test__start_subtest(subspec->name))
return;
- if (!run_on_current_arch(spec->arch_mask)) {
+ arch = get_current_arch();
+ if (spec->arch_mask && (arch < 0 || (spec->arch_mask & (1u << arch)) == 0)) {
test__skip();
return;
}
@@ -817,6 +866,21 @@ void run_subtest(struct test_loader *tester,
validate_msgs(tester->log_buf, &subspec->expect_xlated, emit_xlated);
}
+ if (arch > 0 && subspec->jited[arch].cnt) {
+ err = get_jited_program_text(bpf_program__fd(tprog),
+ tester->log_buf, tester->log_buf_sz);
+ if (err == -ENOTSUP) {
+ printf("%s:SKIP: jited programs disassembly is not supported,\n", __func__);
+ printf("%s:SKIP: tests are built w/o LLVM development libs\n", __func__);
+ test__skip();
+ goto tobj_cleanup;
+ }
+ if (!ASSERT_EQ(err, 0, "get_jited_program_text"))
+ goto tobj_cleanup;
+ emit_jited(tester->log_buf, false /*force*/);
+ validate_msgs(tester->log_buf, &subspec->jited[arch], emit_jited);
+ }
+
if (should_do_test_run(spec, subspec)) {
/* For some reason test_verifier executes programs
* with all capabilities restored. Do the same here.
Allow to verify jit behaviour by writing tests as below: SEC("tp") __jit_x86("endbr64") __jit_x86("movabs $0x.*,%r9") __jit_x86("add %gs:0x.*,%r9") __jit_x86("mov $0x1,%edi") __jit_x86("mov %rdi,-0x8(%r9)") __jit_x86("mov -0x8(%r9),%rdi") __jit_x86("xor %eax,%eax") __jit_x86("lock xchg %rax,-0x8(%r9)") __jit_x86("lock xadd %rax,-0x8(%r9)") __naked void stack_access_insns(void) { asm volatile (... ::: __clobber_all); } Use regular expressions by default, use basic regular expressions class in order to avoid escaping symbols like $(), often used in AT&T disassembly syntax. Signed-off-by: Eduard Zingerman <eddyz87@gmail.com> --- tools/testing/selftests/bpf/progs/bpf_misc.h | 2 + tools/testing/selftests/bpf/test_loader.c | 156 +++++++++++++------ 2 files changed, 112 insertions(+), 46 deletions(-)