diff --git a/.travis.yml b/.travis.yml index f5ea947f0..61c30764e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,13 +27,19 @@ dist: trusty # cache: directories: - - build/cache + - ../cache # # Build Dependencies # before_script: + # + # Cache / Depends + # + - mkdir -p ../cache + - mkdir -p ../depends + # # Build Enviornment # @@ -166,29 +172,28 @@ matrix: - make -j3 - make tidy - # # - # # Codecov - # # - # - os: linux - # addons: - # apt: - # sources: - # - ubuntu-toolchain-r-test - # - llvm-toolchain-trusty-4.0 - # packages: - # - gcc-6 - # - g++-6 - # - clang-4.0 - # - nasm - # env: - # - TEST="Codecov" - # script: - # - cmake -DCONFIG=travis_codecov .. - # - make -j3 - # - make test - # - rm -Rf depends - # - cd .. - # - bash <(curl -s https://codecov.io/bash) + # + # Codecov + # + - os: linux + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-trusty-4.0 + packages: + - gcc-6 + - g++-6 + - clang-4.0 + - nasm + env: + - TEST="Codecov" + script: + - cmake -DCONFIG=travis_codecov .. + - make -j3 + - make test + - cd .. + - bash <(curl -s https://codecov.io/bash) # # Google Address Sanitizer diff --git a/bfintrinsics/tests/arch/intel_x64/vmcs/test_debug.cpp b/bfintrinsics/tests/arch/intel_x64/vmcs/test_debug.cpp index 6b1b7bdb8..acaa76b94 100644 --- a/bfintrinsics/tests/arch/intel_x64/vmcs/test_debug.cpp +++ b/bfintrinsics/tests/arch/intel_x64/vmcs/test_debug.cpp @@ -54,6 +54,8 @@ proc_ctl_disallow1(uint64_t mask) TEST_CASE("debug_dump") { + CHECK_NOTHROW(_cpuid_eax(0)); + proc_ctl_disallow1(msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); CHECK_THROWS(dump()); diff --git a/bfm/tests/test_command_line_parser.cpp b/bfm/tests/test_command_line_parser.cpp index f7865cf08..6da07443e 100755 --- a/bfm/tests/test_command_line_parser.cpp +++ b/bfm/tests/test_command_line_parser.cpp @@ -16,11 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include - -#include -#include -#include +#include TEST_CASE("test command line parser with no args") { diff --git a/bfm/tests/test_ioctl_driver.cpp b/bfm/tests/test_ioctl_driver.cpp index a0b271675..83b6ab87d 100755 --- a/bfm/tests/test_ioctl_driver.cpp +++ b/bfm/tests/test_ioctl_driver.cpp @@ -16,9 +16,6 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include - #include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT diff --git a/bfm/tests/test_main.cpp b/bfm/tests/test_main.cpp index 46e99a319..079de8ea5 100644 --- a/bfm/tests/test_main.cpp +++ b/bfm/tests/test_main.cpp @@ -16,9 +16,6 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include - #include void bfm_flush(); diff --git a/bfm/tests/test_support.h b/bfm/tests/test_support.h index 15f83f2d3..554a8f571 100644 --- a/bfm/tests/test_support.h +++ b/bfm/tests/test_support.h @@ -16,7 +16,11 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include +#include + #include +#include #include #include #include @@ -74,3 +78,19 @@ _vmcall(vmcall_registers_t *regs) { bfignored(regs); } + +TEST_CASE("support") +{ + ioctl ctl{}; + int64_t status; + auto drr = ioctl::drr_type{}; + auto data = ioctl::binary_data{}; + + CHECK_NOTHROW(ctl.call_ioctl_add_module(data)); + CHECK_NOTHROW(ctl.call_ioctl_load_vmm()); + CHECK_NOTHROW(ctl.call_ioctl_unload_vmm()); + CHECK_NOTHROW(ctl.call_ioctl_start_vmm()); + CHECK_NOTHROW(ctl.call_ioctl_stop_vmm()); + CHECK_NOTHROW(ctl.call_ioctl_dump_vmm(&drr, 0)); + CHECK_NOTHROW(ctl.call_ioctl_vmm_status(&status)); +} diff --git a/bfvmm/include/hve/arch/x64/gdt.h b/bfvmm/include/hve/arch/x64/gdt.h index 7d0217de8..2be7a0cb1 100644 --- a/bfvmm/include/hve/arch/x64/gdt.h +++ b/bfvmm/include/hve/arch/x64/gdt.h @@ -459,7 +459,9 @@ class EXPORT_HVE gdt_x64 this->set_limit(index, limit); } +#ifndef ENABLE_BUILD_TEST private: +#endif /// @cond diff --git a/bfvmm/src/debug/CMakeLists.txt b/bfvmm/src/debug/CMakeLists.txt index 8f9ff0965..870a5e0ab 100644 --- a/bfvmm/src/debug/CMakeLists.txt +++ b/bfvmm/src/debug/CMakeLists.txt @@ -21,13 +21,18 @@ # ------------------------------------------------------------------------------ list(APPEND SOURCES - unistd.cpp debug_ring/debug_ring.cpp serial/serial_port_ns16550a.cpp serial/serial_port_pl011.cpp serial/serial_port_base.cpp ) +if(NOT ENABLE_MOCKING) + list(APPEND SOURCES + unistd.cpp + ) +endif() + add_shared_library( bfvmm_debug SOURCES ${SOURCES} diff --git a/bfvmm/src/hve/CMakeLists.txt b/bfvmm/src/hve/CMakeLists.txt index a38816e01..8b9012502 100644 --- a/bfvmm/src/hve/CMakeLists.txt +++ b/bfvmm/src/hve/CMakeLists.txt @@ -25,7 +25,7 @@ list(APPEND SOURCES arch/intel_x64/vmxon/vmxon.cpp ) -if(NOT WIN32) +if(NOT WIN32 AND NOT ENABLE_MOCKING) list(APPEND SOURCES arch/intel_x64/exit_handler/exit_handler_support.asm arch/intel_x64/vmcs/vmcs_launch.asm diff --git a/bfvmm/src/vcpu/CMakeLists.txt b/bfvmm/src/vcpu/CMakeLists.txt index 48132fc58..e9f940165 100644 --- a/bfvmm/src/vcpu/CMakeLists.txt +++ b/bfvmm/src/vcpu/CMakeLists.txt @@ -24,8 +24,13 @@ list(APPEND SOURCES if(${BUILD_TARGET_ARCH} STREQUAL "x86_64") list(APPEND SOURCES arch/intel_x64/vcpu.cpp - arch/intel_x64/vcpu_factory.cpp ) + + if(NOT ENABLE_MOCKING) + list(APPEND SOURCES + arch/intel_x64/vcpu_factory.cpp + ) + endif() elseif(${BUILD_TARGET_ARCH} STREQUAL "aarch64") message(WARNING "Unimplemented") else() diff --git a/bfvmm/tests/CMakeLists.txt b/bfvmm/tests/CMakeLists.txt index 191195d0a..aa245f731 100644 --- a/bfvmm/tests/CMakeLists.txt +++ b/bfvmm/tests/CMakeLists.txt @@ -23,13 +23,12 @@ include(${SOURCE_CMAKE_DIR}/project.cmake) init_project() add_subdirectory(../src/debug ${CMAKE_CURRENT_BINARY_DIR}/src/debug) -add_subdirectory(../src/entry ${CMAKE_CURRENT_BINARY_DIR}/src/entry) add_subdirectory(../src/hve ${CMAKE_CURRENT_BINARY_DIR}/src/hve) add_subdirectory(../src/memory_manager ${CMAKE_CURRENT_BINARY_DIR}/src/memory_manager) add_subdirectory(../src/vcpu ${CMAKE_CURRENT_BINARY_DIR}/src/vcpu) add_subdirectory(debug) -# add_subdirectory(entry) add_subdirectory(hve) add_subdirectory(memory_manager) -# add_subdirectory(vcpu) +add_subdirectory(vcpu) +add_subdirectory(support) diff --git a/bfvmm/tests/debug/serial/test_serial_port_ns16550a.cpp b/bfvmm/tests/debug/serial/test_serial_port_ns16550a.cpp index 5db41bf33..7069e55ce 100644 --- a/bfvmm/tests/debug/serial/test_serial_port_ns16550a.cpp +++ b/bfvmm/tests/debug/serial/test_serial_port_ns16550a.cpp @@ -44,6 +44,14 @@ extern "C" void _outd(uint16_t port, uint32_t val) noexcept { g_ports[port] = val; } +TEST_CASE("serial: support") +{ + CHECK_NOTHROW(_inb(0)); + CHECK_NOTHROW(_outb(0, 0)); + CHECK_NOTHROW(_ind(0)); + CHECK_NOTHROW(_outd(0, 0)); +} + TEST_CASE("serial: constructor_null_intrinsics") { CHECK_NOTHROW(std::make_unique()); diff --git a/bfvmm/tests/debug/serial/test_serial_port_pl011.cpp b/bfvmm/tests/debug/serial/test_serial_port_pl011.cpp index e30d78613..8c2cf2936 100644 --- a/bfvmm/tests/debug/serial/test_serial_port_pl011.cpp +++ b/bfvmm/tests/debug/serial/test_serial_port_pl011.cpp @@ -44,6 +44,14 @@ extern "C" void _outd(uint16_t port, uint32_t val) noexcept { g_ports[port] = val; } +TEST_CASE("serial: support") +{ + CHECK_NOTHROW(_inb(0)); + CHECK_NOTHROW(_outb(0, 0)); + CHECK_NOTHROW(_ind(0)); + CHECK_NOTHROW(_outd(0, 0)); +} + TEST_CASE("serial: constructor_null_intrinsics") { CHECK_NOTHROW(std::make_unique()); diff --git a/bfvmm/tests/hve/CMakeLists.txt b/bfvmm/tests/hve/CMakeLists.txt index 9ffed028b..c6ea9658f 100644 --- a/bfvmm/tests/hve/CMakeLists.txt +++ b/bfvmm/tests/hve/CMakeLists.txt @@ -24,6 +24,16 @@ list(APPEND ARGN DEFINES STATIC_INTRINSICS ) +do_test(test_gdt + SOURCES arch/x64/test_gdt.cpp + ${ARGN} +) + +do_test(test_idt + SOURCES arch/x64/test_idt.cpp + ${ARGN} +) + do_test(test_exit_handler SOURCES arch/intel_x64/exit_handler/test_exit_handler.cpp ${ARGN} @@ -34,6 +44,36 @@ do_test(test_exit_handler_entry ${ARGN} ) +do_test(test_vmcs_check_controls + SOURCES arch/intel_x64/vmcs/test_vmcs_check_controls.cpp + ${ARGN} +) + +do_test(test_vmcs_check_guest + SOURCES arch/intel_x64/vmcs/test_vmcs_check_guest.cpp + ${ARGN} +) + +do_test(test_vmcs_check_host + SOURCES arch/intel_x64/vmcs/test_vmcs_check_host.cpp + ${ARGN} +) + +do_test(test_vmcs_state_hvm + SOURCES arch/intel_x64/vmcs/test_vmcs_state_hvm.cpp + ${ARGN} +) + +do_test(test_vmcs_state_vmm + SOURCES arch/intel_x64/vmcs/test_vmcs_state_vmm.cpp + ${ARGN} +) + +do_test(test_vmcs_state + SOURCES arch/intel_x64/vmcs/test_vmcs_state.cpp + ${ARGN} +) + do_test(test_vmcs SOURCES arch/intel_x64/vmcs/test_vmcs.cpp ${ARGN} diff --git a/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler.cpp b/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler.cpp index 568ae76f5..e2c39c937 100644 --- a/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler.cpp @@ -16,7 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../test_support.h" +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT @@ -37,7 +37,7 @@ setup_vmcs_unhandled(MockRepository &mocks, vmcs::value_type reason) g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] = 0xFFFFFFFF00000000UL; g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000UL; - g_exit_reason = reason; + g_vmcs_fields[vmcs::exit_reason::addr] = reason; return vmcs; } @@ -56,7 +56,7 @@ setup_vmcs_handled(MockRepository &mocks, vmcs::value_type reason) } g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFFFFFFFFFFUL; - g_exit_reason = reason; + g_vmcs_fields[vmcs::exit_reason::addr] = reason; return vmcs; } @@ -73,7 +73,7 @@ setup_vmcs_halt(MockRepository &mocks, vmcs::value_type reason) mocks.NeverCall(vmcs, vmcs_intel_x64::resume); g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFFFFFFFFFFUL; - g_exit_reason = reason; + g_vmcs_fields[vmcs::exit_reason::addr] = reason; return vmcs; } @@ -90,7 +90,7 @@ setup_vmcs_promote(MockRepository &mocks, vmcs::value_type reason) mocks.NeverCall(vmcs, vmcs_intel_x64::resume); g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFFFFFFFFFFUL; - g_exit_reason = reason; + g_vmcs_fields[vmcs::exit_reason::addr] = reason; return vmcs; } @@ -102,7 +102,7 @@ setup_ehlr(gsl::not_null vmcs) ehlr.set_vmcs(vmcs); ehlr.set_state_save(&g_state_save); - g_rip = ehlr.m_state_save->rip + g_exit_instruction_length; + g_rip = ehlr.m_state_save->rip + g_vmcs_fields[vmcs::vm_exit_instruction_length::addr]; return ehlr; } @@ -1025,18 +1025,18 @@ TEST_CASE("exit_handler: vm_exit_reason_vmxoff") setup_mm(mocks); setup_pt(mocks); - g_guest_cr3 = 0x1000; - g_guest_gdtr_limit = 0x4; - g_guest_gdtr_base = 0x432000; + g_vmcs_fields[vmcs::guest_cr3::addr] = 0x1000; + g_vmcs_fields[vmcs::guest_gdtr_limit::addr] = 0x4; + g_vmcs_fields[vmcs::guest_gdtr_base::addr] = 0x432000; auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::vmxoff); auto ehlr = setup_ehlr(vmcs); CHECK_THROWS(ehlr.dispatch()); - g_guest_cr3 = 0x0; - g_guest_gdtr_limit = 0x0; - g_guest_gdtr_base = 0x0; + g_vmcs_fields[vmcs::guest_cr3::addr] = 0x0; + g_vmcs_fields[vmcs::guest_gdtr_limit::addr] = 0x0; + g_vmcs_fields[vmcs::guest_gdtr_base::addr] = 0x0; } TEST_CASE("exit_handler: vm_exit_reason_rdmsr_debug_ctl") @@ -1045,12 +1045,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_debug_ctl") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000200000001; + g_vmcs_fields[vmcs::guest_ia32_debugctl::addr] = 0x0000000200000001; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_debugctl::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_debugctl::addr); CHECK(ehlr.m_state_save->rax == 0x1); CHECK(ehlr.m_state_save->rdx == 0x2); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1062,14 +1061,13 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_pat") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000300000002; + g_vmcs_fields[vmcs::guest_ia32_pat::addr] = 0x0000000300000002; ehlr.m_state_save->rcx = x64::msrs::ia32_pat::addr; g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_pat::mask << 32; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_pat::addr); CHECK(ehlr.m_state_save->rax == 0x2); CHECK(ehlr.m_state_save->rdx == 0x3); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1081,14 +1079,13 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_efer") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000400000003; + g_vmcs_fields[vmcs::guest_ia32_efer::addr] = 0x0000000400000003; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_efer::addr; g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_efer::mask << 32; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_efer::addr); CHECK(ehlr.m_state_save->rax == 0x3); CHECK(ehlr.m_state_save->rdx == 0x4); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1100,14 +1097,13 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_perf") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000400000003; + g_vmcs_fields[vmcs::guest_ia32_perf_global_ctrl::addr] = 0x0000000400000003; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_perf_global_ctrl::addr; g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_perf_global_ctrl::mask << 32; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_perf_global_ctrl::addr); CHECK(ehlr.m_state_save->rax == 0x3); CHECK(ehlr.m_state_save->rdx == 0x4); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1119,12 +1115,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_cs") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000500000004; + g_vmcs_fields[vmcs::guest_ia32_sysenter_cs::addr] = 0x0000000500000004; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_sysenter_cs::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_cs::addr); CHECK(ehlr.m_state_save->rax == 0x4); CHECK(ehlr.m_state_save->rdx == 0x5); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1136,12 +1131,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_esp") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000600000005; + g_vmcs_fields[vmcs::guest_ia32_sysenter_esp::addr] = 0x0000000600000005; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_sysenter_esp::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_esp::addr); CHECK(ehlr.m_state_save->rax == 0x5); CHECK(ehlr.m_state_save->rdx == 0x6); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1153,12 +1147,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_eip") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000700000006; + g_vmcs_fields[vmcs::guest_ia32_sysenter_eip::addr] = 0x0000000700000006; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_sysenter_eip::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_eip::addr); CHECK(ehlr.m_state_save->rax == 0x6); CHECK(ehlr.m_state_save->rdx == 0x7); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1170,12 +1163,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_fs_base") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000800000007; + g_vmcs_fields[vmcs::guest_fs_base::addr] = 0x0000000800000007; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_fs_base::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_fs_base::addr); CHECK(ehlr.m_state_save->rax == 0x7); CHECK(ehlr.m_state_save->rdx == 0x8); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1187,12 +1179,11 @@ TEST_CASE("exit_handler: vm_exit_reason_rdmsr_gs_base") auto vmcs = setup_vmcs_handled(mocks, exit_reason::basic_exit_reason::rdmsr); auto ehlr = setup_ehlr(vmcs); - g_value = 0x0000000900000008; + g_vmcs_fields[vmcs::guest_gs_base::addr] = 0x0000000900000008; ehlr.m_state_save->rcx = intel_x64::msrs::ia32_gs_base::addr; CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_gs_base::addr); CHECK(ehlr.m_state_save->rax == 0x8); CHECK(ehlr.m_state_save->rdx == 0x9); CHECK(ehlr.m_state_save->rip == g_rip); @@ -1242,8 +1233,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_debug_ctrl") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_debugctl::addr); - CHECK(g_value == 0x0000000200000001); + CHECK(g_vmcs_fields[ vmcs::guest_ia32_debugctl::addr] == 0x0000000200000001); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1261,8 +1251,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_pat") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_pat::addr); - CHECK(g_value == 0x0000000300000002); + CHECK(g_vmcs_fields[vmcs::guest_ia32_pat::addr] == 0x0000000300000002); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1280,8 +1269,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_efer") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_efer::addr); - CHECK(g_value == 0x0000000400000003); + CHECK(g_vmcs_fields[vmcs::guest_ia32_efer::addr] == 0x0000000400000003); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1299,8 +1287,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_perf") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_perf_global_ctrl::addr); - CHECK(g_value == 0x0000000400000003); + CHECK(g_vmcs_fields[vmcs::guest_ia32_perf_global_ctrl::addr] == 0x0000000400000003); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1316,8 +1303,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_cs") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_cs::addr); - CHECK(g_value == 0x0000000500000004); + CHECK(g_vmcs_fields[vmcs::guest_ia32_sysenter_cs::addr] == 0x0000000500000004); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1333,8 +1319,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_esp") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_esp::addr); - CHECK(g_value == 0x0000000600000005); + CHECK(g_vmcs_fields[vmcs::guest_ia32_sysenter_esp::addr] == 0x0000000600000005); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1350,8 +1335,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_eip") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_ia32_sysenter_eip::addr); - CHECK(g_value == 0x0000000700000006); + CHECK(g_vmcs_fields[vmcs::guest_ia32_sysenter_eip::addr] == 0x0000000700000006); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1367,8 +1351,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_fs_base") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_fs_base::addr); - CHECK(g_value == 0x0000000800000007); + CHECK(g_vmcs_fields[vmcs::guest_fs_base::addr] == 0x0000000800000007); CHECK(ehlr.m_state_save->rip == g_rip); } @@ -1384,8 +1367,7 @@ TEST_CASE("exit_handler: vm_exit_reason_wrmsr_gs_base") CHECK_NOTHROW(ehlr.dispatch()); - CHECK(g_field == vmcs::guest_gs_base::addr); - CHECK(g_value == 0x0000000900000008); + CHECK(g_vmcs_fields[vmcs::guest_gs_base::addr] == 0x0000000900000008); CHECK(ehlr.m_state_save->rip == g_rip); } diff --git a/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler_entry.cpp b/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler_entry.cpp index 914310ec2..6b1e63bd6 100644 --- a/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler_entry.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/exit_handler/test_exit_handler_entry.cpp @@ -16,7 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../test_support.h" +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT diff --git a/bfvmm/tests/hve/arch/intel_x64/test_support.h b/bfvmm/tests/hve/arch/intel_x64/test_support.h deleted file mode 100644 index ac5d1f208..000000000 --- a/bfvmm/tests/hve/arch/intel_x64/test_support.h +++ /dev/null @@ -1,481 +0,0 @@ -// -// Bareflank Hypervisor -// Copyright (C) 2015 Assured Information Security, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -using namespace x64; -using namespace intel_x64; -using namespace vmcs; - -std::map g_msrs; -std::map g_vmcs_fields; -std::map g_eax_cpuid; -std::map g_ebx_cpuid; -std::map g_ecx_cpuid; - -uintptr_t g_rip = 0; - -vmcs::field_type g_field = 0; -vmcs::value_type g_value = 0; -vmcs::value_type g_exit_reason = 0; -vmcs::value_type g_exit_qualification = 0; -vmcs::value_type g_exit_instruction_length = 8; -vmcs::value_type g_exit_instruction_information = 0; -vmcs::value_type g_guest_cr3 = 0; -vmcs::value_type g_guest_gdtr_limit = 0; -vmcs::value_type g_guest_gdtr_base = 0; - -intel_x64::cr0::value_type g_cr0 = 0; -intel_x64::cr3::value_type g_cr3 = 0; -intel_x64::cr4::value_type g_cr4 = 0; -x64::rflags::value_type g_rflags = 0; - -alignas(0x1000) static char g_map[100]; - -auto g_msg = std::string(R"%({"msg":"hello world"})%"); -auto g_state_save = state_save_intel_x64 {}; - -bool g_virt_to_phys_fails = false; -bool g_phys_to_virt_fails = false; -bool g_vmclear_fails = false; -bool g_vmload_fails = false; -bool g_vmlaunch_fails = false; -bool g_vmxon_fails = false; -bool g_vmxoff_fails = false; -bool g_write_cr4_fails = false; - -uint64_t g_test_addr = 0U; - -uint64_t g_virt_apic_addr = 0U; -uint64_t g_virt_apic_mem[64] = {0U}; - -uint64_t g_vmcs_link_addr = 1U; -uint64_t g_vmcs_link_mem[1] = {0U}; - -uint64_t g_pdpt_addr = 2U; -uint64_t g_pdpt_mem[4] = {0U}; - -std::map g_mock_mem {{ - {g_virt_apic_addr, static_cast(&g_virt_apic_mem)}, - {g_vmcs_link_addr, static_cast(&g_vmcs_link_mem)}, - {g_pdpt_addr, static_cast(&g_pdpt_mem)} -}}; - -extern "C" uint64_t -_read_msr(uint32_t addr) noexcept -{ return g_msrs[addr]; } - -extern "C" void -_write_msr(uint32_t addr, uint64_t val) noexcept -{ g_msrs[addr] = val; } - -extern "C" void -_write_gdt(void *gdt_reg) noexcept -{ bfignored(gdt_reg); } - -extern "C" void -_write_idt(void *idt_reg) noexcept -{ bfignored(idt_reg); } - -extern "C" void -_write_es(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_cs(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_ss(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_ds(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_fs(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_gs(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_ldtr(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" void -_write_tr(uint16_t val) noexcept -{ bfignored(val); } - -extern "C" uint64_t -_read_cr0(void) noexcept -{ return g_cr0; } - -extern "C" uint64_t -_read_cr3(void) noexcept -{ return g_cr3; } - -extern "C" uint64_t -_read_cr4(void) noexcept -{ return g_cr4; } - -extern "C" void -_write_cr0(uint64_t val) noexcept -{ g_cr0 = val; } - -extern "C" void -_write_cr3(uint64_t val) noexcept -{ g_cr3 = val; } - -extern "C" void -_write_cr4(uint64_t val) noexcept -{ - if (g_write_cr4_fails) { - return; - } - - g_cr4 = val; -} - -extern "C" void -_write_dr7(uint64_t val) noexcept -{ bfignored(val); } - -extern "C" uint64_t -_read_rflags(void) noexcept -{ return g_rflags; } - -extern "C" void -_stop() noexcept -{ } - -extern "C" void -_wbinvd() noexcept -{ } - -extern "C" void -_invlpg(const void *addr) noexcept -{ bfignored(addr); } - -extern "C" void -_cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept -{ - bfignored(eax); - bfignored(ebx); - bfignored(ecx); - bfignored(edx); -} - -extern "C" uint32_t -_cpuid_eax(uint32_t val) noexcept -{ return g_eax_cpuid[val]; } - -extern "C" uint32_t -_cpuid_subebx(uint32_t val, uint32_t sub) noexcept -{ bfignored(sub); return g_ebx_cpuid[val]; } - -extern "C" uint32_t -_cpuid_ecx(uint32_t val) noexcept -{ return g_ecx_cpuid[val]; } - -extern "C" bool -_vmread(uint64_t field, uint64_t *val) noexcept -{ - switch (field) { - case vmcs::exit_reason::addr: - *val = g_exit_reason; - break; - case vmcs::exit_qualification::addr: - *val = g_exit_qualification; - break; - case vmcs::vm_exit_instruction_length::addr: - *val = g_exit_instruction_length; - break; - case vmcs::vm_exit_instruction_information::addr: - *val = g_exit_instruction_information; - break; - case vmcs::guest_linear_address::addr: - *val = 0x0; - break; - case vmcs::guest_physical_address::addr: - *val = 0x0; - break; - case vmcs::guest_cr3::addr: - *val = g_guest_cr3; - break; - case vmcs::guest_gdtr_limit::addr: - *val = g_guest_gdtr_limit; - break; - case vmcs::guest_gdtr_base::addr: - *val = g_guest_gdtr_base; - break; - default: - g_field = field; - *val = g_value; - break; - } - - return true; -} - -extern "C" bool -_vmwrite(uint64_t field, uint64_t val) noexcept -{ - g_field = field; - g_value = val; - - return true; -} - -extern "C" bool -_vmclear(void *ptr) noexcept -{ (void)ptr; return !g_vmclear_fails; } - -extern "C" bool -_vmptrld(void *ptr) noexcept -{ (void)ptr; return !g_vmload_fails; } - -extern "C" bool -_vmlaunch_demote() noexcept -{ return !g_vmlaunch_fails; } - -extern "C" bool -_vmxon(void *ptr) noexcept -{ - bfignored(ptr); - return !g_vmxon_fails; -} - -extern "C" bool -_vmxoff() noexcept -{ return !g_vmxoff_fails; } - -extern "C" uint64_t -thread_context_cpuid(void) -{ return 0; } - -extern "C" uint64_t -thread_context_tlsptr(void) -{ return 0; } - -uintptr_t -virtptr_to_physint(void *ptr) -{ - bfignored(ptr); - - if (g_virt_to_phys_fails) { - throw gsl::fail_fast(""); - } - - return 0x0000000ABCDEF0000; -} - -void * -physint_to_virtptr(uintptr_t ptr) -{ - bfignored(ptr); - - if (g_phys_to_virt_fails) { - return nullptr; - } - - return static_cast(g_mock_mem[g_test_addr]); -} - -extern "C" void -vmcs_launch(state_save_intel_x64 *state_save) noexcept -{ } - -extern "C" void -vmcs_promote(state_save_intel_x64 *state_save, const void *guest_gdt) noexcept -{ } - -extern "C" void -vmcs_resume(state_save_intel_x64 *state_save) noexcept -{ } - -void -setup_msrs() -{ - g_msrs[intel_x64::msrs::ia32_vmx_basic::addr] = (1ULL << 55) | (6ULL << 50); - g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] = 0xFFFFFFFF00000000UL; - g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] = 0xFFFFFFFF00000000UL; - g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] = 0xFFFFFFFF00000000UL; - g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] = 0xFFFFFFFF00000000UL; - g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000UL; - - g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed0::addr] = 0U; - g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFF; - g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed0::addr] = 0U; - g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFF; - - g_msrs[intel_x64::msrs::ia32_efer::addr] = intel_x64::msrs::ia32_efer::lma::mask; - g_msrs[intel_x64::msrs::ia32_feature_control::addr] = (0x1ULL << 0); -} - -void -setup_cpuid() -{ - g_ecx_cpuid[intel_x64::cpuid::feature_information::addr] = intel_x64::cpuid::feature_information::ecx::vmx::mask; -} - -void -setup_registers() -{ - g_cr0 = 0x0; - g_cr3 = 0x0; - g_cr4 = 0x0; - g_rflags = 0x0; -} - -#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT - -auto -setup_mm(MockRepository &mocks) -{ - auto mm = mocks.Mock(); - mocks.OnCallFunc(memory_manager_x64::instance).Return(mm); - - mocks.OnCall(mm, memory_manager_x64::alloc_map).Return(static_cast(g_map)); - mocks.OnCall(mm, memory_manager_x64::free_map); - mocks.OnCall(mm, memory_manager_x64::virtptr_to_physint).Do(virtptr_to_physint); - mocks.OnCall(mm, memory_manager_x64::physint_to_virtptr).Do(physint_to_virtptr); - - mocks.OnCallFunc(bfn::map_with_cr3); - mocks.OnCallFunc(bfn::virt_to_phys_with_cr3).Return(0x42); - - return mm; -} - -auto -setup_pt(MockRepository &mocks) -{ - auto pt = mocks.Mock(); - mocks.OnCallFunc(root_pt).Return(pt); - - mocks.OnCall(pt, root_page_table_x64::map_4k); - mocks.OnCall(pt, root_page_table_x64::unmap); - - return pt; -} - -auto -setup_vmcs_state(MockRepository &mocks) -{ - auto state = mocks.Mock(); - - mocks.OnCall(state, vmcs_intel_x64_state::es).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::cs).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::ss).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::ds).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::fs).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::gs).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::ldtr).Return(0x10); - mocks.OnCall(state, vmcs_intel_x64_state::tr).Return(0x10); - - mocks.OnCall(state, vmcs_intel_x64_state::gdt_limit).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::idt_limit).Return(0); - - mocks.OnCall(state, vmcs_intel_x64_state::es_limit).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::cs_limit).Return(0xFFFFFFFF); - mocks.OnCall(state, vmcs_intel_x64_state::ss_limit).Return(0xFFFFFFFF); - mocks.OnCall(state, vmcs_intel_x64_state::ds_limit).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::fs_limit).Return(0xFFFFFFFF); - mocks.OnCall(state, vmcs_intel_x64_state::gs_limit).Return(0xFFFFFFFF); - mocks.OnCall(state, vmcs_intel_x64_state::ldtr_limit).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::tr_limit).Return(sizeof(tss_x64)); - - mocks.OnCall(state, vmcs_intel_x64_state::es_access_rights).Return(access_rights::unusable); - mocks.OnCall(state, vmcs_intel_x64_state::cs_access_rights).Return(access_rights::ring0_cs_descriptor); - mocks.OnCall(state, vmcs_intel_x64_state::ss_access_rights).Return(access_rights::ring0_ss_descriptor); - mocks.OnCall(state, vmcs_intel_x64_state::ds_access_rights).Return(access_rights::unusable); - mocks.OnCall(state, vmcs_intel_x64_state::fs_access_rights).Return(access_rights::ring0_fs_descriptor); - mocks.OnCall(state, vmcs_intel_x64_state::gs_access_rights).Return(access_rights::ring0_gs_descriptor); - mocks.OnCall(state, vmcs_intel_x64_state::ldtr_access_rights).Return(access_rights::unusable); - mocks.OnCall(state, vmcs_intel_x64_state::tr_access_rights).Return(access_rights::ring0_tr_descriptor); - - mocks.OnCall(state, vmcs_intel_x64_state::es_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::cs_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ss_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ds_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ds_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::fs_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::gs_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ldtr_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::tr_base).Return(0); - - auto cr0 = 0UL; - cr0 |= cr0::paging::mask; - cr0 |= cr0::protection_enable::mask; - - auto cr4 = 0UL; - cr4 |= cr4::physical_address_extensions::mask; - - auto rflags = 0UL; - rflags |= rflags::interrupt_enable_flag::mask; - - mocks.OnCall(state, vmcs_intel_x64_state::cr0).Return(cr0); - mocks.OnCall(state, vmcs_intel_x64_state::cr3).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::cr4).Return(cr4); - mocks.OnCall(state, vmcs_intel_x64_state::dr7).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::rflags).Return(rflags); - mocks.OnCall(state, vmcs_intel_x64_state::gdt_base).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::idt_base).Return(0); - - auto efer = 0UL; - efer |= intel_x64::msrs::ia32_efer::lme::mask; - efer |= intel_x64::msrs::ia32_efer::lma::mask; - - mocks.OnCall(state, vmcs_intel_x64_state::ia32_debugctl_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_pat_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_efer_msr).Return(efer); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_perf_global_ctrl_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_cs_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_esp_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_eip_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_fs_base_msr).Return(0); - mocks.OnCall(state, vmcs_intel_x64_state::ia32_gs_base_msr).Return(0); - - mocks.OnCall(state, vmcs_intel_x64_state::is_guest).Return(false); - mocks.OnCall(state, vmcs_intel_x64_state::dump); - - return state; -} - -#endif diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs.cpp index 9f9e33bd6..ea8d263ef 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs.cpp @@ -16,7 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../test_support.h" +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT @@ -41,10 +41,8 @@ TEST_CASE("vmcs: launch_vmlaunch_failure") auto guest_state = setup_vmcs_state(mocks); setup_msrs(); - mocks.OnCallFunc(check::all); - mocks.OnCallFunc(debug::dump); - mocks.OnCall(guest_state, vmcs_intel_x64_state::is_guest).Return(true); + mocks.OnCall(guest_state, vmcs_intel_x64_state::is_guest).Return(true); mocks.OnCallFunc(vmcs_launch); vmcs_intel_x64 vmcs{}; @@ -59,6 +57,7 @@ TEST_CASE("vmcs: launch_vmlaunch_demote_failure") auto guest_state = setup_vmcs_state(mocks); setup_msrs(); + mocks.OnCallFunc(check::all); mocks.OnCallFunc(debug::dump); mocks.OnCall(guest_state, vmcs_intel_x64_state::is_guest).Return(false); @@ -162,4 +161,26 @@ TEST_CASE("vmcs: resume_failure") CHECK_THROWS(vmcs.resume()); } +TEST_CASE("vmcs: clear") +{ + vmcs_intel_x64 vmcs{}; + CHECK_NOTHROW(vmcs.clear()); +} + +TEST_CASE("vmcs: set_pre_launch_delegate") +{ + vmcs_intel_x64::pre_launch_delegate_t d; + + vmcs_intel_x64 vmcs{}; + CHECK_NOTHROW(vmcs.set_pre_launch_delegate(d)); +} + +TEST_CASE("vmcs: set_post_launch_delegate") +{ + vmcs_intel_x64::post_launch_delegate_t d; + + vmcs_intel_x64 vmcs{}; + CHECK_NOTHROW(vmcs.set_post_launch_delegate(d)); +} + #endif diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_controls.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_controls.cpp index 6c6ab7a4c..8510e1a82 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_controls.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_controls.cpp @@ -15,76 +15,16 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -#include -#include - -#include -#include -#include +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -using namespace intel_x64; -using namespace msrs; -using namespace vmcs; -using namespace check; - -struct cpuid_regs g_cpuid_regs; - - -bool g_phys_to_virt_return_nullptr = false; -uint64_t g_test_addr = 0U; -uint64_t g_virt_apic_addr = 0U; -uint8_t g_virt_apic_mem[0x81] = {0U}; - -std::map g_mock_mem { - { - {g_virt_apic_addr, static_cast(&g_virt_apic_mem)}, - } -}; - -uint32_t -test_cpuid_eax(uint32_t val) noexcept -{ return g_eax_cpuid[val]; } - -uint64_t -test_read_msr(uint32_t addr) noexcept -{ return g_msrs[addr]; } - -static bool -test_vmread(uint64_t field, uint64_t *val) noexcept -{ - *val = g_vmcs_fields[field]; - return true; -} - -static bool -test_vmwrite(uint64_t field, uint64_t val) noexcept -{ - g_vmcs_fields[field] = val; - return true; -} - -static void -setup_intrinsics(MockRepository &mocks, memory_manager_x64 *mm) -{ - mocks.OnCallFunc(memory_manager_x64::instance).Return(mm); - mocks.OnCall(mm, memory_manager_x64::physint_to_virtptr).Do(test_physint_to_virtptr); - mocks.OnCallFunc(_cpuid_eax).Do(test_cpuid_eax); - mocks.OnCallFunc(_read_msr).Do(test_read_msr); - mocks.OnCallFunc(_vmread).Do(test_vmread); - mocks.OnCallFunc(_vmwrite).Do(test_vmwrite); -} - -static struct control_flow_path path; - void test_vmcs_check(std::vector cfg, void(*func)()) { for (auto p : cfg) { MockRepository mocks; - auto mm = mocks.Mock(); - setup_intrinsics(mocks, mm); + setup_mm(mocks); p.setup(); @@ -101,11 +41,11 @@ static void setup_check_control_pin_based_ctls_reserved_properly_set_paths(std::vector &cfg) { - path.setup = [&] { g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL; }; path.throws_exception = false; cfg.push_back(path); - path.setup = [&] { g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 1; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] = 1; }; path.throws_exception = true; cfg.push_back(path); @@ -118,11 +58,11 @@ static void setup_check_control_proc_based_ctls_reserved_properly_set_paths( std::vector &cfg) { - path.setup = [&] { g_msrs[ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL; }; path.throws_exception = false; cfg.push_back(path); - path.setup = [&] { g_msrs[ia32_vmx_true_procbased_ctls::addr] = 1; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] = 1; }; path.throws_exception = true; cfg.push_back(path); @@ -135,19 +75,19 @@ static void setup_check_control_proc_based_ctls2_reserved_properly_set_paths( std::vector &cfg) { - path.setup = [&] { proc_ctl_disallow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); }; + path.setup = [&] { proc_ctl_disallow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); }; path.throws_exception = true; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL; + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL; }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - g_msrs[ia32_vmx_procbased_ctls2::addr] |= 1; + g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] |= 1; secondary_processor_based_vm_execution_controls::set(0UL); }; path.throws_exception = true; @@ -156,7 +96,7 @@ setup_check_control_proc_based_ctls2_reserved_properly_set_paths( path.setup = [&] { using namespace secondary_processor_based_vm_execution_controls; - g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xfffffffe00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] = 0xfffffffe00000000UL; primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); // we use the _fields_ set() here rather than the controls enable() @@ -187,7 +127,7 @@ static void setup_check_control_io_bitmap_address_bits_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::use_io_bitmaps::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::use_io_bitmaps::mask); primary_processor_based_vm_execution_controls::use_io_bitmaps::disable(); g_eax_cpuid[x64::cpuid::addr_size::addr] = 48U; }; @@ -195,7 +135,7 @@ setup_check_control_io_bitmap_address_bits_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::use_msr_bitmap::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::use_msr_bitmap::mask); primary_processor_based_vm_execution_controls::use_msr_bitmap::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::use_msr_bitmap::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::use_msr_bitmap::mask); primary_processor_based_vm_execution_controls::use_msr_bitmap::enable(); address_of_msr_bitmap::set(0x1U); }; @@ -301,13 +241,13 @@ setup_check_control_tpr_shadow_and_virtual_apic_paths(std::vector &cfg) { path.setup = [&] { - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::nmi_exiting::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::nmi_exiting::mask); pin_based_vm_execution_controls::nmi_exiting::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - pin_ctl_allow0(ia32_vmx_true_pinbased_ctls::nmi_exiting::mask); - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); + pin_ctl_allow0(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::nmi_exiting::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); pin_based_vm_execution_controls::nmi_exiting::disable(); pin_based_vm_execution_controls::virtual_nmis::enable(); }; @@ -384,7 +324,7 @@ setup_check_control_nmi_exiting_and_virtual_nmi_paths(std::vector &cfg) { path.setup = [&] { - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); pin_based_vm_execution_controls::virtual_nmis::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::nmi_window_exiting::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::virtual_nmis::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::nmi_window_exiting::mask); pin_based_vm_execution_controls::virtual_nmis::disable(); primary_processor_based_vm_execution_controls::nmi_window_exiting::enable(); }; @@ -411,7 +351,7 @@ setup_check_control_virtual_nmi_and_nmi_window_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::virtualize_apic_accesses::disable(); }; @@ -463,15 +403,15 @@ setup_check_control_x2apic_mode_and_virtual_apic_access_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::virtual_interrupt_delivery::disable(); }; @@ -518,9 +458,9 @@ setup_check_control_virtual_interrupt_and_external_interrupt_paths( cfg.push_back(path); path.setup = [&] { - pin_ctl_allow0(ia32_vmx_true_pinbased_ctls::external_interrupt_exiting::mask); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); + pin_ctl_allow0(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::external_interrupt_exiting::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); secondary_processor_based_vm_execution_controls::virtual_interrupt_delivery::enable(); pin_based_vm_execution_controls::external_interrupt_exiting::disable(); }; @@ -528,7 +468,7 @@ setup_check_control_virtual_interrupt_and_external_interrupt_paths( cfg.push_back(path); path.setup = [&] { - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::external_interrupt_exiting::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::external_interrupt_exiting::mask); pin_based_vm_execution_controls::external_interrupt_exiting::enable(); }; path.throws_exception = false; @@ -540,15 +480,15 @@ setup_check_control_process_posted_interrupt_checks_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::enable_vpid::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::enable_vpid::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::enable_vpid::disable(); }; @@ -618,8 +558,8 @@ setup_check_control_vpid_checks_paths(std::vector &cfg cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::enable_vpid::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::enable_vpid::mask); secondary_processor_based_vm_execution_controls::enable_vpid::enable(); virtual_processor_identifier::set(0U); }; @@ -655,8 +595,8 @@ setup_check_control_enable_ept_checks_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::enable_pml::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::enable_pml::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::enable_pml::disable(); }; @@ -712,9 +652,9 @@ setup_check_control_enable_pml_checks_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::virtual_interrupt_delivery::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); }; @@ -759,9 +699,9 @@ setup_check_control_unrestricted_guests_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::vmcs_shadowing::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::vmcs_shadowing::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::vmcs_shadowing::disable(); }; @@ -873,7 +813,7 @@ setup_check_control_enable_vmcs_shadowing_paths(std::vector &cfg) { path.setup = [&] { - proc_ctl_allow0(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl_allow0(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::ept_violation_ve::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::ept_violation_ve::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::ept_violation_ve::disable(); }; @@ -920,8 +860,8 @@ setup_check_control_enable_ept_violation_checks_paths(std::vector &cfg) { path.setup = [&] { - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); pin_based_vm_execution_controls::activate_vmx_preemption_timer::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - pin_ctl_allow0(ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); - exit_ctl_allow1(ia32_vmx_true_exit_ctls::save_vmx_preemption_timer_value::mask); + pin_ctl_allow0(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::save_vmx_preemption_timer_value::mask); pin_based_vm_execution_controls::activate_vmx_preemption_timer::disable(); vm_exit_controls::save_vmx_preemption_timer_value::enable(); }; @@ -978,7 +918,7 @@ setup_check_control_activate_and_save_preemption_timer_must_be_0_paths( cfg.push_back(path); path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::save_vmx_preemption_timer_value::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::save_vmx_preemption_timer_value::mask); vm_exit_controls::save_vmx_preemption_timer_value::disable(); }; path.throws_exception = false; @@ -1062,17 +1002,17 @@ setup_check_control_vm_entry_ctls_reserved_properly_set_paths(std::vector(); - setup_intrinsics(mocks, mm); + setup_mm(mocks); - g_msrs[ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL; vm_entry_controls::set(0x1234UL); - auto msr_addr = ia32_vmx_true_entry_ctls::addr; + auto msr_addr = intel_x64::msrs::ia32_vmx_true_entry_ctls::addr; auto ctls = vm_entry_controls::get(); auto name = vm_entry_controls::name; - CHECK_NOTHROW(control_reserved_properly_set(msr_addr, ctls, name)); + CHECK_NOTHROW(check::control_reserved_properly_set(msr_addr, ctls, name)); } TEST_CASE("check_memory_type_reserved") { MockRepository mocks; - auto mm = mocks.Mock(); - setup_intrinsics(mocks, mm); + setup_mm(mocks); CHECK_FALSE(memory_type_reserved(x64::memory_type::write_through)); CHECK(memory_type_reserved(8U)); diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_guest.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_guest.cpp index d7f686d29..3136143af 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_guest.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_check_guest.cpp @@ -15,98 +15,16 @@ // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -#include -#include -#include -#include -#include -#include +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -TEST_CASE("test name goes here") -{ - CHECK(true); -} - -using namespace intel_x64; -using namespace msrs; -using namespace vmcs; - -struct cpuid_regs g_cpuid_regs; - -std::map g_msrs; -std::map g_vmcs_fields; -std::map g_eax_cpuid; -std::map g_ebx_cpuid; - -bool g_phys_to_virt_return_nullptr = false; - -uint64_t g_test_addr = 0U; -uint64_t g_virt_apic_addr = 0U; -uint8_t g_virt_apic_mem[0x81] = {0U}; - -uint64_t g_vmcs_link_addr = 1U; -uint32_t g_vmcs_link_mem[1] = {0U}; - -uint64_t g_pdpt_addr = 2U; -uint64_t g_pdpt_mem[4] = {0U}; - -std::map g_mock_mem { - { - {g_virt_apic_addr, static_cast(&g_virt_apic_mem)}, - {g_vmcs_link_addr, static_cast(&g_vmcs_link_mem)}, - {g_pdpt_addr, static_cast(&g_pdpt_mem)} - } -}; - -uint32_t -test_cpuid_eax(uint32_t val) noexcept -{ return g_eax_cpuid[val]; } - -uint32_t -test_cpuid_subebx(uint32_t val, uint32_t sub) noexcept -{ bfignored(sub); return g_ebx_cpuid[val]; } - -uint64_t -test_read_msr(uint32_t addr) noexcept -{ return g_msrs[addr]; } - -static bool -test_vmread(uint64_t field, uint64_t *val) noexcept -{ - *val = g_vmcs_fields[field]; - return true; -} - -static bool -test_vmwrite(uint64_t field, uint64_t val) noexcept -{ - g_vmcs_fields[field] = val; - return true; -} - -static void -setup_intrinsics(MockRepository &mocks, memory_manager_x64 *mm) -{ - mocks.OnCallFunc(memory_manager_x64::instance).Return(mm); - mocks.OnCall(mm, memory_manager_x64::physint_to_virtptr).Do(test_physint_to_virtptr); - mocks.OnCallFunc(_cpuid_eax).Do(test_cpuid_eax); - mocks.OnCallFunc(_cpuid_subebx).Do(test_cpuid_subebx); - mocks.OnCallFunc(_read_msr).Do(test_read_msr); - mocks.OnCallFunc(_vmread).Do(test_vmread); - mocks.OnCallFunc(_vmwrite).Do(test_vmwrite); -} - -static struct control_flow_path path; - void test_vmcs_check(std::vector cfg, void(*func)()) { for (auto p : cfg) { MockRepository mocks; - auto mm = mocks.Mock(); - setup_intrinsics(mocks, mm); + setup_mm(mocks); p.setup(); @@ -140,23 +58,23 @@ setup_check_guest_cr0_for_unsupported_bits_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); guest_cr0::set(0UL); }; @@ -252,14 +170,14 @@ static void setup_check_guest_verify_ia_32e_mode_disabled_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); guest_cr4::pcid_enable_bit::enable(); }; @@ -287,14 +205,14 @@ static void setup_check_guest_load_debug_controls_verify_dr7_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::load_debug_controls::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_debug_controls::mask); vm_entry_controls::load_debug_controls::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::load_debug_controls::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_debug_controls::mask); vm_entry_controls::load_debug_controls::enable(); guest_dr7::set(0x100000000U); }; @@ -337,14 +255,14 @@ setup_check_guest_verify_load_ia32_perf_global_ctrl_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::load_ia32_pat::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_pat::mask); vm_entry_controls::load_ia32_pat::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::load_ia32_pat::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_pat::mask); vm_entry_controls::load_ia32_pat::enable(); guest_ia32_pat::set(2ULL); }; @@ -411,14 +329,14 @@ static void setup_check_guest_verify_load_ia32_efer_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::load_ia32_efer::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_efer::mask); vm_entry_controls::load_ia32_efer::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::load_ia32_efer::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_efer::mask); vm_entry_controls::load_ia32_efer::enable(); guest_ia32_efer::reserved::set(0xEUL); }; @@ -426,7 +344,7 @@ setup_check_guest_verify_load_ia32_efer_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::load_ia32_bndcfgs::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_bndcfgs::mask); vm_entry_controls::load_ia32_bndcfgs::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::load_ia32_bndcfgs::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::load_ia32_bndcfgs::mask); vm_entry_controls::load_ia32_bndcfgs::enable(); guest_ia32_bndcfgs::reserved::set(0xCUL); }; @@ -534,8 +452,8 @@ setup_check_guest_ss_and_cs_rpl_are_the_same_paths(std::vector &cfg) path.setup = [&] { disable_v8086(); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::unrestricted_guest::enable(); }; @@ -1474,8 +1392,8 @@ setup_check_guest_ds_dpl_paths(std::vector &cfg) cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); make_unusable(guest_ds_access_rights::addr); }; @@ -1511,8 +1429,8 @@ setup_check_guest_es_dpl_paths(std::vector &cfg) path.setup = [&] { disable_v8086(); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::unrestricted_guest::enable(); }; @@ -1520,8 +1438,8 @@ setup_check_guest_es_dpl_paths(std::vector &cfg) cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); make_unusable(guest_es_access_rights::addr); }; @@ -1557,8 +1475,8 @@ setup_check_guest_fs_dpl_paths(std::vector &cfg) path.setup = [&] { disable_v8086(); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::unrestricted_guest::enable(); }; @@ -1566,8 +1484,8 @@ setup_check_guest_fs_dpl_paths(std::vector &cfg) cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); make_unusable(guest_fs_access_rights::addr); }; @@ -1603,8 +1521,8 @@ setup_check_guest_gs_dpl_paths(std::vector &cfg) path.setup = [&] { disable_v8086(); - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow1(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow1(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); primary_processor_based_vm_execution_controls::activate_secondary_controls::enable(); secondary_processor_based_vm_execution_controls::unrestricted_guest::enable(); }; @@ -1612,8 +1530,8 @@ setup_check_guest_gs_dpl_paths(std::vector &cfg) cfg.push_back(path); path.setup = [&] { - proc_ctl_allow1(ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); - proc_ctl2_allow0(ia32_vmx_procbased_ctls2::unrestricted_guest::mask); + proc_ctl_allow1(intel_x64::msrs::ia32_vmx_true_procbased_ctls::activate_secondary_controls::mask); + proc_ctl2_allow0(intel_x64::msrs::ia32_vmx_procbased_ctls2::unrestricted_guest::mask); secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); make_unusable(guest_gs_access_rights::addr); }; @@ -1936,14 +1854,14 @@ setup_check_guest_cs_db_must_be_0_if_l_equals_1_paths(std::vector { path.setup = [&] { guest_tr_access_rights::set(3U); - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); }; path.throws_exception = true; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); }; path.throws_exception = false; @@ -2593,7 +2511,7 @@ static void setup_check_guest_rip_upper_bits_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); guest_cs_access_rights::l::set(true); }; @@ -2601,7 +2519,7 @@ setup_check_guest_rip_upper_bits_paths(std::vector &cf cfg.push_back(path); path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); guest_rip::set(0xf00000000U); }; @@ -2617,14 +2535,14 @@ static void setup_check_guest_rip_valid_addr_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); guest_cs_access_rights::l::set(false); }; @@ -2663,7 +2581,7 @@ static void setup_check_guest_rflags_vm_bit_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::disable(); guest_cr0::protection_enable::enable(); }; @@ -2887,14 +2805,14 @@ static void setup_check_guest_valid_activity_state_and_smm_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::entry_to_smm::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::entry_to_smm::mask); vm_entry_controls::entry_to_smm::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::entry_to_smm::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::entry_to_smm::mask); vm_entry_controls::entry_to_smm::enable(); guest_activity_state::set(vmcs::guest_activity_state::shutdown); }; @@ -3027,14 +2945,14 @@ static void setup_check_guest_interruptibility_entry_to_smm_paths(std::vector &cfg) { path.setup = [&] { - entry_ctl_allow0(ia32_vmx_true_entry_ctls::entry_to_smm::mask); + entry_ctl_allow0(intel_x64::msrs::ia32_vmx_true_entry_ctls::entry_to_smm::mask); vm_entry_controls::entry_to_smm::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - entry_ctl_allow1(ia32_vmx_true_entry_ctls::entry_to_smm::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::entry_to_smm::mask); vm_entry_controls::entry_to_smm::enable(); guest_interruptibility_state::blocking_by_smi::set(false); }; @@ -3082,14 +3000,14 @@ setup_check_guest_interruptibility_state_virtual_nmi_paths(std::vector -#include -#include -#include -#include -#include +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -TEST_CASE("test name goes here") -{ - CHECK(true); -} - -using namespace intel_x64; -using namespace msrs; -using namespace vmcs; - -std::map g_msrs; -std::map g_vmcs_fields; -std::map g_eax_cpuid; - -uint32_t -test_cpuid_eax(uint32_t val) noexcept -{ return g_eax_cpuid[val]; } - -uint64_t -test_read_msr(uint32_t addr) noexcept -{ return g_msrs[addr]; } - -static bool -test_vmread(uint64_t field, uint64_t *val) noexcept -{ - *val = g_vmcs_fields[field]; - return true; -} - -static bool -test_vmwrite(uint64_t field, uint64_t val) noexcept -{ - g_vmcs_fields[field] = val; - return true; -} - -static void -setup_intrinsics(MockRepository &mocks) -{ - mocks.OnCallFunc(_cpuid_eax).Do(test_cpuid_eax); - mocks.OnCallFunc(_read_msr).Do(test_read_msr); - mocks.OnCallFunc(_vmread).Do(test_vmread); - mocks.OnCallFunc(_vmwrite).Do(test_vmwrite); -} - -static struct control_flow_path path; - void test_vmcs_check(std::vector cfg, void(*func)()) { for (auto p : cfg) { - MockRepository mocks; - setup_intrinsics(mocks); - p.setup(); if (p.throws_exception) { @@ -93,16 +39,16 @@ setup_check_host_cr0_for_unsupported_bits_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::load_ia32_perf_global_ctrl::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_perf_global_ctrl::mask); vm_exit_controls::load_ia32_perf_global_ctrl::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::load_ia32_perf_global_ctrl::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_perf_global_ctrl::mask); vm_exit_controls::load_ia32_perf_global_ctrl::enable(); host_ia32_perf_global_ctrl::set(0xcU); }; @@ -188,14 +134,14 @@ static void setup_check_host_verify_load_ia32_pat_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::load_ia32_pat::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_pat::mask); vm_exit_controls::load_ia32_pat::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::load_ia32_pat::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_pat::mask); vm_exit_controls::load_ia32_pat::enable(); host_ia32_pat::pa0::memory_type::set(2ULL); }; @@ -260,14 +206,14 @@ static void setup_check_host_verify_load_ia32_efer_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::load_ia32_efer::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_efer::mask); vm_exit_controls::load_ia32_efer::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::load_ia32_efer::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::load_ia32_efer::mask); vm_exit_controls::load_ia32_efer::enable(); host_ia32_efer::reserved::set(0xEUL); }; @@ -275,7 +221,7 @@ setup_check_host_verify_load_ia32_efer_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::disable(); host_ss_selector::set(0U); }; @@ -562,13 +508,13 @@ setup_check_host_tr_canonical_base_address_paths(std::vector &cfg) { - path.setup = [&] { g_msrs[ia32_efer::addr] = msrs::ia32_efer::lma::mask; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_efer::addr] = intel_x64::msrs::ia32_efer::lma::mask; }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - g_msrs[ia32_efer::addr] = 0; - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + g_msrs[intel_x64::msrs::ia32_efer::addr] = 0; + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_entry_controls::ia_32e_mode_guest::enable(); }; path.throws_exception = true; @@ -582,7 +528,7 @@ setup_check_host_if_outside_ia32e_mode_paths(std::vector &cfg) { - path.setup = [&] { g_msrs[ia32_efer::addr] = 0; }; + path.setup = [&] { g_msrs[intel_x64::msrs::ia32_efer::addr] = 0; }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - g_msrs[ia32_efer::addr] = msrs::ia32_efer::lma::mask; - exit_ctl_allow0(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + g_msrs[intel_x64::msrs::ia32_efer::addr] = intel_x64::msrs::ia32_efer::lma::mask; + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::disable(); }; path.throws_exception = true; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::enable(); }; path.throws_exception = false; @@ -617,15 +563,15 @@ static void setup_check_host_address_space_disabled_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::enable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::host_address_space_size::mask); - entry_ctl_allow1(ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); + entry_ctl_allow1(intel_x64::msrs::ia32_vmx_true_entry_ctls::ia_32e_mode_guest::mask); vm_exit_controls::host_address_space_size::disable(); vm_entry_controls::ia_32e_mode_guest::enable(); }; @@ -633,7 +579,7 @@ setup_check_host_address_space_disabled_paths(std::vector &cfg) { path.setup = [&] { - exit_ctl_allow0(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow0(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::disable(); }; path.throws_exception = false; cfg.push_back(path); path.setup = [&] { - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); vm_exit_controls::host_address_space_size::enable(); host_cr4::physical_address_extensions::disable(); }; diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_launch_mock.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_launch_mock.cpp deleted file mode 100644 index 1eff4af12..000000000 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_launch_mock.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// Bareflank Hypervisor -// Copyright (C) 2015 Assured Information Security, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#include -#include - -TEST_CASE("") -{ - CHECK_NOTHROW(vmcs_launch(nullptr)); -} diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_promote_mock.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_promote_mock.cpp deleted file mode 100644 index f62489946..000000000 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_promote_mock.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// Bareflank Hypervisor -// Copyright (C) 2015 Assured Information Security, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#include -#include - -TEST_CASE("") -{ - CHECK_NOTHROW(vmcs_promote(0, 0)); -} diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_resume_mock.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_resume_mock.cpp deleted file mode 100644 index 395153d56..000000000 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_resume_mock.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// Bareflank Hypervisor -// Copyright (C) 2015 Assured Information Security, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#include -#include - -TEST_CASE("") -{ - CHECK_NOTHROW(vmcs_resume(nullptr)); -} diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state.cpp index 72fe56b5d..6aa75a669 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state.cpp @@ -16,12 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include - -#include -#include - -using namespace x64; +#include TEST_CASE("vmcs: state") { diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_hvm.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_hvm.cpp index 372f291c7..4366d4ab2 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_hvm.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_hvm.cpp @@ -16,240 +16,15 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include - -#include -#include +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -using namespace x64; - -uint16_t test_es; -uint16_t test_cs; -uint16_t test_ss; -uint16_t test_ds; -uint16_t test_fs; -uint16_t test_gs; -uint16_t test_ldtr; -uint16_t test_tr; - -uint64_t test_cr0; -uint64_t test_cr3; -uint64_t test_cr4; -uint64_t test_dr7; -uint64_t test_rflags; - -gdt_reg_x64_t test_gdtr{}; -idt_reg_x64_t test_idtr{}; - -std::vector test_gdt = { - 0x0, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF -}; - -std::vector test_idt{512}; - -std::map g_msrs; -std::map g_eax_cpuid; - -static uint16_t -test_read_es() noexcept -{ return test_es; } - -static uint16_t -test_read_cs() noexcept -{ return test_cs; } - -static uint16_t -test_read_ss() noexcept -{ return test_ss; } - -static uint16_t -test_read_ds() noexcept -{ return test_ds; } - -static uint16_t -test_read_fs() noexcept -{ return test_fs; } - -static uint16_t -test_read_gs() noexcept -{ return test_gs; } - -static uint16_t -test_read_tr() noexcept -{ return test_tr; } - -static uint16_t -test_read_ldtr() noexcept -{ return test_ldtr; } - -static void -test_write_es(uint16_t val) noexcept -{ test_es = val; } - -static void -test_write_cs(uint16_t val) noexcept -{ test_cs = val; } - -static void -test_write_ss(uint16_t val) noexcept -{ test_ss = val; } - -static void -test_write_ds(uint16_t val) noexcept -{ test_ds = val; } - -static void -test_write_fs(uint16_t val) noexcept -{ test_fs = val; } - -static void -test_write_gs(uint16_t val) noexcept -{ test_gs = val; } - -static void -test_write_tr(uint16_t val) noexcept -{ test_tr = val; } - -static void -test_write_ldtr(uint16_t val) noexcept -{ test_ldtr = val; } - -static uint64_t -test_read_cr0() noexcept -{ return test_cr0; } - -static uint64_t -test_read_cr3() noexcept -{ return test_cr3; } - -static uint64_t -test_read_cr4() noexcept -{ return test_cr4; } - -static void -test_write_cr0(uint64_t val) noexcept -{ test_cr0 = val; } - -static void -test_write_cr3(uint64_t val) noexcept -{ test_cr3 = val; } - -static void -test_write_cr4(uint64_t val) noexcept -{ test_cr4 = val; } - -static uint64_t -test_read_dr7() noexcept -{ return test_dr7; } - -static void -test_write_dr7(uint64_t val) noexcept -{ test_dr7 = val; } - -static uint64_t -test_read_rflags() noexcept -{ return test_rflags; } - -static void -test_write_rflags(uint64_t val) noexcept -{ test_rflags = val; } - -static void -test_read_gdt(gdt_reg_x64_t *gdt_reg) noexcept -{ *gdt_reg = test_gdtr; } - -static void -test_read_idt(idt_reg_x64_t *idt_reg) noexcept -{ *idt_reg = test_idtr; } - -static uint64_t -test_read_msr(uint32_t addr) noexcept -{ return g_msrs[addr]; } - -static void -test_write_msr(uint32_t addr, uint64_t val) noexcept -{ g_msrs[addr] = val; } - -static uint32_t -test_cpuid_eax(uint32_t val) noexcept -{ return g_eax_cpuid[val]; } - -void -setup_gdt() -{ - auto limit = test_gdt.size() * sizeof(gdt_x64::segment_descriptor_type); - - test_gdtr.base = &test_gdt.at(0); - test_gdtr.limit = gsl::narrow_cast(limit); -} - -void -setup_idt() -{ - auto limit = test_idt.size() * sizeof(idt_x64::interrupt_descriptor_type); - - test_idtr.base = &test_idt.at(0); - test_idtr.limit = gsl::narrow_cast(limit); -} - -static void -setup_intrinsics(MockRepository &mocks) -{ - mocks.OnCallFunc(_read_es).Do(test_read_es); - mocks.OnCallFunc(_read_cs).Do(test_read_cs); - mocks.OnCallFunc(_read_ss).Do(test_read_ss); - mocks.OnCallFunc(_read_ds).Do(test_read_ds); - mocks.OnCallFunc(_read_fs).Do(test_read_fs); - mocks.OnCallFunc(_read_gs).Do(test_read_gs); - mocks.OnCallFunc(_read_tr).Do(test_read_tr); - mocks.OnCallFunc(_read_ldtr).Do(test_read_ldtr); - - mocks.OnCallFunc(_write_es).Do(test_write_es); - mocks.OnCallFunc(_write_cs).Do(test_write_cs); - mocks.OnCallFunc(_write_ss).Do(test_write_ss); - mocks.OnCallFunc(_write_ds).Do(test_write_ds); - mocks.OnCallFunc(_write_fs).Do(test_write_fs); - mocks.OnCallFunc(_write_gs).Do(test_write_gs); - mocks.OnCallFunc(_write_tr).Do(test_write_tr); - mocks.OnCallFunc(_write_ldtr).Do(test_write_ldtr); - - mocks.OnCallFunc(_read_cr0).Do(test_read_cr0); - mocks.OnCallFunc(_read_cr3).Do(test_read_cr3); - mocks.OnCallFunc(_read_cr4).Do(test_read_cr4); - mocks.OnCallFunc(_write_cr0).Do(test_write_cr0); - mocks.OnCallFunc(_write_cr3).Do(test_write_cr3); - mocks.OnCallFunc(_write_cr4).Do(test_write_cr4); - - mocks.OnCallFunc(_read_dr7).Do(test_read_dr7); - mocks.OnCallFunc(_write_dr7).Do(test_write_dr7); - - mocks.OnCallFunc(_read_rflags).Do(test_read_rflags); - mocks.OnCallFunc(_write_rflags).Do(test_write_rflags); - - mocks.OnCallFunc(_read_gdt).Do(test_read_gdt); - mocks.OnCallFunc(_read_idt).Do(test_read_idt); - - mocks.OnCallFunc(_read_msr).Do(test_read_msr); - mocks.OnCallFunc(_write_msr).Do(test_write_msr); - - mocks.OnCallFunc(_cpuid_eax).Do(test_cpuid_eax); - - setup_gdt(); - setup_idt(); -} - TEST_CASE("vmcs: host_vm_state") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); CHECK_NOTHROW(vmcs_intel_x64_host_vm_state{}); } @@ -257,7 +32,8 @@ TEST_CASE("vmcs: host_vm_state") TEST_CASE("vmcs: host_vm_state_segment_registers") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::set(1U); segment_register::cs::set(1U); @@ -283,7 +59,8 @@ TEST_CASE("vmcs: host_vm_state_segment_registers") TEST_CASE("vmcs: host_vm_state_control_registers") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); intel_x64::cr0::set(1U); intel_x64::cr3::set(2U); @@ -299,7 +76,8 @@ TEST_CASE("vmcs: host_vm_state_control_registers") TEST_CASE("vmcs: host_vm_state_debug_registers") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); dr7::set(42U); vmcs_intel_x64_host_vm_state state{}; @@ -310,7 +88,8 @@ TEST_CASE("vmcs: host_vm_state_debug_registers") TEST_CASE("vmcs: host_vm_state_rflags") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); rflags::set(42U); vmcs_intel_x64_host_vm_state state{}; @@ -321,44 +100,49 @@ TEST_CASE("vmcs: host_vm_state_rflags") TEST_CASE("vmcs: host_vm_state_gdt_base") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); vmcs_intel_x64_host_vm_state state{}; - CHECK(state.gdt_base() == bfrcast(gdt_x64::integer_pointer, test_gdtr.base)); + CHECK(state.gdt_base() == bfscast(gdt_x64::integer_pointer, g_gdtr.base)); } TEST_CASE("vmcs: host_vm_state_idt_base") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); vmcs_intel_x64_host_vm_state state{}; - CHECK(state.idt_base() == bfrcast(gdt_x64::integer_pointer, test_idtr.base)); + CHECK(state.idt_base() == bfscast(gdt_x64::integer_pointer, g_idtr.base)); } TEST_CASE("vmcs: host_vm_state_gdt_limit") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); vmcs_intel_x64_host_vm_state state{}; - CHECK(state.gdt_limit() == test_gdtr.limit); + CHECK(state.gdt_limit() == g_gdtr.limit); } TEST_CASE("vmcs: host_vm_state_idt_limit") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); vmcs_intel_x64_host_vm_state state{}; - CHECK(state.idt_limit() == test_idtr.limit); + CHECK(state.idt_limit() == g_idtr.limit); } TEST_CASE("vmcs: host_vm_state_es_limit") { SECTION("es_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -368,7 +152,8 @@ TEST_CASE("vmcs: host_vm_state_es_limit") SECTION("es_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -381,7 +166,8 @@ TEST_CASE("vmcs: host_vm_state_cs_limit") { SECTION("cs_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -391,7 +177,8 @@ TEST_CASE("vmcs: host_vm_state_cs_limit") SECTION("cs_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -404,7 +191,8 @@ TEST_CASE("vmcs: host_vm_state_ss_limit") { SECTION("ss_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -414,7 +202,8 @@ TEST_CASE("vmcs: host_vm_state_ss_limit") SECTION("ss_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -427,7 +216,8 @@ TEST_CASE("vmcs: host_vm_state_ds_limit") { SECTION("ds_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -437,7 +227,8 @@ TEST_CASE("vmcs: host_vm_state_ds_limit") SECTION("ds_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -450,7 +241,8 @@ TEST_CASE("vmcs: host_vm_state_fs_limit") { SECTION("fs_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -460,7 +252,8 @@ TEST_CASE("vmcs: host_vm_state_fs_limit") SECTION("fs_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -473,7 +266,8 @@ TEST_CASE("vmcs: host_vm_state_gs_limit") { SECTION("gs_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -483,7 +277,8 @@ TEST_CASE("vmcs: host_vm_state_gs_limit") SECTION("gs_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -496,7 +291,8 @@ TEST_CASE("vmcs: host_vm_state_tr_limit") { SECTION("tr_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -506,7 +302,8 @@ TEST_CASE("vmcs: host_vm_state_tr_limit") SECTION("tr_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -519,7 +316,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_limit") { SECTION("ldtr_limit == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -529,7 +327,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_limit") SECTION("ldtr_limit == 0xFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(1U); vmcs_intel_x64_host_vm_state state{}; @@ -542,7 +341,8 @@ TEST_CASE("vmcs: host_vm_state_es_access_rights") { SECTION("es_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -552,7 +352,8 @@ TEST_CASE("vmcs: host_vm_state_es_access_rights") SECTION("es_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -565,7 +366,8 @@ TEST_CASE("vmcs: host_vm_state_cs_access_rights") { SECTION("cs_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -575,7 +377,8 @@ TEST_CASE("vmcs: host_vm_state_cs_access_rights") SECTION("cs_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -588,7 +391,8 @@ TEST_CASE("vmcs: host_vm_state_ss_access_rights") { SECTION("ss_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -598,7 +402,8 @@ TEST_CASE("vmcs: host_vm_state_ss_access_rights") SECTION("ss_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -611,7 +416,8 @@ TEST_CASE("vmcs: host_vm_state_ds_access_rights") { SECTION("ds_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -621,7 +427,8 @@ TEST_CASE("vmcs: host_vm_state_ds_access_rights") SECTION("ds_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -634,7 +441,8 @@ TEST_CASE("vmcs: host_vm_state_fs_access_rights") { SECTION("fs_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -644,7 +452,8 @@ TEST_CASE("vmcs: host_vm_state_fs_access_rights") SECTION("fs_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -657,7 +466,8 @@ TEST_CASE("vmcs: host_vm_state_gs_access_rights") { SECTION("gs_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -667,7 +477,8 @@ TEST_CASE("vmcs: host_vm_state_gs_access_rights") SECTION("gs_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -680,7 +491,8 @@ TEST_CASE("vmcs: host_vm_state_tr_access_rights") { SECTION("tr_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -690,7 +502,8 @@ TEST_CASE("vmcs: host_vm_state_tr_access_rights") SECTION("tr_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -703,7 +516,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_access_rights") { SECTION("ldtr_access_rights unusable") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -713,7 +527,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_access_rights") SECTION("ldtr_access_rights == 0x70") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(2U); vmcs_intel_x64_host_vm_state state{}; @@ -726,7 +541,8 @@ TEST_CASE("vmcs: host_vm_state_es_base") { SECTION("es_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -736,7 +552,8 @@ TEST_CASE("vmcs: host_vm_state_es_base") SECTION("es_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::es::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -749,7 +566,8 @@ TEST_CASE("vmcs: host_vm_state_cs_base") { SECTION("cs_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -759,7 +577,8 @@ TEST_CASE("vmcs: host_vm_state_cs_base") SECTION("cs_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::cs::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -772,7 +591,8 @@ TEST_CASE("vmcs: host_vm_state_ss_base") { SECTION("ss_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -782,7 +602,8 @@ TEST_CASE("vmcs: host_vm_state_ss_base") SECTION("ss_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ss::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -795,7 +616,8 @@ TEST_CASE("vmcs: host_vm_state_ds_base") { SECTION("ds_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -805,7 +627,8 @@ TEST_CASE("vmcs: host_vm_state_ds_base") SECTION("ds_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ds::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -818,7 +641,8 @@ TEST_CASE("vmcs: host_vm_state_fs_base") { SECTION("fs_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -828,7 +652,8 @@ TEST_CASE("vmcs: host_vm_state_fs_base") SECTION("fs_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::fs::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -841,7 +666,8 @@ TEST_CASE("vmcs: host_vm_state_gs_base") { SECTION("gs_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -851,7 +677,8 @@ TEST_CASE("vmcs: host_vm_state_gs_base") SECTION("gs_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::gs::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -864,7 +691,8 @@ TEST_CASE("vmcs: host_vm_state_tr_base") { SECTION("tr_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -874,7 +702,8 @@ TEST_CASE("vmcs: host_vm_state_tr_base") SECTION("tr_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::tr::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -887,7 +716,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_base") { SECTION("ldtr_base == 0") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(0U); vmcs_intel_x64_host_vm_state state{}; @@ -897,7 +727,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_base") SECTION("ldtr_base == 0xFFFFFFFF") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); segment_register::ldtr::index::set(3U); vmcs_intel_x64_host_vm_state state{}; @@ -909,7 +740,8 @@ TEST_CASE("vmcs: host_vm_state_ldtr_base") TEST_CASE("vmcs: host_vm_state_ia32_msrs_no_perf") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); intel_x64::msrs::ia32_debugctl::set(42U); x64::msrs::ia32_pat::set(42U); @@ -937,7 +769,8 @@ TEST_CASE("vmcs: host_vm_state_ia32_msrs_no_perf") TEST_CASE("vmcs: host_vm_state_ia32_msrs_perf") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); intel_x64::msrs::ia32_debugctl::set(42U); x64::msrs::ia32_pat::set(42U); @@ -966,7 +799,8 @@ TEST_CASE("vmcs: host_vm_state_ia32_msrs_perf") TEST_CASE("vmcs: host_vm_state_dump") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); vmcs_intel_x64_host_vm_state state{}; CHECK_NOTHROW(state.dump()); diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_vmm.cpp b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_vmm.cpp index 8f88cf71d..9b233aec5 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_vmm.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmcs/test_vmcs_state_vmm.cpp @@ -16,55 +16,17 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include - -#include -#include - -#include -#include +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -using namespace x64; - -static uint32_t -test_cpuid_ecx(uint32_t addr) noexcept -{ - bfignored(addr); - return 0xFFFFFFFFU; -} - -static uint32_t -test_cpuid_subebx(uint32_t addr, uint32_t leaf) -{ - bfignored(addr); - bfignored(leaf); - return 0xFFFFFFFFU; -} - -static void -setup_mm(MockRepository &mocks) -{ - auto pt = mocks.Mock(); - - mocks.OnCallFunc(root_pt).Return(pt); - mocks.OnCall(pt, root_page_table_x64::cr3).Return(42U); -} - -static void -setup_intrinsics(MockRepository &mocks) -{ - mocks.OnCallFunc(_cpuid_ecx).Do(test_cpuid_ecx); - mocks.OnCallFunc(_cpuid_subebx).Do(test_cpuid_subebx); -} - TEST_CASE("vmcs: vmm_state") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); + + g_ecx_cpuid[intel_x64::cpuid::feature_information::addr] = 0xFFFFFFFF; + g_ebx_cpuid[intel_x64::cpuid::extended_feature_flags::addr] = 0xFFFFFFFF; vmcs_intel_x64_vmm_state state{}; } @@ -73,7 +35,6 @@ TEST_CASE("vmcs: state_segment_registers") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -88,7 +49,6 @@ TEST_CASE("vmcs: state_control_registers") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -101,7 +61,6 @@ TEST_CASE("vmcs: state_debug_registers") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK(state.dr7() == 0U); @@ -111,7 +70,6 @@ TEST_CASE("vmcs: state_rflags") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK(state.rflags() == 0U); @@ -121,7 +79,6 @@ TEST_CASE("vmcs: state_gdt_base") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK(state.gdt_base() != 0U); @@ -131,7 +88,6 @@ TEST_CASE("vmcs: state_idt_base") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK(state.idt_base() != 0U); @@ -141,7 +97,6 @@ TEST_CASE("vmcs: state_gdt_limit") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -152,7 +107,6 @@ TEST_CASE("vmcs: state_idt_limit") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK(state.idt_limit() == 2047U); @@ -162,7 +116,6 @@ TEST_CASE("vmcs: state_segment_registers_limit") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -177,7 +130,6 @@ TEST_CASE("vmcs: state_segment_registers_access_rights") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -192,7 +144,6 @@ TEST_CASE("vmcs: state_segment_register_base") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -207,7 +158,6 @@ TEST_CASE("vmcs: state_msrs") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; @@ -219,7 +169,6 @@ TEST_CASE("vmcs: state_dump") { MockRepository mocks; setup_mm(mocks); - setup_intrinsics(mocks); vmcs_intel_x64_vmm_state state{}; CHECK_NOTHROW(state.dump()); diff --git a/bfvmm/tests/hve/arch/intel_x64/vmcs_utils.h b/bfvmm/tests/hve/arch/intel_x64/vmcs_utils.h deleted file mode 100644 index fed2dff76..000000000 --- a/bfvmm/tests/hve/arch/intel_x64/vmcs_utils.h +++ /dev/null @@ -1,493 +0,0 @@ -// -// Bareflank Hypervisor -// Copyright (C) 2015 Assured Information Security, Inc. -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -#ifndef TEST_VMCS_UTILS_H -#define TEST_VMCS_UTILS_H - -#include -#include -#include - -#include - -using namespace intel_x64; -using namespace vmcs; -using namespace msrs; - -struct control_flow_path { - std::function setup{}; - bool throws_exception{false}; -}; - -struct cpuid_regs { - uint32_t eax; - uint32_t ebx; - uint32_t ecx; - uint32_t edx; -}; - -extern struct cpuid_regs g_cpuid_regs; - -extern std::map g_msrs; -extern std::map g_vmcs_fields; -extern std::map g_eax_cpuid; -extern std::map g_mock_mem; - -extern bool g_virt_to_phys_return_nullptr; -extern bool g_phys_to_virt_return_nullptr; -extern bool g_vmclear_fails; -extern bool g_vmload_fails; -extern bool g_vmlaunch_fails; - -extern size_t g_new_throws_bad_alloc; - -extern uint64_t g_test_addr; -extern uint64_t g_virt_apic_addr; -extern uint8_t g_virt_apic_mem[0x81]; - -extern uint64_t g_vmcs_link_addr; -extern uint32_t g_vmcs_link_mem[1]; - -extern uint64_t g_pdpt_addr; -extern uint64_t g_pdpt_mem[4]; - -inline uintptr_t -test_virtptr_to_physint(void *ptr) -{ - (void) ptr; - - if (g_virt_to_phys_return_nullptr) { - throw gsl::fail_fast(""); - } - - return 0x0000000ABCDEF0000; -} - -inline void * -test_physint_to_virtptr(uintptr_t phys) -{ - (void) phys; - - if (g_phys_to_virt_return_nullptr) { - return nullptr; - } - - return static_cast(g_mock_mem[g_test_addr]); -} - -inline void -proc_ctl_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_procbased_ctls::addr] |= mask << 32; } - -inline void -proc_ctl_allow0(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_procbased_ctls::addr] &= ~mask; } - -inline void -proc_ctl_disallow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_procbased_ctls::addr] &= ~(mask << 32); } - -inline void -proc_ctl2_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_procbased_ctls2::addr] |= mask << 32; } - -inline void -proc_ctl2_allow0(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_procbased_ctls2::addr] &= ~mask; } - -inline void -proc_ctl2_disallow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_procbased_ctls2::addr] &= ~(mask << 32); } - -inline void -pin_ctl_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_pinbased_ctls::addr] |= mask << 32; } - -inline void -pin_ctl_allow0(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_pinbased_ctls::addr] &= ~mask; } - -inline void -exit_ctl_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_exit_ctls::addr] |= mask << 32; } - -inline void -exit_ctl_allow0(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_exit_ctls::addr] &= ~mask; } - -inline void -entry_ctl_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_entry_ctls::addr] |= mask << 32; } - -inline void -entry_ctl_allow0(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_true_entry_ctls::addr] &= ~mask; } - -inline void -vmfunc_ctl_allow1(uint64_t mask) -{ g_msrs[msrs::ia32_vmx_vmfunc::addr] |= mask; } - -inline void -setup_check_control_vm_execution_control_fields_all_paths(std::vector - &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL; - g_msrs[ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL; - g_msrs[ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL; - cr3_target_count::set(3UL); - primary_processor_based_vm_execution_controls::use_io_bitmaps::disable(); - primary_processor_based_vm_execution_controls::use_msr_bitmap::disable(); - primary_processor_based_vm_execution_controls::use_tpr_shadow::disable(); - secondary_processor_based_vm_execution_controls::virtualize_x2apic_mode::disable(); - secondary_processor_based_vm_execution_controls::apic_register_virtualization::disable(); - secondary_processor_based_vm_execution_controls::virtual_interrupt_delivery::disable(); - pin_based_vm_execution_controls::nmi_exiting::enable(); - pin_based_vm_execution_controls::virtual_nmis::enable(); - secondary_processor_based_vm_execution_controls::virtualize_apic_accesses::disable(); - pin_based_vm_execution_controls::process_posted_interrupts::disable(); - secondary_processor_based_vm_execution_controls::enable_vpid::disable(); - secondary_processor_based_vm_execution_controls::enable_ept::disable(); - secondary_processor_based_vm_execution_controls::enable_pml::disable(); - secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); - secondary_processor_based_vm_execution_controls::enable_vm_functions::disable(); - secondary_processor_based_vm_execution_controls::vmcs_shadowing::disable(); - secondary_processor_based_vm_execution_controls::ept_violation_ve::disable(); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_control_vm_exit_control_fields_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[ia32_vmx_true_exit_ctls::addr] = 0xffffffff00000000UL; - pin_ctl_allow1(ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); - pin_based_vm_execution_controls::activate_vmx_preemption_timer::enable(); - vm_exit_msr_store_count::set(0UL); - vm_exit_msr_load_count::set(0UL); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_control_vm_entry_control_fields_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL; - vm_entry_interruption_information::valid_bit::disable(); - vm_entry_msr_load_count::set(0UL); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_control_vmx_controls_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - std::vector sub_cfg; - - setup_check_control_vm_execution_control_fields_all_paths(sub_cfg); - setup_check_control_vm_exit_control_fields_all_paths(sub_cfg); - setup_check_control_vm_entry_control_fields_all_paths(sub_cfg); - - path.setup = [sub_cfg] { - for (const auto &sub_path : sub_cfg) - { sub_path.setup(); } - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_control_registers_debug_registers_and_msrs_all_paths( - std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; - g_msrs[msrs::ia32_vmx_cr0_fixed0::addr] = 0ULL; - g_msrs[msrs::ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; - guest_cr0::paging::disable(); - g_msrs[msrs::ia32_vmx_cr4_fixed0::addr] = 0ULL; - g_msrs[msrs::ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; - vm_entry_controls::load_debug_controls::disable(); - vm_entry_controls::ia_32e_mode_guest::disable(); - guest_cr4::pcid_enable_bit::disable(); - g_eax_cpuid[x64::cpuid::addr_size::addr] = 48U; - guest_cr3::set(0x1000UL); - guest_ia32_sysenter_esp::set(0x1000UL); - guest_ia32_sysenter_eip::set(0x1000UL); - vm_entry_controls::load_ia32_perf_global_ctrl::disable(); - vm_entry_controls::load_ia32_pat::disable(); - vm_entry_controls::load_ia32_efer::disable(); - vm_entry_controls::load_ia32_bndcfgs::disable(); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_segment_registers_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - guest_tr_selector::ti::disable(); - guest_ldtr_access_rights::unusable::enable(); - guest_rflags::virtual_8086_mode::enable(); - guest_cs_selector::set(0x1UL); - guest_cs_base::set(0x10UL); - guest_ss_selector::set(0x1UL); - guest_ss_base::set(0x10UL); - guest_ds_selector::set(0x1UL); - guest_ds_base::set(0x10UL); - guest_es_selector::set(0x1UL); - guest_es_base::set(0x10UL); - guest_fs_selector::set(0x1UL); - guest_fs_base::set(0x10UL); - guest_gs_selector::set(0x1UL); - guest_gs_base::set(0x10UL); - guest_tr_base::set(0x10UL); - guest_cs_limit::set(0xFFFFUL); - guest_ss_limit::set(0xFFFFUL); - guest_ds_limit::set(0xFFFFUL); - guest_es_limit::set(0xFFFFUL); - guest_gs_limit::set(0xFFFFUL); - guest_fs_limit::set(0xFFFFUL); - guest_cs_access_rights::set(0xF3UL); - guest_ss_access_rights::set(0xF3UL); - guest_ds_access_rights::set(0xF3UL); - guest_es_access_rights::set(0xF3UL); - guest_fs_access_rights::set(0xF3UL); - guest_gs_access_rights::set(0xF3UL); - guest_tr_access_rights::type::set(gsl::narrow_cast(x64::access_rights::type::read_execute_accessed)); - //guest_tr_access_rights::s::enable(); - guest_tr_access_rights::present::enable(); - guest_tr_limit::set(0x1UL); - guest_tr_access_rights::granularity::disable(); - guest_tr_access_rights::unusable::disable(); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_descriptor_table_registers_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - guest_gdtr_base::set(0x1000UL); - guest_idtr_base::set(0x1000UL); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_rip_and_rflags_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; - vm_entry_controls::ia_32e_mode_guest::disable(); - guest_rip::set(0x1000UL); - guest_rflags::reserved::set(0UL); - guest_rflags::always_enabled::set(0x2UL); - guest_cr0::protection_enable::enable(); - vm_entry_interruption_information::valid_bit::disable(); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_non_register_state_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; - guest_activity_state::set(guest_activity_state::active); - guest_interruptibility_state::blocking_by_sti::disable(); - guest_interruptibility_state::blocking_by_mov_ss::disable(); - vm_entry_interruption_information::valid_bit::disable(); - vm_entry_controls::entry_to_smm::disable(); - guest_interruptibility_state::reserved::set(0UL); - guest_interruptibility_state::enclave_interruption::disable(); - guest_pending_debug_exceptions::reserved::set(0UL); - guest_pending_debug_exceptions::rtm::disable(); - vmcs_link_pointer::set(0xFFFFFFFFFFFFFFFFUL); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_pdptes_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - path.setup = [&] { guest_cr0::paging::disable(); }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_guest_state_all_paths(std::vector &cfg) -{ - std::vector sub_cfg; - struct control_flow_path path; - - setup_check_guest_control_registers_debug_registers_and_msrs_all_paths(sub_cfg); - setup_check_guest_segment_registers_all_paths(sub_cfg); - setup_check_guest_descriptor_table_registers_all_paths(sub_cfg); - setup_check_guest_rip_and_rflags_all_paths(sub_cfg); - setup_check_guest_non_register_state_all_paths(sub_cfg); - setup_check_guest_pdptes_all_paths(sub_cfg); - - path.setup = [sub_cfg] { - for (const auto &sub_path : sub_cfg) - { sub_path.setup(); } - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_host_control_registers_and_msrs_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_eax_cpuid[0x80000008ULL] = 48UL; - g_msrs[ia32_vmx_cr0_fixed0::addr] = 0ULL; // allow cr0 and - g_msrs[ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; // cr4 bits to be - g_msrs[ia32_vmx_cr4_fixed0::addr] = 0ULL; // either 0 or 1 - g_msrs[ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; // - host_cr3::set(0x1000UL); // host_cr3 is valid physical address - host_ia32_sysenter_esp::set(0x1000UL); // esp is canonical address - host_ia32_sysenter_eip::set(0x1000UL); // eip is canonical address - vm_exit_controls::load_ia32_perf_global_ctrl::disable(); - vm_exit_controls::load_ia32_pat::disable(); - vm_exit_controls::load_ia32_efer::disable(); - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_host_segment_and_descriptor_table_registers_all_paths( - std::vector &cfg) -{ - using namespace x64::segment_register; - struct control_flow_path path; - - path.setup = [&] { - host_es_selector::ti::disable(); host_es_selector::rpl::set(0UL); // es.ti == 0 && es.rpl == 0 - host_cs_selector::ti::disable(); host_cs_selector::rpl::set(0UL); // cs.ti == 0 && cs.rpl == 0 - host_ss_selector::ti::disable(); host_ss_selector::rpl::set(0UL); // ss.ti == 0 && ss.rpl == 0 - host_ds_selector::ti::disable(); host_ds_selector::rpl::set(0UL); // ds.ti == 0 && ds.rpl == 0 - host_fs_selector::ti::disable(); host_fs_selector::rpl::set(0UL); // fs.ti == 0 && fs.rpl == 0 - host_gs_selector::ti::disable(); host_gs_selector::rpl::set(0UL); // gs.ti == 0 && gs.rpl == 0 - host_tr_selector::ti::disable(); host_tr_selector::rpl::set(0UL); // tr.ti == 0 && tr.rpl == 0 - - host_cs_selector::set(~(cs::ti::mask | cs::rpl::mask)); // cs != 0 - host_tr_selector::set(~(tr::ti::mask | tr::rpl::mask)); // tr != 0 - - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); - vm_exit_controls::host_address_space_size::enable(); // VM-exit ctrl host_address_space_size is 1 - host_fs_base::set(0x1000UL); // fs base is canonical address - host_gs_base::set(0x1000UL); // gs base is canonical address - host_gdtr_base::set(0x1000UL); // gdtr base is canonical address - host_idtr_base::set(0x1000UL); // idtr base is canonical address - host_tr_base::set(0x1000UL); // tr base is canonical address - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_host_address_space_size_all_paths(std::vector &cfg) -{ - struct control_flow_path path; - - path.setup = [&] { - g_msrs[ia32_efer::addr] |= msrs::ia32_efer::lma::mask; // efer.lma == 1 - exit_ctl_allow1(ia32_vmx_true_exit_ctls::host_address_space_size::mask); - vm_exit_controls::host_address_space_size::enable(); // VM-exit ctrl host_address_space_size is 1 - host_cr4::physical_address_extensions::enable(); // host_cr4::physical_address_extensions == 1 - host_rip::set(0x1000UL); // rip is canonical address - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_host_state_all_paths(std::vector &cfg) -{ - std::vector sub_cfg; - struct control_flow_path path; - - setup_check_host_control_registers_and_msrs_all_paths(sub_cfg); - setup_check_host_segment_and_descriptor_table_registers_all_paths(sub_cfg); - setup_check_host_address_space_size_all_paths(sub_cfg); - - path.setup = [sub_cfg] { - g_eax_cpuid[0x80000008ULL] = 48UL; - for (const auto &sub_path : sub_cfg) - { sub_path.setup(); } - }; - path.throws_exception = false; - cfg.push_back(path); -} - -inline void -setup_check_all_paths(std::vector &cfg) -{ - std::vector sub_cfg; - struct control_flow_path path; - - setup_check_control_vmx_controls_all_paths(sub_cfg); - setup_check_host_state_all_paths(sub_cfg); - setup_check_guest_state_all_paths(sub_cfg); - - path.setup = [sub_cfg] { - for (const auto &sub_path : sub_cfg) - { - sub_path.setup(); - } - }; - path.throws_exception = false; - cfg.push_back(path); -} - -/// @endcond - -#endif diff --git a/bfvmm/tests/hve/arch/intel_x64/vmxon/test_vmxon.cpp b/bfvmm/tests/hve/arch/intel_x64/vmxon/test_vmxon.cpp index f81dcf9c7..37edfe520 100644 --- a/bfvmm/tests/hve/arch/intel_x64/vmxon/test_vmxon.cpp +++ b/bfvmm/tests/hve/arch/intel_x64/vmxon/test_vmxon.cpp @@ -16,7 +16,7 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include "../test_support.h" +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT diff --git a/bfvmm/tests/hve/arch/x64/test_gdt.cpp b/bfvmm/tests/hve/arch/x64/test_gdt.cpp index e252e6bd0..d725558fb 100644 --- a/bfvmm/tests/hve/arch/x64/test_gdt.cpp +++ b/bfvmm/tests/hve/arch/x64/test_gdt.cpp @@ -16,357 +16,233 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include -#include +#include -#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT +TEST_CASE("gdt_constructor_no_size") +{ + setup_gdt(); + gdt_x64 gdt; +} -TEST_CASE("test name goes here") +TEST_CASE("gdt_constructor_zero_size") { - CHECK(true); + CHECK_NOTHROW(gdt_x64{0}); } -std::vector g_gdt = { - 0x0, - 0xFFFFFFFFFFFFFFFF, - 0xFFFF8FFFFFFFFFFF, - 0x00000000FFFFFFFF -}; +TEST_CASE("gdt_constructor_size") +{ + gdt_x64 gdt{4}; + CHECK(gdt.base() != 0); + CHECK(gdt.limit() == 4 * sizeof(gdt_x64::segment_descriptor_type) - 1); +} + +TEST_CASE("gdt_base") +{ + g_gdtr.base = reinterpret_cast(g_gdt.data()); -gdt_reg_x64_t g_gdt_reg; + gdt_x64 gdt; + CHECK(gdt.base() == reinterpret_cast(g_gdt.data())); +} -void -test_read_gdt(gdt_reg_x64_t *gdt_reg) noexcept -{ *gdt_reg = g_gdt_reg; } +TEST_CASE("gdt_limit") +{ + g_gdtr.limit = 42; -void -test_write_gdt(gdt_reg_x64_t *gdt_reg) noexcept -{ g_gdt_reg = *gdt_reg; } + gdt_x64 gdt; + CHECK(gdt.limit() == 42); +} -static void -setup_intrinsics(MockRepository &mocks) +TEST_CASE("gdt_set_base_zero_index") { - mocks.OnCallFunc(_read_gdt).Do(test_read_gdt); - mocks.OnCallFunc(_write_gdt).Do(test_write_gdt); + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.set_base(0, 0x10)); } -TEST_CASE("gdt_reg_set_get") +TEST_CASE("gdt_set_base_invalid_index") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.set_base(1000, 0x10)); +} - x64::gdt::set(g_gdt.data(), 4 << 3); +TEST_CASE("gdt_set_base_tss_at_end_of_gdt") +{ + setup_gdt(); - CHECK(x64::gdt::get().base == g_gdt.data()); - CHECK(x64::gdt::get().limit == 4 << 3); + gdt_x64 gdt; + CHECK_THROWS(gdt.set_base(7, 0x10)); } -TEST_CASE("gdt_reg_base_set_get") +TEST_CASE("gdt_set_base_descriptor_success") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - x64::gdt::base::set(g_gdt.data()); - CHECK(x64::gdt::base::get() == g_gdt.data()); + gdt_x64 gdt; + CHECK_NOTHROW(gdt.set_base(5, 0xBBBBBBBB12345678)); + CHECK(gdt.m_gdt.at(5) == 0x12FFFF345678FFFF); } -TEST_CASE("gdt_reg_limit_set_get") +TEST_CASE("gdt_set_base_tss_success") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - x64::gdt::limit::set(4 << 3); - CHECK(x64::gdt::limit::get() == 4 << 3); + gdt_x64 gdt; + CHECK_NOTHROW(gdt.set_base(6, 0x1234567812345678)); + CHECK(gdt.m_gdt.at(6) == 0x12FF8F345678FFFF); + CHECK(gdt.m_gdt.at(7) == 0x0000000012345678); } -TEST_CASE("gdt_size") +TEST_CASE("gdt_base_zero_index") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - uint64_t bytes = 0x0; - CHECK(x64::gdt::size(bytes) == 0U); + gdt_x64 gdt; + CHECK_THROWS(gdt.base(0)); +} + +TEST_CASE("gdt_base_invalid_index") +{ + setup_gdt(); - bytes = 0x2; - CHECK(x64::gdt::size(bytes) == 1U); + gdt_x64 gdt; + CHECK_THROWS(gdt.base(1000)); +} - bytes = 0x1000; - CHECK(x64::gdt::size(bytes) == 1U * x64::page_size); +TEST_CASE("gdt_base_tss_at_end_of_gdt") +{ + setup_gdt(); - bytes = 0x2001; - CHECK(x64::gdt::size(bytes) == 2U * x64::page_size + 1U); + gdt_x64 gdt; + CHECK_THROWS(gdt.base(7)); } -TEST_CASE("gdt_constructor_no_size") +TEST_CASE("gdt_base_descriptor_success") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - gdt_x64 gdt; + gdt_x64 gdt; + gdt.m_gdt.at(5) = 0x12FFFF345678FFFF; + CHECK(gdt.base(5) == 0x0000000012345678); } -TEST_CASE("gdt_constructor_zero_size") +TEST_CASE("gdt_base_tss_success") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - CHECK_NOTHROW(gdt_x64{0}); + gdt_x64 gdt; + gdt.m_gdt.at(6) = 0x12FF8F345678FFFF; + gdt.m_gdt.at(7) = 0x0000000012345678; + CHECK(gdt.base(6) == 0x1234567812345678); } -TEST_CASE("gdt_constructor_size") +TEST_CASE("gdt_set_limit_zero_index") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - gdt_x64 gdt{4}; - CHECK(gdt.base() != 0); - CHECK(gdt.limit() == 4 * sizeof(gdt_x64::segment_descriptor_type) - 1); + gdt_x64 gdt; + CHECK_THROWS(gdt.set_limit(0, 0x10)); } -TEST_CASE("gdt_base") +TEST_CASE("gdt_set_limit_invalid_index") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - gdt_x64 gdt; - CHECK(gdt.base() == reinterpret_cast(g_gdt.data())); + gdt_x64 gdt; + CHECK_THROWS(gdt.set_limit(1000, 0x10)); } -TEST_CASE("gdt_limit") +TEST_CASE("gdt_set_limit_descriptor_success") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); - gdt_x64 gdt; - CHECK(gdt.limit() == 4 * sizeof(gdt_x64::segment_descriptor_type)); + gdt_x64 gdt; + CHECK_NOTHROW(gdt.set_limit(5, 0x12345678)); + CHECK(gdt.m_gdt.at(5) == 0xFFF1FFFFFFFF2345); } -//TEST_CASE("gdt_set_base_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_base(0, 0x10)); -//} -// -//TEST_CASE("gdt_set_base_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_base(1000, 0x10)); -//} -// -//TEST_CASE("gdt_set_base_tss_at_end_of_gdt") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_base(3, 0x10)); -//} -// -//TEST_CASE("gdt_set_base_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// CHECK_NOTHROW(gdt.set_base(1, 0xBBBBBBBB12345678)); -// CHECK(gdt.m_gdt.at(1) == 0x12FFFF345678FFFF); -//} -// -//TEST_CASE("gdt_set_base_tss_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// CHECK_NOTHROW(gdt.set_base(2, 0x1234567812345678)); -// CHECK(gdt.m_gdt.at(2) == 0x12FF8F345678FFFF); -// CHECK(gdt.m_gdt.at(3) == 0x0000000012345678); -//} -// -//TEST_CASE("gdt_base_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.base(0)); -//} -// -//TEST_CASE("gdt_base_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.base(1000)); -//} -// -//TEST_CASE("gdt_base_tss_at_end_of_gdt") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.base(3)); -//} -// -//TEST_CASE("gdt_base_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// gdt.m_gdt.at(1) = 0x12FFFF345678FFFF; -// CHECK(gdt.base(1) == 0x0000000012345678); -//} -// -//TEST_CASE("gdt_base_tss_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// gdt.m_gdt.at(2) = 0x12FF8F345678FFFF; -// gdt.m_gdt.at(3) = 0x0000000012345678; -// CHECK(gdt.base(2) == 0x1234567812345678); -//} -// -//TEST_CASE("gdt_set_limit_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_limit(0, 0x10)); -//} -// -//TEST_CASE("gdt_set_limit_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_limit(1000, 0x10)); -//} -// -//TEST_CASE("gdt_set_limit_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// CHECK_NOTHROW(gdt.set_limit(1, 0x12345678)); -// CHECK(gdt.m_gdt.at(1) == 0xFFF1FFFFFFFF2345); -//} -// -//TEST_CASE("gdt_limit_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.limit(0)); -//} -// -//TEST_CASE("gdt_limit_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.limit(1000)); -//} -// -//TEST_CASE("gdt_limit_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// gdt.m_gdt.at(1) = 0xFFF4FFFFFFFF5678; -// CHECK(gdt.limit(1) == 0x0000000045678FFF); -//} -// -//TEST_CASE("gdt_limit_descriptor_in_bytes_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// gdt.m_gdt.at(1) = 0xFF74FFFFFFFF5678; -// CHECK(gdt.limit(1) == 0x0000000000045678); -//} -// -//TEST_CASE("gdt_set_access_rights_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_access_rights(0, 0x10)); -//} -// -//TEST_CASE("gdt_set_access_rights_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.set_access_rights(1000, 0x10)); -//} -// -//TEST_CASE("gdt_set_access_rights_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// CHECK_NOTHROW(gdt.set_access_rights(1, 0x12345678)); -// CHECK(gdt.m_gdt.at(1) == 0xFF5F78FFFFFFFFFF); -//} -// -//TEST_CASE("gdt_access_rights_zero_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.access_rights(0)); -//} -// -//TEST_CASE("gdt_access_rights_invalid_index") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// CHECK_THROWS(gdt.access_rights(1000)); -//} -// -//TEST_CASE("gdt_access_rights_descriptor_success") -//{ -// MockRepository mocks; -// setup_intrinsics(mocks); -// -// gdt_x64 gdt; -// -// gdt.m_gdt.at(1) = 0xFF5F78FFFFFFFFFF; -// CHECK(gdt.access_rights(1) == 0x0000000000005078); -//} +TEST_CASE("gdt_limit_zero_index") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.limit(0)); +} + +TEST_CASE("gdt_limit_invalid_index") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.limit(1000)); +} + +TEST_CASE("gdt_limit_descriptor_success") +{ + setup_gdt(); + + gdt_x64 gdt; + gdt.m_gdt.at(5) = 0xFFF4FFFFFFFF5678; + CHECK(gdt.limit(5) == 0x0000000045678FFF); +} + +TEST_CASE("gdt_limit_descriptor_in_bytes_success") +{ + setup_gdt(); + + gdt_x64 gdt; + gdt.m_gdt.at(5) = 0xFF74FFFFFFFF5678; + CHECK(gdt.limit(5) == 0x0000000000045678); +} + +TEST_CASE("gdt_set_access_rights_zero_index") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.set_access_rights(0, 0x10)); +} + +TEST_CASE("gdt_set_access_rights_invalid_index") +{ + setup_gdt(); -#endif + gdt_x64 gdt; + CHECK_THROWS(gdt.set_access_rights(1000, 0x10)); +} + +TEST_CASE("gdt_set_access_rights_descriptor_success") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_NOTHROW(gdt.set_access_rights(5, 0x12345678)); + CHECK(gdt.m_gdt.at(5) == 0xFF5F78FFFFFFFFFF); +} + +TEST_CASE("gdt_access_rights_zero_index") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.access_rights(0)); +} + +TEST_CASE("gdt_access_rights_invalid_index") +{ + setup_gdt(); + + gdt_x64 gdt; + CHECK_THROWS(gdt.access_rights(1000)); +} + +TEST_CASE("gdt_access_rights_descriptor_success") +{ + setup_gdt(); + + gdt_x64 gdt; + gdt.m_gdt.at(5) = 0xFF5F78FFFFFFFFFF; + CHECK(gdt.access_rights(5) == 0x0000000000005078); +} diff --git a/bfvmm/tests/hve/arch/x64/test_idt.cpp b/bfvmm/tests/hve/arch/x64/test_idt.cpp index 70da0b082..0bfcfcfbf 100644 --- a/bfvmm/tests/hve/arch/x64/test_idt.cpp +++ b/bfvmm/tests/hve/arch/x64/test_idt.cpp @@ -16,115 +16,32 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include -#include -#include - -#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT - -std::vector g_idt = { - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF, - 0xFFFFFFFFFFFFFFFF -}; - -idt_reg_x64_t g_idt_reg; - -void -test_read_idt(idt_reg_x64_t *idt_reg) noexcept -{ *idt_reg = g_idt_reg; } - -void -test_write_idt(idt_reg_x64_t *idt_reg) noexcept -{ g_idt_reg = *idt_reg; } - -static void -setup_intrinsics(MockRepository &mocks) -{ - mocks.OnCallFunc(_read_idt).Do(test_read_idt); - mocks.OnCallFunc(_write_idt).Do(test_write_idt); -} - -TEST_CASE("idt_reg_set_get") -{ - MockRepository mocks; - setup_intrinsics(mocks); - - x64::idt::set(g_idt.data(), (4 << 3) - 1); - - CHECK(x64::idt::get().base == g_idt.data()); - CHECK(x64::idt::get().limit == (4 << 3) - 1); -} - -TEST_CASE("idt_reg_base_set_get") -{ - MockRepository mocks; - setup_intrinsics(mocks); - - x64::idt::base::set(g_idt.data()); - CHECK(x64::idt::base::get() == g_idt.data()); -} - -TEST_CASE("idt_reg_limit_set_get") -{ - MockRepository mocks; - setup_intrinsics(mocks); - - x64::idt::limit::set((4 << 3) - 1); - CHECK(x64::idt::limit::get() == (4 << 3) - 1); -} - -TEST_CASE("idt_size") -{ - MockRepository mocks; - setup_intrinsics(mocks); - - uint64_t bytes = 0; - CHECK(x64::idt::size(bytes) == 0U); - - bytes = 0xfff; - CHECK(x64::idt::size(bytes) == 1U); - - bytes = 0x1000; - CHECK(x64::idt::size(bytes) == 1U * x64::page_size); - - bytes = 0x5001; - CHECK(x64::idt::size(bytes) == 5U * x64::page_size + 1U); -} +#include TEST_CASE("idt_constructor_no_size") { - MockRepository mocks; - setup_intrinsics(mocks); - + setup_idt(); idt_x64 idt; } TEST_CASE("idt_constructor_zero_size") { - MockRepository mocks; - setup_intrinsics(mocks); - + setup_idt(); CHECK_NOTHROW(idt_x64{0}); } TEST_CASE("idt_constructor_size") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_idt(); idt_x64 idt{4}; - CHECK(idt.base() != 0); CHECK(idt.limit() == (4 * sizeof(idt_x64::interrupt_descriptor_type)) - 1); } TEST_CASE("idt_base") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_idt(); idt_x64 idt; CHECK(idt.base() == reinterpret_cast(g_idt.data())); @@ -132,11 +49,8 @@ TEST_CASE("idt_base") TEST_CASE("idt_limit") { - MockRepository mocks; - setup_intrinsics(mocks); + setup_idt(); idt_x64 idt; CHECK(idt.limit() == (4 * sizeof(idt_x64::interrupt_descriptor_type)) - 1); } - -#endif diff --git a/bfvmm/tests/support/CMakeLists.txt b/bfvmm/tests/support/CMakeLists.txt new file mode 100644 index 000000000..b807655e0 --- /dev/null +++ b/bfvmm/tests/support/CMakeLists.txt @@ -0,0 +1,32 @@ +# +# Bareflank Hypervisor +# Copyright (C) 2015 Assured Information Security, Inc. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +list(APPEND ARGN + DEPENDS bfvmm_vcpu + DEPENDS bfvmm_hve + DEPENDS bfvmm_memory_manager + DEFINES STATIC_VCPU + DEFINES STATIC_HVE + DEFINES STATIC_MEMORY_MANAGER + DEFINES STATIC_INTRINSICS +) + +do_test(test_support + SOURCES arch/intel_x64/test_support.cpp + ${ARGN} +) diff --git a/bfvmm/tests/support/arch/intel_x64/test_support.cpp b/bfvmm/tests/support/arch/intel_x64/test_support.cpp new file mode 100644 index 000000000..445909ee5 --- /dev/null +++ b/bfvmm/tests/support/arch/intel_x64/test_support.cpp @@ -0,0 +1,83 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include + +TEST_CASE("support") +{ + CHECK_NOTHROW(_read_msr(0)); + CHECK_NOTHROW(_write_msr(0, 0)); + + CHECK_NOTHROW(_read_cr0()); + CHECK_NOTHROW(_read_cr3()); + CHECK_NOTHROW(_read_cr4()); + CHECK_NOTHROW(_write_cr0(0)); + CHECK_NOTHROW(_write_cr3(0)); + CHECK_NOTHROW(_write_cr4(0)); + + CHECK_NOTHROW(_read_dr7()); + CHECK_NOTHROW(_write_dr7(0)); + + CHECK_NOTHROW(_read_rflags()); + CHECK_NOTHROW(_write_rflags(0)); + + CHECK_NOTHROW(_read_es()); + CHECK_NOTHROW(_read_cs()); + CHECK_NOTHROW(_read_ss()); + CHECK_NOTHROW(_read_ds()); + CHECK_NOTHROW(_read_fs()); + CHECK_NOTHROW(_read_gs()); + CHECK_NOTHROW(_read_tr()); + CHECK_NOTHROW(_read_ldtr()); + + CHECK_NOTHROW(_write_es(0)); + CHECK_NOTHROW(_write_cs(0)); + CHECK_NOTHROW(_write_ss(0)); + CHECK_NOTHROW(_write_ds(0)); + CHECK_NOTHROW(_write_fs(0)); + CHECK_NOTHROW(_write_gs(0)); + CHECK_NOTHROW(_write_tr(0)); + CHECK_NOTHROW(_write_ldtr(0)); + + CHECK_NOTHROW(_read_gdt(&g_gdtr)); + CHECK_NOTHROW(_read_idt(&g_gdtr)); + + CHECK_NOTHROW(_stop()); + CHECK_NOTHROW(_wbinvd()); + CHECK_NOTHROW(_invlpg(nullptr)); + + CHECK_NOTHROW(_cpuid(nullptr, nullptr, nullptr, nullptr)); + CHECK_NOTHROW(_cpuid_eax(0)); + CHECK_NOTHROW(_cpuid_subebx(0, 0)); + CHECK_NOTHROW(_cpuid_ecx(0)); + + CHECK_NOTHROW(_vmclear(nullptr)); + CHECK_NOTHROW(_vmptrld(nullptr)); + CHECK_NOTHROW(_vmlaunch_demote()); + CHECK_NOTHROW(_vmxon(nullptr)); + CHECK_NOTHROW(_vmxoff()); + + CHECK_NOTHROW(vmcs_launch(nullptr)); + CHECK_NOTHROW(vmcs_promote(nullptr, nullptr)); + CHECK_NOTHROW(vmcs_resume(nullptr)); + + CHECK_NOTHROW(thread_context_cpuid()); + CHECK_NOTHROW(thread_context_tlsptr()); + + CHECK_NOTHROW(exit_handler_entry()); +} diff --git a/bfvmm/tests/support/arch/intel_x64/test_support.h b/bfvmm/tests/support/arch/intel_x64/test_support.h new file mode 100644 index 000000000..c2927fc7e --- /dev/null +++ b/bfvmm/tests/support/arch/intel_x64/test_support.h @@ -0,0 +1,959 @@ +// +// Bareflank Hypervisor +// Copyright (C) 2015 Assured Information Security, Inc. +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +#include +#include + +using namespace x64; +using namespace intel_x64; +using namespace vmcs; + +std::map g_msrs; +std::map g_vmcs_fields; +std::map g_eax_cpuid; +std::map g_ebx_cpuid; +std::map g_ecx_cpuid; + +uintptr_t g_rip = 0; + +x64::dr7::value_type g_dr7 = 0; +x64::rflags::value_type g_rflags = 0; +intel_x64::cr0::value_type g_cr0 = 0; +intel_x64::cr3::value_type g_cr3 = 0; +intel_x64::cr4::value_type g_cr4 = 0; + +uint16_t g_es; +uint16_t g_cs; +uint16_t g_ss; +uint16_t g_ds; +uint16_t g_fs; +uint16_t g_gs; +uint16_t g_ldtr; +uint16_t g_tr; + +gdt_reg::reg_t g_gdtr{}; +idt_reg::reg_t g_idtr{}; + +std::vector g_gdt = { + 0x0, + 0xFF7FFFFFFFFFFFFF, + 0xFF7FFFFFFFFFFFFF, + 0xFF7FFFFFFFFFFFFF, + 0xFF7FFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, + 0xFFFF8FFFFFFFFFFF, + 0x00000000FFFFFFFF, +}; + +std::vector g_idt = { + 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF, + 0xFFFFFFFFFFFFFFFF +}; + +alignas(0x1000) static char g_map[100]; + +auto g_msg = std::string(R"%({"msg":"hello world"})%"); +auto g_state_save = state_save_intel_x64 {}; + +bool g_virt_to_phys_fails = false; +bool g_phys_to_virt_fails = false; +bool g_vmclear_fails = false; +bool g_vmload_fails = false; +bool g_vmlaunch_fails = false; +bool g_vmxon_fails = false; +bool g_vmxoff_fails = false; +bool g_write_cr4_fails = false; + +uint64_t g_test_addr = 0U; +uint64_t g_virt_apic_addr = 0U; +uint64_t g_virt_apic_mem[64] = {0U}; +uint64_t g_vmcs_link_addr = 1U; +uint64_t g_vmcs_link_mem[1] = {0U}; +uint64_t g_pdpt_addr = 2U; +uint64_t g_pdpt_mem[4] = {0U}; + +std::map g_mock_mem {{ + {g_virt_apic_addr, static_cast(&g_virt_apic_mem)}, + {g_vmcs_link_addr, static_cast(&g_vmcs_link_mem)}, + {g_pdpt_addr, static_cast(&g_pdpt_mem)} +}}; + +struct control_flow_path { + std::function setup{}; + bool throws_exception{false}; +} path; + +struct cpuid_regs { + uint32_t eax; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; +} g_cpuid_regs; + +extern "C" uint64_t +_read_msr(uint32_t addr) noexcept +{ return g_msrs[addr]; } + +extern "C" void +_write_msr(uint32_t addr, uint64_t val) noexcept +{ g_msrs[addr] = val; } + +extern "C" uint64_t +_read_cr0(void) noexcept +{ return g_cr0; } + +extern "C" uint64_t +_read_cr3(void) noexcept +{ return g_cr3; } + +extern "C" uint64_t +_read_cr4(void) noexcept +{ return g_cr4; } + +extern "C" void +_write_cr0(uint64_t val) noexcept +{ g_cr0 = val; } + +extern "C" void +_write_cr3(uint64_t val) noexcept +{ g_cr3 = val; } + +extern "C" void +_write_cr4(uint64_t val) noexcept +{ + if (g_write_cr4_fails) { + return; + } + + g_cr4 = val; +} + +extern "C" uint64_t +_read_dr7() noexcept +{ return g_dr7; } + +extern "C" void +_write_dr7(uint64_t val) noexcept +{ g_dr7 = val; } + +extern "C" uint64_t +_read_rflags(void) noexcept +{ return g_rflags; } + +extern "C" void +_write_rflags(uint64_t val) noexcept +{ g_rflags = val; } + +extern "C" uint16_t +_read_es() noexcept +{ return g_es; } + +extern "C" uint16_t +_read_cs() noexcept +{ return g_cs; } + +extern "C" uint16_t +_read_ss() noexcept +{ return g_ss; } + +extern "C" uint16_t +_read_ds() noexcept +{ return g_ds; } + +extern "C" uint16_t +_read_fs() noexcept +{ return g_fs; } + +extern "C" uint16_t +_read_gs() noexcept +{ return g_gs; } + +extern "C" uint16_t +_read_tr() noexcept +{ return g_tr; } + +extern "C" uint16_t +_read_ldtr() noexcept +{ return g_ldtr; } + +extern "C" void +_write_es(uint16_t val) noexcept +{ g_es = val; } + +extern "C" void +_write_cs(uint16_t val) noexcept +{ g_cs = val; } + +extern "C" void +_write_ss(uint16_t val) noexcept +{ g_ss = val; } + +extern "C" void +_write_ds(uint16_t val) noexcept +{ g_ds = val; } + +extern "C" void +_write_fs(uint16_t val) noexcept +{ g_fs = val; } + +extern "C" void +_write_gs(uint16_t val) noexcept +{ g_gs = val; } + +extern "C" void +_write_tr(uint16_t val) noexcept +{ g_tr = val; } + +extern "C" void +_write_ldtr(uint16_t val) noexcept +{ g_ldtr = val; } + +extern "C" void +_read_gdt(void *gdt_reg) noexcept +{ *static_cast(gdt_reg) = g_gdtr; } + +extern "C" void +_read_idt(void *idt_reg) noexcept +{ *static_cast(idt_reg) = g_idtr; } + +extern "C" void +_stop() noexcept +{ } + +extern "C" void +_wbinvd() noexcept +{ } + +extern "C" void +_invlpg(const void *addr) noexcept +{ bfignored(addr); } + +extern "C" void +_cpuid(void *eax, void *ebx, void *ecx, void *edx) noexcept +{ + bfignored(eax); + bfignored(ebx); + bfignored(ecx); + bfignored(edx); +} + +extern "C" uint32_t +_cpuid_eax(uint32_t val) noexcept +{ return g_eax_cpuid[val]; } + +extern "C" uint32_t +_cpuid_subebx(uint32_t val, uint32_t sub) noexcept +{ bfignored(sub); return g_ebx_cpuid[val]; } + +extern "C" uint32_t +_cpuid_ecx(uint32_t val) noexcept +{ return g_ecx_cpuid[val]; } + +extern "C" bool +_vmread(uint64_t field, uint64_t *value) noexcept +{ + *value = g_vmcs_fields[field]; + return true; +} + +extern "C" bool +_vmwrite(uint64_t field, uint64_t value) noexcept +{ + g_vmcs_fields[field] = value; + return true; +} + +extern "C" bool +_vmclear(void *ptr) noexcept +{ (void)ptr; return !g_vmclear_fails; } + +extern "C" bool +_vmptrld(void *ptr) noexcept +{ (void)ptr; return !g_vmload_fails; } + +extern "C" bool +_vmlaunch_demote() noexcept +{ return !g_vmlaunch_fails; } + +extern "C" bool +_vmxon(void *ptr) noexcept +{ + bfignored(ptr); + return !g_vmxon_fails; +} + +extern "C" bool +_vmxoff() noexcept +{ return !g_vmxoff_fails; } + +extern "C" uint64_t +thread_context_cpuid(void) +{ return 0; } + +extern "C" uint64_t +thread_context_tlsptr(void) +{ return 0; } + +uintptr_t +virtptr_to_physint(void *ptr) +{ + bfignored(ptr); + + if (g_virt_to_phys_fails) { + throw gsl::fail_fast(""); + } + + return 0x0000000ABCDEF0000; +} + +void * +physint_to_virtptr(uintptr_t ptr) +{ + bfignored(ptr); + + if (g_phys_to_virt_fails) { + return nullptr; + } + + return static_cast(g_mock_mem[g_test_addr]); +} + +extern "C" void +vmcs_launch(state_save_intel_x64 *state_save) noexcept +{ } + +extern "C" void +vmcs_promote(state_save_intel_x64 *state_save, const void *guest_gdt) noexcept +{ } + +extern "C" void +vmcs_resume(state_save_intel_x64 *state_save) noexcept +{ } + +extern "C" void +exit_handler_entry(void) noexcept +{ } + +void +setup_msrs() +{ + g_msrs[intel_x64::msrs::ia32_vmx_basic::addr] = (1ULL << 55) | (6ULL << 50); + g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] = 0xFFFFFFFF00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] = 0xFFFFFFFF00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] = 0xFFFFFFFF00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] = 0xFFFFFFFF00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000UL; + + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed0::addr] = 0U; + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFF; + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed0::addr] = 0U; + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFF; + + g_msrs[intel_x64::msrs::ia32_efer::addr] = intel_x64::msrs::ia32_efer::lma::mask; + g_msrs[intel_x64::msrs::ia32_feature_control::addr] = (0x1ULL << 0); +} + +void +setup_cpuid() +{ + g_ecx_cpuid[intel_x64::cpuid::feature_information::addr] = intel_x64::cpuid::feature_information::ecx::vmx::mask; +} + +void +setup_registers() +{ + g_cr0 = 0x0; + g_cr3 = 0x0; + g_cr4 = 0x0; + g_rflags = 0x0; +} + +void +setup_gdt() +{ + auto limit = g_gdt.size() * sizeof(gdt_x64::segment_descriptor_type) - 1; + + g_gdtr.base = reinterpret_cast(&g_gdt.at(0)); + g_gdtr.limit = gsl::narrow_cast(limit); +} + +void +setup_idt() +{ + auto limit = g_idt.size() * sizeof(idt_x64::interrupt_descriptor_type) - 1; + + g_idtr.base = reinterpret_cast(&g_idt.at(0)); + g_idtr.limit = gsl::narrow_cast(limit); +} + +#ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT + +template auto +mock_no_delete(MockRepository &mocks) +{ + auto ptr = mocks.Mock(); + mocks.OnCallDestructor(ptr); + + return ptr; +} + +template auto +mock_unique(MockRepository &mocks) +{ + return std::unique_ptr(mock_no_delete(mocks)); +} + +auto +setup_mm(MockRepository &mocks) +{ + auto mm = mocks.Mock(); + mocks.OnCallFunc(memory_manager_x64::instance).Return(mm); + + mocks.OnCall(mm, memory_manager_x64::alloc_map).Return(static_cast(g_map)); + mocks.OnCall(mm, memory_manager_x64::free_map); + mocks.OnCall(mm, memory_manager_x64::virtptr_to_physint).Do(virtptr_to_physint); + mocks.OnCall(mm, memory_manager_x64::physint_to_virtptr).Do(physint_to_virtptr); + + mocks.OnCallFunc(bfn::map_with_cr3); + mocks.OnCallFunc(bfn::virt_to_phys_with_cr3).Return(0x42); + + return mm; +} + +auto +setup_pt(MockRepository &mocks) +{ + auto pt = mocks.Mock(); + mocks.OnCallFunc(root_pt).Return(pt); + + mocks.OnCall(pt, root_page_table_x64::map_4k); + mocks.OnCall(pt, root_page_table_x64::unmap); + mocks.OnCall(pt, root_page_table_x64::cr3).Return(0x000000ABCDEF0000); + + return pt; +} + +auto +setup_vmcs_state(MockRepository &mocks) +{ + auto state = mocks.Mock(); + + mocks.OnCall(state, vmcs_intel_x64_state::es).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::cs).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::ss).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::ds).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::fs).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::gs).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::ldtr).Return(0x10); + mocks.OnCall(state, vmcs_intel_x64_state::tr).Return(0x10); + + mocks.OnCall(state, vmcs_intel_x64_state::gdt_limit).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::idt_limit).Return(0); + + mocks.OnCall(state, vmcs_intel_x64_state::es_limit).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::cs_limit).Return(0xFFFFFFFF); + mocks.OnCall(state, vmcs_intel_x64_state::ss_limit).Return(0xFFFFFFFF); + mocks.OnCall(state, vmcs_intel_x64_state::ds_limit).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::fs_limit).Return(0xFFFFFFFF); + mocks.OnCall(state, vmcs_intel_x64_state::gs_limit).Return(0xFFFFFFFF); + mocks.OnCall(state, vmcs_intel_x64_state::ldtr_limit).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::tr_limit).Return(sizeof(tss_x64)); + + mocks.OnCall(state, vmcs_intel_x64_state::es_access_rights).Return(access_rights::unusable); + mocks.OnCall(state, vmcs_intel_x64_state::cs_access_rights).Return(access_rights::ring0_cs_descriptor); + mocks.OnCall(state, vmcs_intel_x64_state::ss_access_rights).Return(access_rights::ring0_ss_descriptor); + mocks.OnCall(state, vmcs_intel_x64_state::ds_access_rights).Return(access_rights::unusable); + mocks.OnCall(state, vmcs_intel_x64_state::fs_access_rights).Return(access_rights::ring0_fs_descriptor); + mocks.OnCall(state, vmcs_intel_x64_state::gs_access_rights).Return(access_rights::ring0_gs_descriptor); + mocks.OnCall(state, vmcs_intel_x64_state::ldtr_access_rights).Return(access_rights::unusable); + mocks.OnCall(state, vmcs_intel_x64_state::tr_access_rights).Return(access_rights::ring0_tr_descriptor); + + mocks.OnCall(state, vmcs_intel_x64_state::es_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::cs_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ss_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ds_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ds_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::fs_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::gs_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ldtr_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::tr_base).Return(0); + + auto cr0 = 0UL; + cr0 |= cr0::paging::mask; + cr0 |= cr0::protection_enable::mask; + + auto cr4 = 0UL; + cr4 |= cr4::physical_address_extensions::mask; + + auto rflags = 0UL; + rflags |= rflags::interrupt_enable_flag::mask; + + mocks.OnCall(state, vmcs_intel_x64_state::cr0).Return(cr0); + mocks.OnCall(state, vmcs_intel_x64_state::cr3).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::cr4).Return(cr4); + mocks.OnCall(state, vmcs_intel_x64_state::dr7).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::rflags).Return(rflags); + mocks.OnCall(state, vmcs_intel_x64_state::gdt_base).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::idt_base).Return(0); + + auto efer = 0UL; + efer |= intel_x64::msrs::ia32_efer::lme::mask; + efer |= intel_x64::msrs::ia32_efer::lma::mask; + + mocks.OnCall(state, vmcs_intel_x64_state::ia32_debugctl_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_pat_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_efer_msr).Return(efer); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_perf_global_ctrl_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_cs_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_esp_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_sysenter_eip_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_fs_base_msr).Return(0); + mocks.OnCall(state, vmcs_intel_x64_state::ia32_gs_base_msr).Return(0); + + mocks.OnCall(state, vmcs_intel_x64_state::is_guest).Return(false); + mocks.OnCall(state, vmcs_intel_x64_state::dump); + + return state; +} + +inline void +proc_ctl_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] |= mask << 32; } + +inline void +proc_ctl_allow0(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] &= ~mask; } + +inline void +proc_ctl_disallow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] &= ~(mask << 32); } + +inline void +proc_ctl2_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] |= mask << 32; } + +inline void +proc_ctl2_allow0(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] &= ~mask; } + +inline void +proc_ctl2_disallow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] &= ~(mask << 32); } + +inline void +pin_ctl_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] |= mask << 32; } + +inline void +pin_ctl_allow0(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] &= ~mask; } + +inline void +exit_ctl_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] |= mask << 32; } + +inline void +exit_ctl_allow0(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] &= ~mask; } + +inline void +entry_ctl_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] |= mask << 32; } + +inline void +entry_ctl_allow0(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] &= ~mask; } + +inline void +vmfunc_ctl_allow1(uint64_t mask) +{ g_msrs[intel_x64::msrs::ia32_vmx_vmfunc::addr] |= mask; } + +inline void +setup_check_control_vm_execution_control_fields_all_paths(std::vector + &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_pinbased_ctls::addr] = 0xffffffff00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_true_procbased_ctls::addr] = 0xffffffff00000000UL; + g_msrs[intel_x64::msrs::ia32_vmx_procbased_ctls2::addr] = 0xffffffff00000000UL; + cr3_target_count::set(3UL); + primary_processor_based_vm_execution_controls::use_io_bitmaps::disable(); + primary_processor_based_vm_execution_controls::use_msr_bitmap::disable(); + primary_processor_based_vm_execution_controls::use_tpr_shadow::disable(); + secondary_processor_based_vm_execution_controls::virtualize_x2apic_mode::disable(); + secondary_processor_based_vm_execution_controls::apic_register_virtualization::disable(); + secondary_processor_based_vm_execution_controls::virtual_interrupt_delivery::disable(); + pin_based_vm_execution_controls::nmi_exiting::enable(); + pin_based_vm_execution_controls::virtual_nmis::enable(); + secondary_processor_based_vm_execution_controls::virtualize_apic_accesses::disable(); + pin_based_vm_execution_controls::process_posted_interrupts::disable(); + secondary_processor_based_vm_execution_controls::enable_vpid::disable(); + secondary_processor_based_vm_execution_controls::enable_ept::disable(); + secondary_processor_based_vm_execution_controls::enable_pml::disable(); + secondary_processor_based_vm_execution_controls::unrestricted_guest::disable(); + secondary_processor_based_vm_execution_controls::enable_vm_functions::disable(); + secondary_processor_based_vm_execution_controls::vmcs_shadowing::disable(); + secondary_processor_based_vm_execution_controls::ept_violation_ve::disable(); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_control_vm_exit_control_fields_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_exit_ctls::addr] = 0xffffffff00000000UL; + pin_ctl_allow1(intel_x64::msrs::ia32_vmx_true_pinbased_ctls::activate_vmx_preemption_timer::mask); + pin_based_vm_execution_controls::activate_vmx_preemption_timer::enable(); + vm_exit_msr_store_count::set(0UL); + vm_exit_msr_load_count::set(0UL); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_control_vm_entry_control_fields_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xffffffff00000000UL; + vm_entry_interruption_information::valid_bit::disable(); + vm_entry_msr_load_count::set(0UL); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_control_vmx_controls_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + std::vector sub_cfg; + + setup_check_control_vm_execution_control_fields_all_paths(sub_cfg); + setup_check_control_vm_exit_control_fields_all_paths(sub_cfg); + setup_check_control_vm_entry_control_fields_all_paths(sub_cfg); + + path.setup = [sub_cfg] { + for (const auto &sub_path : sub_cfg) + { sub_path.setup(); } + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_control_registers_debug_registers_and_msrs_all_paths( + std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed0::addr] = 0ULL; + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; + guest_cr0::paging::disable(); + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed0::addr] = 0ULL; + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; + vm_entry_controls::load_debug_controls::disable(); + vm_entry_controls::ia_32e_mode_guest::disable(); + guest_cr4::pcid_enable_bit::disable(); + g_eax_cpuid[x64::cpuid::addr_size::addr] = 48U; + guest_cr3::set(0x1000UL); + guest_ia32_sysenter_esp::set(0x1000UL); + guest_ia32_sysenter_eip::set(0x1000UL); + vm_entry_controls::load_ia32_perf_global_ctrl::disable(); + vm_entry_controls::load_ia32_pat::disable(); + vm_entry_controls::load_ia32_efer::disable(); + vm_entry_controls::load_ia32_bndcfgs::disable(); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_segment_registers_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + guest_tr_selector::ti::disable(); + guest_ldtr_access_rights::unusable::enable(); + guest_rflags::virtual_8086_mode::enable(); + guest_cs_selector::set(0x1UL); + guest_cs_base::set(0x10UL); + guest_ss_selector::set(0x1UL); + guest_ss_base::set(0x10UL); + guest_ds_selector::set(0x1UL); + guest_ds_base::set(0x10UL); + guest_es_selector::set(0x1UL); + guest_es_base::set(0x10UL); + guest_fs_selector::set(0x1UL); + guest_fs_base::set(0x10UL); + guest_gs_selector::set(0x1UL); + guest_gs_base::set(0x10UL); + guest_tr_base::set(0x10UL); + guest_cs_limit::set(0xFFFFUL); + guest_ss_limit::set(0xFFFFUL); + guest_ds_limit::set(0xFFFFUL); + guest_es_limit::set(0xFFFFUL); + guest_gs_limit::set(0xFFFFUL); + guest_fs_limit::set(0xFFFFUL); + guest_cs_access_rights::set(0xF3UL); + guest_ss_access_rights::set(0xF3UL); + guest_ds_access_rights::set(0xF3UL); + guest_es_access_rights::set(0xF3UL); + guest_fs_access_rights::set(0xF3UL); + guest_gs_access_rights::set(0xF3UL); + guest_tr_access_rights::type::set(gsl::narrow_cast(x64::access_rights::type::read_execute_accessed)); + //guest_tr_access_rights::s::enable(); + guest_tr_access_rights::present::enable(); + guest_tr_limit::set(0x1UL); + guest_tr_access_rights::granularity::disable(); + guest_tr_access_rights::unusable::disable(); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_descriptor_table_registers_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + guest_gdtr_base::set(0x1000UL); + guest_idtr_base::set(0x1000UL); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_rip_and_rflags_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; + vm_entry_controls::ia_32e_mode_guest::disable(); + guest_rip::set(0x1000UL); + guest_rflags::reserved::set(0UL); + guest_rflags::always_enabled::set(0x2UL); + guest_cr0::protection_enable::enable(); + vm_entry_interruption_information::valid_bit::disable(); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_non_register_state_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_vmx_true_entry_ctls::addr] = 0xFFFFFFFF00000000ULL; + guest_activity_state::set(guest_activity_state::active); + guest_interruptibility_state::blocking_by_sti::disable(); + guest_interruptibility_state::blocking_by_mov_ss::disable(); + vm_entry_interruption_information::valid_bit::disable(); + vm_entry_controls::entry_to_smm::disable(); + guest_interruptibility_state::reserved::set(0UL); + guest_interruptibility_state::enclave_interruption::disable(); + guest_pending_debug_exceptions::reserved::set(0UL); + guest_pending_debug_exceptions::rtm::disable(); + vmcs_link_pointer::set(0xFFFFFFFFFFFFFFFFUL); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_pdptes_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + path.setup = [&] { guest_cr0::paging::disable(); }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_guest_state_all_paths(std::vector &cfg) +{ + std::vector sub_cfg; + struct control_flow_path path; + + setup_check_guest_control_registers_debug_registers_and_msrs_all_paths(sub_cfg); + setup_check_guest_segment_registers_all_paths(sub_cfg); + setup_check_guest_descriptor_table_registers_all_paths(sub_cfg); + setup_check_guest_rip_and_rflags_all_paths(sub_cfg); + setup_check_guest_non_register_state_all_paths(sub_cfg); + setup_check_guest_pdptes_all_paths(sub_cfg); + + path.setup = [sub_cfg] { + for (const auto &sub_path : sub_cfg) + { sub_path.setup(); } + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_host_control_registers_and_msrs_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_eax_cpuid[0x80000008ULL] = 48UL; + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed0::addr] = 0ULL; // allow cr0 and + g_msrs[intel_x64::msrs::ia32_vmx_cr0_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; // cr4 bits to be + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed0::addr] = 0ULL; // either 0 or 1 + g_msrs[intel_x64::msrs::ia32_vmx_cr4_fixed1::addr] = 0xFFFFFFFFFFFFFFFFULL; // + host_cr3::set(0x1000UL); // host_cr3 is valid physical address + host_ia32_sysenter_esp::set(0x1000UL); // esp is canonical address + host_ia32_sysenter_eip::set(0x1000UL); // eip is canonical address + vm_exit_controls::load_ia32_perf_global_ctrl::disable(); + vm_exit_controls::load_ia32_pat::disable(); + vm_exit_controls::load_ia32_efer::disable(); + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_host_segment_and_descriptor_table_registers_all_paths( + std::vector &cfg) +{ + using namespace x64::segment_register; + struct control_flow_path path; + + path.setup = [&] { + host_es_selector::ti::disable(); host_es_selector::rpl::set(0UL); // es.ti == 0 && es.rpl == 0 + host_cs_selector::ti::disable(); host_cs_selector::rpl::set(0UL); // cs.ti == 0 && cs.rpl == 0 + host_ss_selector::ti::disable(); host_ss_selector::rpl::set(0UL); // ss.ti == 0 && ss.rpl == 0 + host_ds_selector::ti::disable(); host_ds_selector::rpl::set(0UL); // ds.ti == 0 && ds.rpl == 0 + host_fs_selector::ti::disable(); host_fs_selector::rpl::set(0UL); // fs.ti == 0 && fs.rpl == 0 + host_gs_selector::ti::disable(); host_gs_selector::rpl::set(0UL); // gs.ti == 0 && gs.rpl == 0 + host_tr_selector::ti::disable(); host_tr_selector::rpl::set(0UL); // tr.ti == 0 && tr.rpl == 0 + + host_cs_selector::set(~(cs::ti::mask | cs::rpl::mask)); // cs != 0 + host_tr_selector::set(~(tr::ti::mask | tr::rpl::mask)); // tr != 0 + + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); + vm_exit_controls::host_address_space_size::enable(); // VM-exit ctrl host_address_space_size is 1 + host_fs_base::set(0x1000UL); // fs base is canonical address + host_gs_base::set(0x1000UL); // gs base is canonical address + host_gdtr_base::set(0x1000UL); // gdtr base is canonical address + host_idtr_base::set(0x1000UL); // idtr base is canonical address + host_tr_base::set(0x1000UL); // tr base is canonical address + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_host_address_space_size_all_paths(std::vector &cfg) +{ + struct control_flow_path path; + + path.setup = [&] { + g_msrs[intel_x64::msrs::ia32_efer::addr] |= intel_x64::msrs::ia32_efer::lma::mask; // efer.lma == 1 + exit_ctl_allow1(intel_x64::msrs::ia32_vmx_true_exit_ctls::host_address_space_size::mask); + vm_exit_controls::host_address_space_size::enable(); // VM-exit ctrl host_address_space_size is 1 + host_cr4::physical_address_extensions::enable(); // host_cr4::physical_address_extensions == 1 + host_rip::set(0x1000UL); // rip is canonical address + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_host_state_all_paths(std::vector &cfg) +{ + std::vector sub_cfg; + struct control_flow_path path; + + setup_check_host_control_registers_and_msrs_all_paths(sub_cfg); + setup_check_host_segment_and_descriptor_table_registers_all_paths(sub_cfg); + setup_check_host_address_space_size_all_paths(sub_cfg); + + path.setup = [sub_cfg] { + g_eax_cpuid[0x80000008ULL] = 48UL; + for (const auto &sub_path : sub_cfg) + { sub_path.setup(); } + }; + path.throws_exception = false; + cfg.push_back(path); +} + +inline void +setup_check_all_paths(std::vector &cfg) +{ + std::vector sub_cfg; + struct control_flow_path path; + + setup_check_control_vmx_controls_all_paths(sub_cfg); + setup_check_host_state_all_paths(sub_cfg); + setup_check_guest_state_all_paths(sub_cfg); + + path.setup = [sub_cfg] { + for (const auto &sub_path : sub_cfg) + { + sub_path.setup(); + } + }; + path.throws_exception = false; + cfg.push_back(path); +} +#endif diff --git a/bfvmm/tests/vcpu/CMakeLists.txt b/bfvmm/tests/vcpu/CMakeLists.txt index 52ecc16e8..9f7bf360e 100644 --- a/bfvmm/tests/vcpu/CMakeLists.txt +++ b/bfvmm/tests/vcpu/CMakeLists.txt @@ -16,19 +16,32 @@ # License along with this library; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -macro(do_test str) - add_executable(test_${str} test_${str}.cpp) - target_compile_definitions(test_${str} PRIVATE STATIC_VCPU) - target_link_libraries(test_${str} bfvmm_vcpu_static) - target_link_libraries(test_${str} bfvmm_exit_handler_static) - target_link_libraries(test_${str} bfvmm_vmcs_static) - target_link_libraries(test_${str} bfvmm_vmxon_static) - target_link_libraries(test_${str} bfvmm_memory_manager_static) - target_link_libraries(test_${str} bfvmm_intrinsics_static) - target_link_libraries(test_${str} test_catch) - add_test(test_${str} test_${str}) - install(TARGETS test_${str} DESTINATION ${BUILD_SYSROOT_TEST}/bin/bfvmm) -endmacro(do_test) +list(APPEND ARGN + DEPENDS bfvmm_vcpu + DEPENDS bfvmm_hve + DEPENDS bfvmm_memory_manager + DEFINES STATIC_VCPU + DEFINES STATIC_HVE + DEFINES STATIC_MEMORY_MANAGER + DEFINES STATIC_INTRINSICS +) -do_test(vcpu) -do_test(vcpu_intel_x64) +do_test(test_vcpu + SOURCES test_vcpu.cpp + ${ARGN} +) + +do_test(test_vcpu_manager + SOURCES test_vcpu_manager.cpp + ${ARGN} +) + +do_test(test_vcpu_factory + SOURCES test_vcpu_factory.cpp + ${ARGN} +) + +do_test(test_vcpu_intel_x64 + SOURCES arch/intel_x64/test_vcpu.cpp + ${ARGN} +) diff --git a/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu.cpp b/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu.cpp index d330fa785..e39b1f3cf 100644 --- a/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu.cpp +++ b/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu.cpp @@ -16,195 +16,10 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -#include -#include - -#include - -#include -#include -#include - -#include -using namespace x64; +#include #ifdef _HIPPOMOCKS__ENABLE_CFUNC_MOCKING_SUPPORT -gdt_reg_x64_t test_gdtr{}; -idt_reg_x64_t test_idtr{}; - -std::vector test_gdt = { - 0x0, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF, - 0xFF7FFFFFFFFFFFFF -}; - -std::vector test_idt{512}; - -void -setup_gdt() -{ - auto limit = test_gdt.size() * sizeof(gdt_x64::segment_descriptor_type); - - test_gdtr.base = &test_gdt.at(0); - test_gdtr.limit = gsl::narrow_cast(limit); -} - -void -setup_idt() -{ - auto limit = test_idt.size() * sizeof(idt_x64::interrupt_descriptor_type); - - test_idtr.base = &test_idt.at(0); - test_idtr.limit = gsl::narrow_cast(limit); -} - -static uint64_t -test_read_msr(uint32_t addr) noexcept -{ bfignored(addr); return 0; } - -static uint64_t -test_read_cr0() noexcept -{ return 0; } - -static uint64_t -test_read_cr3() noexcept -{ return 0; } - -static uint64_t -test_read_cr4() noexcept -{ return 0; } - -static uint64_t -test_read_rflags() noexcept -{ return 0; } - -static uint64_t -test_read_dr7() noexcept -{ return 0; } - -static void -test_read_gdt(gdt_reg_x64_t *gdt_reg) noexcept -{ *gdt_reg = test_gdtr; } - -static void -test_read_idt(idt_reg_x64_t *idt_reg) noexcept -{ *idt_reg = test_idtr; } - -static uint16_t -test_read_es() noexcept -{ return 0; } - -static uint16_t -test_read_cs() noexcept -{ return 0; } - -static uint16_t -test_read_ss() noexcept -{ return 0; } - -static uint16_t -test_read_ds() noexcept -{ return 0; } - -static uint16_t -test_read_fs() noexcept -{ return 0; } - -static uint16_t -test_read_gs() noexcept -{ return 0; } - -static uint16_t -test_read_ldtr() noexcept -{ return 0; } - -static uint16_t -test_read_tr() noexcept -{ return 0; } - -static uint32_t -test_cpuid_ecx(uint32_t val) noexcept -{ bfignored(val); return 0x04000000U; } - -static uint32_t -test_cpuid_eax(uint32_t val) noexcept -{ bfignored(val); return 0x00000000U; } - -static uint32_t -test_cpuid_subebx(uint32_t addr, uint32_t leaf) -{ - bfignored(addr); - bfignored(leaf); - - return 0x00000000U; -} - -static void -setup_intrinsics(MockRepository &mocks) -{ - mocks.OnCallFunc(_read_msr).Do(test_read_msr); - mocks.OnCallFunc(_read_cr0).Do(test_read_cr0); - mocks.OnCallFunc(_read_cr3).Do(test_read_cr3); - mocks.OnCallFunc(_read_cr4).Do(test_read_cr4); - mocks.OnCallFunc(_read_rflags).Do(test_read_rflags); - mocks.OnCallFunc(_read_dr7).Do(test_read_dr7); - mocks.OnCallFunc(_read_gdt).Do(test_read_gdt); - mocks.OnCallFunc(_read_idt).Do(test_read_idt); - mocks.OnCallFunc(_read_es).Do(test_read_es); - mocks.OnCallFunc(_read_cs).Do(test_read_cs); - mocks.OnCallFunc(_read_ss).Do(test_read_ss); - mocks.OnCallFunc(_read_ds).Do(test_read_ds); - mocks.OnCallFunc(_read_fs).Do(test_read_fs); - mocks.OnCallFunc(_read_gs).Do(test_read_gs); - mocks.OnCallFunc(_read_ldtr).Do(test_read_ldtr); - mocks.OnCallFunc(_read_tr).Do(test_read_tr); - mocks.OnCallFunc(_cpuid_ecx).Do(test_cpuid_ecx); - mocks.OnCallFunc(_cpuid_eax).Do(test_cpuid_eax); - mocks.OnCallFunc(_cpuid_subebx).Do(test_cpuid_subebx); - - setup_gdt(); - setup_idt(); -} - -static auto -setup_mm(MockRepository &mocks) -{ - auto mm = mocks.Mock(); - mocks.OnCallFunc(memory_manager_x64::instance).Return(mm); - mocks.OnCall(mm, memory_manager_x64::virtptr_to_physint).Return(0x000000ABCDEF0000); - - return mm; -} - -static auto -setup_pt(MockRepository &mocks) -{ - auto pt = mocks.Mock(); - mocks.OnCallFunc(root_pt).Return(pt); - mocks.OnCall(pt, root_page_table_x64::cr3).Return(0x000000ABCDEF0000); - - return pt; -} - -template auto -mock_no_delete(MockRepository &mocks) -{ - auto ptr = mocks.Mock(); - mocks.OnCallDestructor(ptr); - - return ptr; -} - -template auto -mock_unique(MockRepository &mocks) -{ - return std::unique_ptr(mock_no_delete(mocks)); -} - TEST_CASE("vcpu_intel_x64: invalid_id") { CHECK_THROWS(std::make_unique(vcpuid::reserved)); @@ -213,7 +28,8 @@ TEST_CASE("vcpu_intel_x64: invalid_id") TEST_CASE("vcpu_intel_x64: valid") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); auto test = [&] { auto on = mock_unique(mocks); @@ -237,7 +53,8 @@ TEST_CASE("vcpu_intel_x64: valid") TEST_CASE("vcpu_intel_x64: init_null_params") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -256,7 +73,8 @@ TEST_CASE("vcpu_intel_x64: init_null_params") TEST_CASE("vcpu_intel_x64: init_valid_params") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -287,7 +105,8 @@ TEST_CASE("vcpu_intel_x64: init_valid_params") TEST_CASE("vcpu_intel_x64: init_valid") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -318,7 +137,8 @@ TEST_CASE("vcpu_intel_x64: init_valid") TEST_CASE("vcpu_intel_x64: init_vmcs_throws") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -349,7 +169,8 @@ TEST_CASE("vcpu_intel_x64: init_vmcs_throws") TEST_CASE("vcpu_intel_x64: fini_null_params") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -368,7 +189,8 @@ TEST_CASE("vcpu_intel_x64: fini_null_params") TEST_CASE("vcpu_intel_x64: fini_valid_params") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -400,7 +222,8 @@ TEST_CASE("vcpu_intel_x64: fini_valid_params") TEST_CASE("vcpu_intel_x64: fini_valid") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -432,7 +255,8 @@ TEST_CASE("vcpu_intel_x64: fini_valid") TEST_CASE("vcpu_intel_x64: fini_no_init") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -457,7 +281,8 @@ TEST_CASE("vcpu_intel_x64: fini_no_init") TEST_CASE("vcpu_intel_x64: run_launch") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -495,7 +320,8 @@ TEST_CASE("vcpu_intel_x64: run_launch") TEST_CASE("vcpu_intel_x64: run_launch_is_host_vcpu") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -533,7 +359,8 @@ TEST_CASE("vcpu_intel_x64: run_launch_is_host_vcpu") TEST_CASE("vcpu_intel_x64: run_resume") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -572,7 +399,8 @@ TEST_CASE("vcpu_intel_x64: run_resume") TEST_CASE("vcpu_intel_x64: run_no_init") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -609,7 +437,8 @@ TEST_CASE("vcpu_intel_x64: run_no_init") TEST_CASE("vcpu_intel_x64: run_vmxon_throws") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -647,7 +476,8 @@ TEST_CASE("vcpu_intel_x64: run_vmxon_throws") TEST_CASE("vcpu_intel_x64: run_vmcs_throws") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -685,7 +515,8 @@ TEST_CASE("vcpu_intel_x64: run_vmcs_throws") TEST_CASE("vcpu_intel_x64: hlt_no_init") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -722,7 +553,8 @@ TEST_CASE("vcpu_intel_x64: hlt_no_init") TEST_CASE("vcpu_intel_x64: hlt_no_run") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -760,7 +592,8 @@ TEST_CASE("vcpu_intel_x64: hlt_no_run") TEST_CASE("vcpu_intel_x64: hlt_valid") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -799,7 +632,8 @@ TEST_CASE("vcpu_intel_x64: hlt_valid") TEST_CASE("vcpu_intel_x64: hlt_valid_is_host_vcpu") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); @@ -838,7 +672,8 @@ TEST_CASE("vcpu_intel_x64: hlt_valid_is_host_vcpu") TEST_CASE("vcpu_intel_x64: hlt_vmxon_throws") { MockRepository mocks; - setup_intrinsics(mocks); + setup_gdt(); + setup_idt(); setup_mm(mocks); setup_pt(mocks); diff --git a/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu_factory.cpp b/bfvmm/tests/vcpu/test_vcpu_factory.cpp similarity index 84% rename from bfvmm/tests/vcpu/arch/intel_x64/test_vcpu_factory.cpp rename to bfvmm/tests/vcpu/test_vcpu_factory.cpp index 56b2d9d7e..7bb8aa36e 100644 --- a/bfvmm/tests/vcpu/arch/intel_x64/test_vcpu_factory.cpp +++ b/bfvmm/tests/vcpu/test_vcpu_factory.cpp @@ -16,9 +16,18 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include + #include #include +WEAK_SYM std::unique_ptr +vcpu_factory::make_vcpu(vcpuid::type vcpuid, user_data *data) +{ + bfignored(data); + return std::make_unique(vcpuid); +} + TEST_CASE("vcpu_factory: make_vcpu") { vcpu_factory factory; diff --git a/bfvmm/tests/vcpu/test_vcpu_manager.cpp b/bfvmm/tests/vcpu/test_vcpu_manager.cpp index 0f2bf2513..9dc5d0ade 100644 --- a/bfvmm/tests/vcpu/test_vcpu_manager.cpp +++ b/bfvmm/tests/vcpu/test_vcpu_manager.cpp @@ -16,6 +16,8 @@ // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +#include + #include #include @@ -52,6 +54,19 @@ mock_no_delete(MockRepository &mocks) return ptr; } +WEAK_SYM std::unique_ptr +vcpu_factory::make_vcpu(vcpuid::type vcpuid, user_data *data) +{ + bfignored(data); + return std::make_unique(vcpuid); +} + +TEST_CASE("vcpu_manager: support") +{ + vcpu_factory factory{}; + CHECK_NOTHROW(factory.make_vcpu(0, nullptr)); +} + TEST_CASE("vcpu_manager: create_valid") { MockRepository mocks; diff --git a/scripts/cmake/flags/test_flags.cmake b/scripts/cmake/flags/test_flags.cmake index a544920f5..92a6ecd54 100644 --- a/scripts/cmake/flags/test_flags.cmake +++ b/scripts/cmake/flags/test_flags.cmake @@ -28,6 +28,7 @@ list(APPEND BFFLAGS_TEST -D${OSTYPE} -D${ABITYPE} -DENABLE_BUILD_TEST + -DDEBUG_LEVEL=5 ) if(NOT WIN32) diff --git a/scripts/cmake/macros.cmake b/scripts/cmake/macros.cmake index 71c4b0370..270bee8c4 100644 --- a/scripts/cmake/macros.cmake +++ b/scripts/cmake/macros.cmake @@ -217,18 +217,6 @@ function(generate_flags PREFIX) list(APPEND _C_FLAGS ${BFFLAGS_USERSPACE_AARCH64}) list(APPEND _CXX_FLAGS ${BFFLAGS_USERSPACE_AARCH64}) endif() - if(ENABLE_ASAN) - list(APPEND _C_FLAGS ${BFFLAGS_ASAN}) - list(APPEND _CXX_FLAGS ${BFFLAGS_ASAN}) - endif() - if(ENABLE_USAN) - list(APPEND _C_FLAGS ${BFFLAGS_USAN}) - list(APPEND _CXX_FLAGS ${BFFLAGS_USAN}) - endif() - if(ENABLE_CODECOV) - list(APPEND _C_FLAGS ${BFFLAGS_CODECOV}) - list(APPEND _CXX_FLAGS ${BFFLAGS_CODECOV}) - endif() elseif(PREFIX STREQUAL "test") list(APPEND _C_FLAGS ${BFFLAGS_TEST} ${BFFLAGS_TEST_C} ${C_FLAGS_TEST}) list(APPEND _CXX_FLAGS ${BFFLAGS_TEST} ${BFFLAGS_TEST_CXX} ${CXX_FLAGS_TEST})