Skip to content

Commit

Permalink
Add tests for SDIV instructions (#153)
Browse files Browse the repository at this point in the history
* Add tests for SDIV instructions

Addresses part of #152

Signed-off-by: Dave Thaler <dthaler@microsoft.com>

* Add cpu_version=v4

Signed-off-by: Dave Thaler <dthaler@microsoft.com>

* Bug fix

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

* Fix test case

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

* Fix test

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

* Fix readme and error

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

* Remove v4 test on ubuntu

Signed-off-by: Dave Thaler <dthaler1968@gmail.com>

---------

Signed-off-by: Dave Thaler <dthaler@microsoft.com>
Signed-off-by: Dave Thaler <dthaler1968@gmail.com>
  • Loading branch information
dthaler committed Jan 11, 2024
1 parent 4797052 commit 13de786
Show file tree
Hide file tree
Showing 13 changed files with 253 additions and 173 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Linux Kernel is treated as the authorative eBPF implementation.
### Ubuntu

```
sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libelf-dev lcov
sudo apt-get install -y libboost-dev libboost-filesystem-dev libboost-program-options-dev libelf-dev lcov libbpf-dev
```

### MacOS
Expand Down
1 change: 1 addition & 0 deletions include/bpf_conformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ typedef enum class _bpf_conformance_test_cpu_version
v1 = 1,
v2 = 2,
v3 = 3,
v4 = 4,
} bpf_conformance_test_cpu_version_t;

// Add typedef for backwards compatibility.
Expand Down
5 changes: 5 additions & 0 deletions src/bpf_assembler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ typedef class _bpf_assembler
{"sub", 0x1},
{"mul", 0x2},
{"div", 0x3},
{"sdiv", 0x3},
{"or", 0x4},
{"and", 0x5},
{"lsh", 0x6},
Expand Down Expand Up @@ -245,6 +246,9 @@ typedef class _bpf_assembler
inst.imm = _decode_imm32(mnemonic.substr(2));
return inst;
}
if (mnemonic.starts_with("sdiv")) {
inst.offset = 1;
}

if (mnemonic.ends_with("32")) {
inst.opcode |= EBPF_CLS_ALU;
Expand Down Expand Up @@ -444,6 +448,7 @@ typedef class _bpf_assembler
{"be16", {&_bpf_assembler::_encode_alu, 1}}, {"be32", {&_bpf_assembler::_encode_alu, 1}},
{"be64", {&_bpf_assembler::_encode_alu, 1}}, {"call", {&_bpf_assembler::_encode_jmp, 2}},
{"div", {&_bpf_assembler::_encode_alu, 2}}, {"div32", {&_bpf_assembler::_encode_alu, 2}},
{"sdiv", {&_bpf_assembler::_encode_alu, 2}}, {"sdiv32", {&_bpf_assembler::_encode_alu, 2}},
{"exit", {&_bpf_assembler::_encode_jmp, 0}}, {"ja", {&_bpf_assembler::_encode_jmp, 1}},
{"jeq", {&_bpf_assembler::_encode_jmp, 3}}, {"jeq32", {&_bpf_assembler::_encode_jmp, 3}},
{"jge", {&_bpf_assembler::_encode_jmp, 3}}, {"jge32", {&_bpf_assembler::_encode_jmp, 3}},
Expand Down
40 changes: 16 additions & 24 deletions src/bpf_conformance.cc
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,18 @@ _generate_xdp_prolog(size_t size)
};
}

bpf_conformance_test_cpu_version_t
get_instruction_cpu_version(ebpf_inst inst)
{
auto instruction = std::find_if(instructions_from_spec.begin(), instructions_from_spec.end(), [&](const auto &instruction) {
return (instruction.opcode == inst.opcode) &&
(!needs_src(inst.opcode) || instruction.src == inst.src) &&
(!needs_imm(inst.opcode) || instruction.imm == inst.imm) &&
(!needs_offset(inst.opcode) || instruction.offset == inst.offset);
});
return instruction->cpu_version;
}

std::map<std::filesystem::path, std::tuple<bpf_conformance_test_result_t, std::string>>
bpf_conformance_options(
const std::vector<std::filesystem::path>& test_files,
Expand Down Expand Up @@ -178,28 +190,8 @@ bpf_conformance_options(
// Determine the required CPU version for the test.
for (size_t i = 0; i < byte_code.size(); i++) {
auto inst = byte_code[i];
// If this is an atomic store, then the test requires CPU version 3.
if (((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_STX) &&
(((inst.opcode & EBPF_MODE_ATOMIC) == EBPF_MODE_ATOMIC))) {
required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3);
}
// If this is a EBPF_CLS_JMP32, then we know this is v3.
else if ((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_JMP32) {
required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3);
} else if ((inst.opcode & EBPF_CLS_MASK) == EBPF_CLS_JMP) {
// If this is a EBPF_CLS_JMP, then check if it is a less than operation.
if ((inst.opcode & EBPF_ALU_OP_MASK) >= (EBPF_OP_JLT_IMM & EBPF_ALU_OP_MASK)) {
// It his is a less than operation, then we know this is v2.
required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v2);
}
}
// If the program uses local or runtime calls then this is v3 of the ABI.
// inst.src == 0 means helper function call.
// inst.src == 1 means local function call.
// inst.src == 2 means runtime function call.
if (inst.opcode == EBPF_OP_CALL && inst.src != 0) {
required_cpu_version = std::max(required_cpu_version, bpf_conformance_test_cpu_version_t::v3);
}
bpf_conformance_test_cpu_version_t cpu_version = get_instruction_cpu_version(inst);
required_cpu_version = std::max(required_cpu_version, cpu_version);
if (inst.opcode == EBPF_OP_LDDW) {
// Instruction has a 64-bit immediate and takes two instructions slots.
i++;
Expand All @@ -215,7 +207,7 @@ bpf_conformance_options(
}

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

// If the caller requires this as a XDP program, then add the prolog instructions.
Expand Down Expand Up @@ -302,7 +294,7 @@ bpf_conformance_options(
}
if (expected_error_string.empty()) {
test_results[test] = {
bpf_conformance_test_result_t::TEST_RESULT_FAIL,
bpf_conformance_test_result_t::TEST_RESULT_ERROR,
"Plugin returned error code " + std::to_string(c.exit_code()) + " and output " +
return_value_string};
} else {
Expand Down
Loading

0 comments on commit 13de786

Please sign in to comment.