Skip to content

Commit

Permalink
Merge branch 'main' into dependabot/github_actions/docker/metadata-ac…
Browse files Browse the repository at this point in the history
…tion-5.5.1
  • Loading branch information
Alan-Jowett committed Feb 9, 2024
2 parents b61ae8b + 4526e43 commit 1860a9b
Show file tree
Hide file tree
Showing 7 changed files with 322 additions and 190 deletions.
44 changes: 44 additions & 0 deletions include/bpf_conformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,49 @@ typedef enum class _bpf_conformance_test_cpu_version
unknown = -1,
} bpf_conformance_test_cpu_version_t;

typedef enum class _bpf_conformance_groups
{
none = 0x00000000,
base32 = 0x00000001,
base64 = 0x00000002,
atomic32 = 0x00000004,
atomic64 = 0x00000008,
divmul32 = 0x00000010,
divmul64 = 0x00000020,
packet = 0x00000040,
callx = 0x00000080,
} bpf_conformance_groups_t;

inline bpf_conformance_groups_t
operator~(bpf_conformance_groups_t a)
{
return static_cast<bpf_conformance_groups_t>(~static_cast<int>(a));
}

inline bpf_conformance_groups_t
operator|(bpf_conformance_groups_t a, bpf_conformance_groups_t b)
{
return static_cast<bpf_conformance_groups_t>(static_cast<int>(a) | static_cast<int>(b));
}

inline bpf_conformance_groups_t&
operator|=(bpf_conformance_groups_t& a, bpf_conformance_groups_t b)
{
return a = a | b;
}

inline bpf_conformance_groups_t
operator&(bpf_conformance_groups_t a, bpf_conformance_groups_t b)
{
return static_cast<bpf_conformance_groups_t>(static_cast<int>(a) & static_cast<int>(b));
}

inline bpf_conformance_groups_t&
operator&=(bpf_conformance_groups_t& a, bpf_conformance_groups_t b)
{
return a = a & b;
}

// Add typedef for backwards compatibility.
typedef bpf_conformance_test_cpu_version_t bpf_conformance_test_CPU_version_t;

Expand All @@ -42,6 +85,7 @@ typedef struct _bpf_conformance_options
std::optional<std::string> include_test_regex;
std::optional<std::string> exclude_test_regex;
bpf_conformance_test_cpu_version_t cpu_version;
bpf_conformance_groups_t groups;
bpf_conformance_list_instructions_t list_instructions_option;
bool debug;
bool xdp_prolog;
Expand Down
10 changes: 5 additions & 5 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,27 +81,27 @@ enable_testing()

add_test(
NAME cpu_v1
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v1 --exclude_regex "imm-"
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v1 --exclude_regex "imm-" --exclude_groups callx
)

add_test(
NAME cpu_v2
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v2 --exclude_regex "imm-"
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v2 --exclude_regex "imm-" --exclude_groups callx
)

add_test(
NAME cpu_v3
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v3 --debug true --list_instructions true --exclude_regex "imm-"
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v3 --debug true --list_instructions true --exclude_regex "imm-" --exclude_groups callx
)

add_test(
NAME elf_format
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --debug true --list_instructions true --elf true --exclude_regex "(call_local*|imm-)"
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_directory ${PROJECT_BINARY_DIR}/tests --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v3 --debug true --list_instructions true --elf true --exclude_regex "(call_local*|imm-)" --exclude_groups callx
)

add_test(
NAME no_bpf_bytecode
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_path ${PROJECT_SOURCE_DIR}/negative/empty.data --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --debug true
COMMAND sudo ${PROJECT_BINARY_DIR}/bin/bpf_conformance_runner --test_file_path ${PROJECT_SOURCE_DIR}/negative/empty.data --plugin_path ${PROJECT_BINARY_DIR}/bin/libbpf_plugin --xdp_prolog true --cpu_version v3 --debug true --exclude_groups callx
)

set_tests_properties(
Expand Down
11 changes: 9 additions & 2 deletions src/bpf_assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,8 +309,15 @@ typedef class _bpf_assembler
auto target = operands[1];
// Mode determines if this is a helper function, a local call, or a call to a runtime function.
if (mode == "helper") {
inst.imm = _decode_imm32(target);
inst.src = 0;
if (target.starts_with('%')) {
inst.opcode |= EBPF_SRC_REG;
inst.imm = 0;
inst.src = _decode_register(target);
} else {
inst.opcode |= EBPF_SRC_IMM;
inst.imm = _decode_imm32(target);
inst.src = 0;
}
} else if (mode == "local") {
inst.imm = _decode_jump_target(target);
inst.src = 1;
Expand Down
26 changes: 16 additions & 10 deletions src/bpf_conformance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ _generate_xdp_prolog(size_t size)
};
}

bpf_conformance_test_cpu_version_t
get_instruction_cpu_version(ebpf_inst inst)
std::optional<bpf_conformance_instruction_t>
get_instruction_conformance_info(ebpf_inst inst)
{
auto instruction = std::find_if(instructions_from_spec.begin(), instructions_from_spec.end(), [&](const auto &instruction) {
return (instruction.opcode == inst.opcode) &&
Expand All @@ -140,9 +140,9 @@ get_instruction_cpu_version(ebpf_inst inst)
(!needs_offset(inst.opcode) || instruction.offset == inst.offset);
});
if (instruction == instructions_from_spec.end()) {
return bpf_conformance_test_cpu_version_t::unknown;
return {};
}
return instruction->cpu_version;
return *instruction;
}

std::map<std::filesystem::path, std::tuple<bpf_conformance_test_result_t, std::string>>
Expand Down Expand Up @@ -189,31 +189,37 @@ bpf_conformance_options(
}

bpf_conformance_test_cpu_version_t required_cpu_version = bpf_conformance_test_cpu_version_t::v1;
bpf_conformance_groups_t required_conformance_groups{};

// Determine the required CPU version for the test.
for (size_t i = 0; i < byte_code.size(); i++) {
auto inst = byte_code[i];
bpf_conformance_test_cpu_version_t cpu_version = get_instruction_cpu_version(inst);
required_cpu_version = std::max(required_cpu_version, cpu_version);
if (auto instruction = get_instruction_conformance_info(inst)) {
bpf_conformance_test_cpu_version_t cpu_version = instruction->cpu_version;
required_cpu_version = std::max(required_cpu_version, cpu_version);
required_conformance_groups |= instruction->groups;
}
if (inst.opcode == EBPF_OP_LDDW) {
// Instruction has a 64-bit immediate and takes two instructions slots.
i++;
}
}

// If the test requires a CPU version that is not supported by the current CPU version, then skip the test.
if (required_cpu_version > options.cpu_version) {
// If the test requires a CPU version that is not supported by the current CPU version,
// or an unsupported conformance group, then skip the test.
if (required_cpu_version > options.cpu_version || (required_conformance_groups & ~options.groups) != bpf_conformance_groups_t::none) {
test_results[test] = {
bpf_conformance_test_result_t::TEST_RESULT_SKIP, "Test file contains unsupported instructions."};
_log_debug_result(test_results, test);
continue;
}

for (const auto& inst : byte_code) {
instructions_used.insert(bpf_conformance_instruction_t(required_cpu_version, inst));
instructions_used.insert(
bpf_conformance_instruction_t(required_cpu_version, required_conformance_groups, inst));
}

// If the caller requires this as a XDP program, then add the prolog instructions.
// If the caller requires this as an XDP program, then add the prolog instructions.
if (options.xdp_prolog && input_memory.size() > 0) {
auto prolog_instructions = _generate_xdp_prolog(input_memory.size());
byte_code.insert(byte_code.begin(), prolog_instructions.begin(), prolog_instructions.end());
Expand Down

0 comments on commit 1860a9b

Please sign in to comment.