Merge pull request #951 from rianquinn/master

Fixes bugs with Clang Tidy and adds some more unit tests
This commit is contained in:
Rian Quinn 2021-07-15 15:45:08 -06:00 committed by GitHub
commit abfea7ff60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
646 changed files with 20276 additions and 26584 deletions

View file

@ -23,9 +23,6 @@ Checks:
'
-*,
bsl-*,
-bsl-template-generic-param,
-bsl-literals-user-defined,
-bsl-unused-return-value,
bugprone-*,
-bugprone-branch-clone,
cert-*,
@ -33,6 +30,7 @@ Checks:
-cert-oop54-cpp,
clang-analyzer-*,
-clang-analyzer-core.CallAndMessage,
-clang-analyzer-core.NonNullParamChecker,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-non-const-global-variables,
hicpp-*,

View file

@ -22,7 +22,7 @@
FetchContent_Declare(
bsl
GIT_REPOSITORY https://github.com/bareflank/bsl.git
GIT_TAG 5c3c948d44a0cdeb2477b42c1493d88e3268c40d
GIT_TAG 4eec9e7e478b8c5df6174f882198777394ce45e0
)
FetchContent_GetProperties(bsl)

View file

@ -27,7 +27,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/../init_cross_compile_build.cmake)
add_subdirectory(../../loader loader)
add_subdirectory(../../runtime runtime)
add_subdirectory(../../syscall syscall)
add_subdirectory(../../kernel/integration integration)
# add_subdirectory(../../kernel/integration integration)
if(DEFINED HYPERVISOR_EXTENSIONS_DIR)
add_subdirectory(${HYPERVISOR_EXTENSIONS_DIR} extension)

View file

@ -74,16 +74,8 @@
- [2.12.6. bf_vps_op_create_vps, OP=0x6, IDX=0x0](#2126-bf_vps_op_create_vps-op0x6-idx0x0)
- [2.12.7. bf_vps_op_destroy_vps, OP=0x6, IDX=0x1](#2127-bf_vps_op_destroy_vps-op0x6-idx0x1)
- [2.12.8. bf_vps_op_init_as_root, OP=0x6, IDX=0x2](#2128-bf_vps_op_init_as_root-op0x6-idx0x2)
- [2.12.9. bf_vps_op_read8, OP=0x6, IDX=0x3](#2129-bf_vps_op_read8-op0x6-idx0x3)
- [2.12.10. bf_vps_op_read16, OP=0x6, IDX=0x4](#21210-bf_vps_op_read16-op0x6-idx0x4)
- [2.12.11. bf_vps_op_read32, OP=0x6, IDX=0x5](#21211-bf_vps_op_read32-op0x6-idx0x5)
- [2.12.12. bf_vps_op_read64, OP=0x6, IDX=0x6](#21212-bf_vps_op_read64-op0x6-idx0x6)
- [2.12.13. bf_vps_op_write8, OP=0x6, IDX=0x7](#21213-bf_vps_op_write8-op0x6-idx0x7)
- [2.12.14. bf_vps_op_write16, OP=0x6, IDX=0x8](#21214-bf_vps_op_write16-op0x6-idx0x8)
- [2.12.15. bf_vps_op_write32, OP=0x6, IDX=0x9](#21215-bf_vps_op_write32-op0x6-idx0x9)
- [2.12.16. bf_vps_op_write64, OP=0x6, IDX=0xA](#21216-bf_vps_op_write64-op0x6-idx0xa)
- [2.12.17. bf_vps_op_read_reg, OP=0x6, IDX=0xB](#21217-bf_vps_op_read_reg-op0x6-idx0xb)
- [2.12.18. bf_vps_op_write_reg, OP=0x6, IDX=0xC](#21218-bf_vps_op_write_reg-op0x6-idx0xc)
- [2.12.17. bf_vps_op_read, OP=0x6, IDX=0xB](#21217-bf_vps_op_read-op0x6-idx0xb)
- [2.12.18. bf_vps_op_write, OP=0x6, IDX=0xC](#21218-bf_vps_op_write-op0x6-idx0xc)
- [2.12.19. bf_vps_op_run, OP=0x5, IDX=0xD](#21219-bf_vps_op_run-op0x5-idx0xd)
- [2.12.20. bf_vps_op_run_current, OP=0x5, IDX=0xE](#21220-bf_vps_op_run_current-op0x5-idx0xe)
- [2.12.21. bf_vps_op_advance_ip, OP=0x5, IDX=0xF](#21221-bf_vps_op_advance_ip-op0x5-idx0xf)
@ -641,7 +633,7 @@ The microkernel defines a "thread" the same way both Intel and AMD define a thre
The layout of the TLS block provided to each extension uses a scheme similar to the ELF TLS specification, but with some modifications. Unlike the ELF TLS specification, each TLS block is limited to two pages. The lower half of the page is dedicated to "thread_local" storage. The upper half is defined by this specification, and provides access to registers shared between the microkernel and the extension to improve performance. For example, access to a VM's general purpose registers is available from the TLS block. Each TLS register defined by this specific is an offset into the upper half of the TLS block (which can be located using the fs segment register on Intel/AMD).
**IMPORTANT:**
The general purpose registers are always accessible to an extension to read and write, but it is up to the extension to ensure the correct VPS state is being modified. Accesses to the TLS block modifies the active VPS only. For example, while an extension is executing its bootstrap handler, there is no active VPS, in which case any reads/writes to the general purpose registers from the TLS block will be lost. When an extension is executing from a VMExit handler, reads/writes to the general purpose registers from the TLS block are made to the VPS that generated the VMExit. If an extension then creates a VPS, the only way to modify the general purpose registers for the newly created VPS is through the read_reg/write_reg ABIs. Attempting to use the TLS block will modify the registers for the active VPS, not the newly created VPS. The only way to set a VPS to "active" is to use the run ABI, which on success does not return, meaning the extension has to wait for a VMExit before the newly create VPS's general purpose registers can be accessed from the TLS block.
The general purpose registers are always accessible to an extension to read and write, but it is up to the extension to ensure the correct VPS state is being modified. Accesses to the TLS block modifies the active VPS only. For example, while an extension is executing its bootstrap handler, there is no active VPS, in which case any reads/writes to the general purpose registers from the TLS block will be lost. When an extension is executing from a VMExit handler, reads/writes to the general purpose registers from the TLS block are made to the VPS that generated the VMExit. If an extension then creates a VPS, the only way to modify the general purpose registers for the newly created VPS is through the read/write ABIs. Attempting to use the TLS block will modify the registers for the active VPS, not the newly created VPS. The only way to set a VPS to "active" is to use the run ABI, which on success does not return, meaning the extension has to wait for a VMExit before the newly create VPS's general purpose registers can be accessed from the TLS block.
Although this seems overly complicated, this optimization works well for the majority of the VMExits an extension will have to handle, especially the VMExits that execute frequently as most of the time an extension will only be modifying the general purpose registers for the active VPS.
@ -1095,173 +1087,7 @@ This syscall tells the microkernel to initialize a VPS using the root VP state p
| :---- | :---------- |
| 0x0000000000000002 | Defines the syscall index for bf_vps_op_init_as_root |
### 2.12.9. bf_vps_op_read8, OP=0x6, IDX=0x3
Reads an 8bit field from the VPS and returns the value. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to read from |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to read |
**Output:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 7:0 | The resulting value |
| REG1 | 63:8 | REVI |
**const, bf_uint64_t: BF_VPS_OP_READ8_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000003 | Defines the syscall index for bf_vps_op_read8 |
### 2.12.10. bf_vps_op_read16, OP=0x6, IDX=0x4
Reads a 16bit field from the VPS and returns the value. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to read from |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to read |
**Output:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 15:0 | The resulting value |
| REG1 | 63:16 | REVI |
**const, bf_uint64_t: BF_VPS_OP_READ16_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000004 | Defines the syscall index for bf_vps_op_read16 |
### 2.12.11. bf_vps_op_read32, OP=0x6, IDX=0x5
Reads a 32bit field from the VPS and returns the value. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to read from |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to read |
**Output:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 31:0 | The resulting value |
| REG1 | 63:32 | REVI |
**const, bf_uint64_t: BF_VPS_OP_READ32_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000005 | Defines the syscall index for bf_vps_op_read32 |
### 2.12.12. bf_vps_op_read64, OP=0x6, IDX=0x6
Reads a 64bit field from the VPS and returns the value. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to read from |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to read |
**Output:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | The resulting value |
**const, bf_uint64_t: BF_VPS_OP_READ64_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000006 | Defines the syscall index for bf_vps_op_read64 |
### 2.12.13. bf_vps_op_write8, OP=0x6, IDX=0x7
Writes to an 8bit field in the VPS. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to write |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to write |
| REG3 | 7:0 | The value to write to the requested field |
| REG3 | 63:8 | REVI |
**const, bf_uint64_t: BF_VPS_OP_WRITE8_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000007 | Defines the syscall index for bf_vps_op_write8 |
### 2.12.14. bf_vps_op_write16, OP=0x6, IDX=0x8
Writes to a 16bit field in the VPS. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to write |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to write |
| REG3 | 15:0 | The value to write to the requested field |
| REG3 | 63:16 | REVI |
**const, bf_uint64_t: BF_VPS_OP_WRITE16_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000008 | Defines the syscall index for bf_vps_op_write16 |
### 2.12.15. bf_vps_op_write32, OP=0x6, IDX=0x9
Writes to a 32bit field in the VPS. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to write |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to write |
| REG3 | 7:0 | The value to write to the requested field |
| REG3 | 63:32 | REVI |
**const, bf_uint64_t: BF_VPS_OP_WRITE32_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x0000000000000009 | Defines the syscall index for bf_vps_op_write32 |
### 2.12.16. bf_vps_op_write64, OP=0x6, IDX=0xA
Writes to a 64bit field in the VPS. The "index" is architecture-specific. For Intel, Appendix B, "Field Encoding in VMCS," defines the index (or encoding). For AMD, Appendix B, "Layout of VMCB," defines the index (or offset).
**Input:**
| Register Name | Bits | Description |
| :------------ | :--- | :---------- |
| REG0 | 63:0 | Set to the result of bf_handle_op_open_handle |
| REG1 | 15:0 | The VPSID of the VPS to write |
| REG1 | 63:16 | REVI |
| REG2 | 63:0 | The HVE specific index defining which field to write |
| REG3 | 63:0 | The value to write to the requested field |
**const, bf_uint64_t: BF_VPS_OP_WRITE64_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x000000000000000A | Defines the syscall index for bf_vps_op_write64 |
### 2.12.17. bf_vps_op_read_reg, OP=0x6, IDX=0xB
### 2.12.17. bf_vps_op_read, OP=0x6, IDX=0xB
Reads a CPU register from the VPS given a bf_reg_t. Note that the bf_reg_t is architecture-specific.
@ -1278,12 +1104,12 @@ Reads a CPU register from the VPS given a bf_reg_t. Note that the bf_reg_t is ar
| :------------ | :--- | :---------- |
| REG0 | 63:0 | The resulting value |
**const, bf_uint64_t: BF_VPS_OP_READ_REG_IDX_VAL**
**const, bf_uint64_t: BF_VPS_OP_READ_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x000000000000000B | Defines the syscall index for bf_vps_op_read_reg |
| 0x000000000000000B | Defines the syscall index for bf_vps_op_read |
### 2.12.18. bf_vps_op_write_reg, OP=0x6, IDX=0xC
### 2.12.18. bf_vps_op_write, OP=0x6, IDX=0xC
Writes to a CPU register in the VPS given a bf_reg_t and the value to write. Note that the bf_reg_t is architecture-specific.
@ -1296,10 +1122,10 @@ Writes to a CPU register in the VPS given a bf_reg_t and the value to write. Not
| REG2 | 63:0 | A bf_reg_t defining which register to write to |
| REG3 | 63:0 | The value to write to the requested register |
**const, bf_uint64_t: BF_VPS_OP_WRITE_REG_IDX_VAL**
**const, bf_uint64_t: BF_VPS_OP_WRITE_IDX_VAL**
| Value | Description |
| :---- | :---------- |
| 0x000000000000000C | Defines the syscall index for bf_vps_op_write_reg |
| 0x000000000000000C | Defines the syscall index for bf_vps_op_write |
### 2.12.19. bf_vps_op_run, OP=0x5, IDX=0xD

View file

@ -19,5 +19,30 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
bf_add_test(requirements INCLUDES ${COMMON_INCLUDES} SYSTEM_INCLUDES ${COMMON_SYSTEM_INCLUDES} DEFINES ${DEFINES})
bf_add_test(behavior INCLUDES ${COMMON_INCLUDES} SYSTEM_INCLUDES ${COMMON_SYSTEM_INCLUDES} DEFINES ${DEFINES})
Checks:
'
-*,
bsl-*,
bugprone-*,
-bugprone-branch-clone,
cert-*,
-cert-dcl21-cpp,
-cert-oop54-cpp,
clang-analyzer-*,
cppcoreguidelines-*,
hicpp-*,
misc-*,
-misc-misplaced-const,
modernize-*,
-modernize-use-default-member-init,
performance-*,
readability-*,
-readability-redundant-member-init,
-readability-avoid-const-params-in-decls,
-readability-static-accessed-through-instance
'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'
AnalyzeTemporaryDtors: false
FormatStyle: none
UseColor: true

View file

@ -69,17 +69,7 @@ endmacro(example_target_source)
# macros in the code.
#
target_include_directories(example_default PRIVATE
include
src
)
if(HYPERVISOR_TARGET_ARCH STREQUAL "AuthenticAMD" OR HYPERVISOR_TARGET_ARCH STREQUAL "GenuineIntel")
target_include_directories(example_default PRIVATE
include/x64
src/x64
)
if(HYPERVISOR_TARGET_ARCH STREQUAL "AuthenticAMD")
target_include_directories(example_default PRIVATE
include/x64/amd
@ -93,6 +83,11 @@ if(HYPERVISOR_TARGET_ARCH STREQUAL "AuthenticAMD" OR HYPERVISOR_TARGET_ARCH STRE
src/x64/intel
)
endif()
target_include_directories(example_default PRIVATE
include/x64
src/x64
)
endif()
if(HYPERVISOR_TARGET_ARCH STREQUAL "aarch64")
@ -102,6 +97,11 @@ if(HYPERVISOR_TARGET_ARCH STREQUAL "aarch64")
)
endif()
target_include_directories(example_default PRIVATE
include
src
)
# ------------------------------------------------------------------------------
# Headers
# ------------------------------------------------------------------------------

View file

@ -67,12 +67,12 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -111,12 +111,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -144,12 +144,12 @@ namespace example
///
[[nodiscard]] constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{
bsl::discard(gs);

View file

@ -66,12 +66,12 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -110,12 +110,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -143,12 +143,12 @@ namespace example
///
[[nodiscard]] constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid,
bsl::safe_uint64 const &fail_reason) noexcept -> bsl::errc_type
{

View file

@ -56,7 +56,7 @@ namespace example
/// and friends otherwise
///
[[nodiscard]] constexpr auto
initialize(gs_t &gs, tls_t &tls) noexcept -> bsl::errc_type
initialize(gs_t const &gs, tls_t const &tls) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -86,7 +86,7 @@ namespace example
/// @param tls the tls_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls) noexcept
release(gs_t const &gs, tls_t const &tls) noexcept
{
bsl::discard(gs);
bsl::discard(tls);

View file

@ -67,12 +67,12 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -111,12 +111,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -143,12 +143,12 @@ namespace example
///
[[nodiscard]] constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid,
bsl::safe_uint64 const &exit_reason) noexcept -> bsl::errc_type
{

View file

@ -62,8 +62,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
-> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -97,7 +99,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -120,10 +126,10 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vmid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::safe_uint16
{

View file

@ -58,10 +58,10 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -82,7 +82,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -105,10 +109,10 @@ namespace example
///
[[nodiscard]] static constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vmid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{

View file

@ -62,8 +62,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
-> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -97,7 +99,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -120,10 +126,10 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vpid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::safe_uint16
{

View file

@ -58,10 +58,10 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -82,7 +82,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -105,10 +109,10 @@ namespace example
///
[[nodiscard]] static constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vpid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{

View file

@ -65,7 +65,7 @@ namespace example
/// and friends otherwise
///
[[nodiscard]] constexpr auto
initialize(gs_t &gs, tls_t &tls) noexcept -> bsl::errc_type
initialize(gs_t const &gs, tls_t const &tls) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -95,7 +95,7 @@ namespace example
/// @param tls the tls_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls) noexcept
release(gs_t const &gs, tls_t const &tls) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -108,29 +108,29 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param mut_rax the index used by CPUID, returns resulting rax
/// @param mut_rbx returns resulting rbx
/// @param mut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param mut_rdx returns resulting rdx
///
constexpr void
cpuid(
gs_t &gs,
tls_t &tls,
bsl::safe_uint64 &rax,
bsl::safe_uint64 &rbx,
bsl::safe_uint64 &rcx,
bsl::safe_uint64 &rdx) noexcept
gs_t const &gs,
tls_t const &tls,
bsl::safe_uint64 &mut_rax,
bsl::safe_uint64 &mut_rbx,
bsl::safe_uint64 &mut_rcx,
bsl::safe_uint64 &mut_rdx) const noexcept
{
bsl::discard(gs);
bsl::discard(tls);
constexpr auto mask{0xFFFFFFFF00000000_u64};
rax = ((rax & mask) | bsl::to_u64(m_eax));
rbx = ((rbx & mask) | bsl::to_u64(m_ebx));
rcx = ((rcx & mask) | bsl::to_u64(m_ecx));
rdx = ((rdx & mask) | bsl::to_u64(m_edx));
mut_rax = ((mut_rax & mask) | bsl::to_u64(m_eax));
mut_rbx = ((mut_rbx & mask) | bsl::to_u64(m_ebx));
mut_rcx = ((mut_rcx & mask) | bsl::to_u64(m_ecx));
mut_rdx = ((mut_rdx & mask) | bsl::to_u64(m_edx));
}
/// <!-- description -->

View file

@ -65,7 +65,7 @@ namespace example
/// and friends otherwise
///
[[nodiscard]] constexpr auto
initialize(gs_t &gs, tls_t &tls) noexcept -> bsl::errc_type
initialize(gs_t const &gs, tls_t const &tls) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -95,7 +95,7 @@ namespace example
/// @param tls the tls_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls) noexcept
release(gs_t const &gs, tls_t const &tls) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -108,29 +108,29 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param mut_rax the index used by CPUID, returns resulting rax
/// @param mut_rbx returns resulting rbx
/// @param mut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param mut_rdx returns resulting rdx
///
constexpr void
cpuid(
gs_t &gs,
tls_t &tls,
bsl::safe_uint64 &rax,
bsl::safe_uint64 &rbx,
bsl::safe_uint64 &rcx,
bsl::safe_uint64 &rdx) noexcept
gs_t const &gs,
tls_t const &tls,
bsl::safe_uint64 &mut_rax,
bsl::safe_uint64 &mut_rbx,
bsl::safe_uint64 &mut_rcx,
bsl::safe_uint64 &mut_rdx) const noexcept
{
bsl::discard(gs);
bsl::discard(tls);
constexpr auto mask{0xFFFFFFFF00000000_u64};
rax = ((rax & mask) | bsl::to_u64(m_eax));
rbx = ((rbx & mask) | bsl::to_u64(m_ebx));
rcx = ((rcx & mask) | bsl::to_u64(m_ecx));
rdx = ((rdx & mask) | bsl::to_u64(m_edx));
mut_rax = ((mut_rax & mask) | bsl::to_u64(m_eax));
mut_rbx = ((mut_rbx & mask) | bsl::to_u64(m_ebx));
mut_rcx = ((mut_rcx & mask) | bsl::to_u64(m_ecx));
mut_rdx = ((mut_rdx & mask) | bsl::to_u64(m_edx));
}
/// <!-- description -->

View file

@ -41,48 +41,48 @@ namespace example
///
/// <!-- inputs/outputs -->
/// @param gs a pointer to the global storage to use
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param pmut_rax the index used by CPUID, returns resulting rax
/// @param pmut_rbx returns resulting rbx
/// @param pmut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param pmut_rdx returns resulting rdx
///
extern "C" constexpr void
intrinsic_cpuid_impl(
gs_t *const gs,
bsl::uint64 *const rax,
bsl::uint64 *const rbx,
bsl::uint64 *const rcx,
bsl::uint64 *const rdx) noexcept
gs_t const *const gs,
bsl::uint64 *const pmut_rax,
bsl::uint64 *const pmut_rbx,
bsl::uint64 *const pmut_rcx,
bsl::uint64 *const pmut_rdx) noexcept
{
if (bsl::unlikely_assert(nullptr == gs)) {
bsl::alert() << "gs is null\n" << bsl::here();
return;
}
if (bsl::unlikely_assert(nullptr == rax)) {
bsl::alert() << "rax is null\n" << bsl::here();
if (bsl::unlikely_assert(nullptr == pmut_rax)) {
bsl::alert() << "pmut_rax is null\n" << bsl::here();
return;
}
if (bsl::unlikely_assert(nullptr == rbx)) {
bsl::alert() << "rbx is null\n" << bsl::here();
if (bsl::unlikely_assert(nullptr == pmut_rbx)) {
bsl::alert() << "pmut_rbx is null\n" << bsl::here();
return;
}
if (bsl::unlikely_assert(nullptr == rcx)) {
bsl::alert() << "rcx is null\n" << bsl::here();
if (bsl::unlikely_assert(nullptr == pmut_rcx)) {
bsl::alert() << "pmut_rcx is null\n" << bsl::here();
return;
}
if (bsl::unlikely_assert(nullptr == rdx)) {
bsl::alert() << "rdx is null\n" << bsl::here();
if (bsl::unlikely_assert(nullptr == pmut_rdx)) {
bsl::alert() << "pmut_rdx is null\n" << bsl::here();
return;
}
*rax = gs->cpuid_val.get();
*rbx = gs->cpuid_val.get();
*rcx = gs->cpuid_val.get();
*rdx = gs->cpuid_val.get();
*pmut_rax = gs->cpuid_val.get();
*pmut_rbx = gs->cpuid_val.get();
*pmut_rcx = gs->cpuid_val.get();
*pmut_rdx = gs->cpuid_val.get();
}
}

View file

@ -68,10 +68,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -137,7 +137,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -169,8 +173,8 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
bsl::safe_uint16 const &vpid,

View file

@ -64,12 +64,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -99,12 +99,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -127,22 +127,22 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
/// @param mut_vp_pool the vp_pool_t to use
/// @param mut_vps_pool the vps_pool_t to use
/// @param ppid the ID of the PP to bootstrap
/// @return Returns bsl::errc_success on success, bsl::errc_failure
/// and friends otherwise
///
[[nodiscard]] static constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t &mut_vp_pool,
vps_pool_t &mut_vps_pool,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{
/// NOTE:
@ -166,13 +166,13 @@ namespace example
/// the VMCS/VMCB and other CPU register state that is needed.
///
auto const vpid{vp_pool.allocate(gs, tls, sys, intrinsic, vmid, ppid)};
auto const vpid{mut_vp_pool.allocate(gs, tls, mut_sys, intrinsic, vmid, ppid)};
if (bsl::unlikely_assert(!vpid)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
auto const vpsid{vps_pool.allocate(gs, tls, sys, intrinsic, vpid, ppid)};
auto const vpsid{mut_vps_pool.allocate(gs, tls, mut_sys, intrinsic, vpid, ppid)};
if (bsl::unlikely_assert(!vpsid)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
@ -185,7 +185,7 @@ namespace example
/// hypervisor, or switching the VM, VP or VPS as it is slow.
///
return sys.bf_vps_op_run(vmid, vpid, vpsid);
return mut_sys.bf_vps_op_run(vmid, vpid, vpsid);
}
};
}

View file

@ -61,12 +61,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -96,12 +96,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -134,12 +134,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid,
bsl::safe_uint64 const &fail_reason) noexcept -> bsl::errc_type
{

View file

@ -73,26 +73,35 @@ namespace example
///
/// @brief stores the bf_syscall_t that this code will use
constinit syscall::bf_syscall_t g_sys{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit syscall::bf_syscall_t g_mut_sys{};
/// @brief stores the intrinsic_t that this code will use
constinit intrinsic_t g_intrinsic{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit intrinsic_t g_mut_intrinsic{};
/// @brief stores the pool of VPs that we will use
constinit vp_pool_t g_vp_pool{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit vp_pool_t g_mut_vp_pool{};
/// @brief stores the pool of VPSs that we will use
constinit vps_pool_t g_vps_pool{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit vps_pool_t g_mut_vps_pool{};
/// @brief stores the bootstrap_t that this code will use
constinit bootstrap_t g_bootstrap{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit bootstrap_t g_mut_bootstrap{};
/// @brief stores the fail_t that this code will use
constinit fail_t g_fail{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit fail_t g_mut_fail{};
/// @brief stores the vmexit_t that this code will use
constinit vmexit_t g_vmexit{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit vmexit_t g_mut_vmexit{};
/// @brief stores the Global Storage for this extension
constinit gs_t g_gs{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
constinit gs_t g_mut_gs{};
/// @brief stores the Thread Local Storage for this extension on this PP
thread_local tls_t g_tls{};
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
thread_local tls_t g_mut_tls{};
/// <!-- description -->
/// @brief Implements the bootstrap entry function. This function is
@ -104,8 +113,6 @@ namespace example
extern "C" void
bootstrap_entry(syscall::bf_uint16_t::value_type const ppid) noexcept
{
bsl::errc_type ret{};
/// NOTE:
/// - Call into the bootstrap handler. This entry point serves as a
/// trampoline between C and C++. Specifically, the microkernel
@ -113,14 +120,14 @@ namespace example
/// a C style function.
///
ret = g_bootstrap.dispatch( // --
g_gs, // --
g_tls, // --
g_sys, // --
g_intrinsic, // --
g_vp_pool, // --
g_vps_pool, // --
ppid);
auto const ret{g_mut_bootstrap.dispatch( // --
g_mut_gs, // --
g_mut_tls, // --
g_mut_sys, // --
g_mut_intrinsic, // --
g_mut_vp_pool, // --
g_mut_vps_pool, // --
bsl::to_u16(ppid))};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
@ -150,8 +157,6 @@ namespace example
syscall::bf_uint16_t::value_type const vpsid,
syscall::bf_status_t::value_type const fail_reason) noexcept
{
bsl::errc_type ret{};
/// NOTE:
/// - Call into the fast fail handler. This entry point serves as a
/// trampoline between C and C++. Specifically, the microkernel
@ -159,15 +164,15 @@ namespace example
/// a C style function.
///
ret = g_fail.dispatch( // --
g_gs, // --
g_tls, // --
g_sys, // --
g_intrinsic, // --
g_vp_pool, // --
g_vps_pool, // --
vpsid, // --
fail_reason);
auto const ret{g_mut_fail.dispatch( // --
g_mut_gs, // --
g_mut_tls, // --
g_mut_sys, // --
g_mut_intrinsic, // --
g_mut_vp_pool, // --
g_mut_vps_pool, // --
bsl::to_u16(vpsid), // --
bsl::to_u64(fail_reason))};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
@ -197,8 +202,6 @@ namespace example
syscall::bf_uint16_t::value_type const vpsid,
syscall::bf_uint64_t::value_type const exit_reason) noexcept
{
bsl::errc_type ret{};
/// NOTE:
/// - Call into the vmexit handler. This entry point serves as a
/// trampoline between C and C++. Specifically, the microkernel
@ -206,15 +209,15 @@ namespace example
/// a C style function.
///
ret = g_vmexit.dispatch( // --
g_gs, // --
g_tls, // --
g_sys, // --
g_intrinsic, // --
g_vp_pool, // --
g_vps_pool, // --
vpsid, // --
exit_reason);
auto const ret{g_mut_vmexit.dispatch( // --
g_mut_gs, // --
g_mut_tls, // --
g_mut_sys, // --
g_mut_intrinsic, // --
g_mut_vp_pool, // --
g_mut_vps_pool, // --
bsl::to_u16(vpsid), // --
bsl::to_u64(exit_reason))};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
@ -242,7 +245,7 @@ namespace example
extern "C" void
ext_main_entry(bsl::uint32 const version) noexcept
{
bsl::errc_type ret{};
bsl::errc_type mut_ret{};
/// NOTE:
/// - Initialize the bf_syscall_t. This will validate the ABI version,
@ -252,19 +255,24 @@ namespace example
/// always the same.
///
ret = g_sys.initialize(version, &bootstrap_entry, &vmexit_entry, &fail_entry);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_sys.initialize( // --
bsl::to_u32(version), // --
&bootstrap_entry, // --
&vmexit_entry, // --
&fail_entry); // --
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
/// NOTE:
/// - Initialize the g_intrinsic. This can be used to add any init
/// - Initialize the g_mut_intrinsic. This can be used to add any init
/// logic that might be needed, otherwise it can be removed.
///
ret = g_intrinsic.initialize(g_gs, g_tls);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_intrinsic.initialize(g_mut_gs, g_mut_tls);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
@ -274,8 +282,8 @@ namespace example
/// their IDs so that they can be allocated.
///
ret = g_vp_pool.initialize(g_gs, g_tls, g_sys, g_intrinsic);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_vp_pool.initialize(g_mut_gs, g_mut_tls, g_mut_sys, g_mut_intrinsic);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
@ -285,41 +293,44 @@ namespace example
/// their IDs so that they can be allocated.
///
ret = g_vps_pool.initialize(g_gs, g_tls, g_sys, g_intrinsic);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_vps_pool.initialize(g_mut_gs, g_mut_tls, g_mut_sys, g_mut_intrinsic);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
/// NOTE:
/// - Initialize the g_bootstrap. This can be used to add any init
/// - Initialize the g_mut_bootstrap. This can be used to add any init
/// logic that might be needed, otherwise it can be removed.
///
ret = g_bootstrap.initialize(g_gs, g_tls, g_sys, g_intrinsic, g_vp_pool, g_vps_pool);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_bootstrap.initialize(
g_mut_gs, g_mut_tls, g_mut_sys, g_mut_intrinsic, g_mut_vp_pool, g_mut_vps_pool);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
/// NOTE:
/// - Initialize the g_fail. This can be used to add any init
/// - Initialize the g_mut_fail. This can be used to add any init
/// logic that might be needed, otherwise it can be removed.
///
ret = g_fail.initialize(g_gs, g_tls, g_sys, g_intrinsic, g_vp_pool, g_vps_pool);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_fail.initialize(
g_mut_gs, g_mut_tls, g_mut_sys, g_mut_intrinsic, g_mut_vp_pool, g_mut_vps_pool);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}
/// NOTE:
/// - Initialize the g_vmexit. This can be used to add any init
/// - Initialize the g_mut_vmexit. This can be used to add any init
/// logic that might be needed, otherwise it can be removed.
///
ret = g_vmexit.initialize(g_gs, g_tls, g_sys, g_intrinsic, g_vp_pool, g_vps_pool);
if (bsl::unlikely_assert(!ret)) {
mut_ret = g_mut_vmexit.initialize(
g_mut_gs, g_mut_tls, g_mut_sys, g_mut_intrinsic, g_mut_vp_pool, g_mut_vps_pool);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return syscall::bf_control_op_exit();
}

View file

@ -67,8 +67,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
-> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept -> bsl::errc_type
{
/// NOTE:
/// - The following is used in the event of an error. Basically,
@ -77,7 +79,7 @@ namespace example
/// ignore() function, which we do at the end when all is good.
///
bsl::finally_assert release_on_error{
bsl::finally_assert mut_release_on_error{
[this, &gs, &tls, &sys, &intrinsic]() noexcept -> void {
this->release(gs, tls, sys, intrinsic);
}};
@ -91,9 +93,9 @@ namespace example
/// and it allows us to create more if needed.
///
bsl::errc_type ret{};
for (bsl::safe_uintmax i{}; i < m_pool.size(); ++i) {
ret = m_pool.at_if(i)->initialize(gs, tls, sys, intrinsic, bsl::to_u16(i));
for (bsl::safe_uintmax mut_i{}; mut_i < m_pool.size(); ++mut_i) {
auto const ret{
m_pool.at_if(mut_i)->initialize(gs, tls, sys, intrinsic, bsl::to_u16(mut_i))};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
@ -108,7 +110,7 @@ namespace example
bsl::touch();
}
release_on_error.ignore();
mut_release_on_error.ignore();
return bsl::errc_success;
}
@ -122,15 +124,19 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
/// NOTE:
/// - Release functions are usually only needed in the event of
/// an error, or during unit testing.
///
for (bsl::safe_uintmax i{}; i < m_pool.size(); ++i) {
m_pool.at_if(i)->release(gs, tls, sys, intrinsic);
for (bsl::safe_uintmax mut_i{}; mut_i < m_pool.size(); ++mut_i) {
m_pool.at_if(mut_i)->release(gs, tls, sys, intrinsic);
}
}
@ -140,7 +146,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vmid the ID of the VM to assign the newly created VP to
/// @param ppid the ID of the PP to assign the newly created VP to
@ -149,16 +155,13 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vmid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::safe_uint16
{
bsl::errc_type ret{};
bsl::safe_uint16 vpid{};
/// NOTE:
/// - Ask the microkernel to create a VP and return the ID of the
/// newly created VP. We do not check in this function if the
@ -168,7 +171,7 @@ namespace example
/// them to another function.
///
vpid = sys.bf_vp_op_create_vp(vmid, ppid);
auto const vpid{mut_sys.bf_vp_op_create_vp(vmid, ppid)};
if (bsl::unlikely_assert(!vpid)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::safe_uint16::failure();
@ -181,8 +184,8 @@ namespace example
/// ignore() function, which we do at the end when all is good.
///
bsl::finally destroy_vp_on_error{[&sys, &vpid]() noexcept -> void {
bsl::discard(sys.bf_vp_op_destroy_vp(vpid));
bsl::finally mut_destroy_vp_on_error{[&mut_sys, &vpid]() noexcept -> void {
bsl::discard(mut_sys.bf_vp_op_destroy_vp(vpid));
}};
/// NOTE:
@ -192,8 +195,8 @@ namespace example
/// the microkernel did not use the same max limits.
///
auto *const vp{m_pool.at_if(bsl::to_umax(vpid))};
if (bsl::unlikely(nullptr == vp)) {
auto *const pmut_vp{m_pool.at_if(bsl::to_umax(vpid))};
if (bsl::unlikely(nullptr == pmut_vp)) {
bsl::error() << "vpid " // --
<< bsl::hex(vpid) // --
<< " provided by the microkernel is invalid" // --
@ -213,13 +216,13 @@ namespace example
/// more than once.
///
ret = vp->allocate(gs, tls, sys, intrinsic, vmid, ppid);
auto const ret{pmut_vp->allocate(gs, tls, mut_sys, intrinsic, vmid, ppid)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::safe_uint16::failure();
}
destroy_vp_on_error.ignore();
mut_destroy_vp_on_error.ignore();
return vpid;
}
};

View file

@ -67,10 +67,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -136,7 +136,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -168,10 +172,10 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vmid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{

View file

@ -67,8 +67,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
-> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept -> bsl::errc_type
{
/// NOTE:
/// - The following is used in the event of an error. Basically,
@ -77,7 +79,7 @@ namespace example
/// ignore() function, which we do at the end when all is good.
///
bsl::finally_assert release_on_error{
bsl::finally_assert mut_release_on_error{
[this, &gs, &tls, &sys, &intrinsic]() noexcept -> void {
this->release(gs, tls, sys, intrinsic);
}};
@ -91,9 +93,9 @@ namespace example
/// and it allows us to create more if needed.
///
bsl::errc_type ret{};
for (bsl::safe_uintmax i{}; i < m_pool.size(); ++i) {
ret = m_pool.at_if(i)->initialize(gs, tls, sys, intrinsic, bsl::to_u16(i));
for (bsl::safe_uintmax mut_i{}; mut_i < m_pool.size(); ++mut_i) {
auto const ret{
m_pool.at_if(mut_i)->initialize(gs, tls, sys, intrinsic, bsl::to_u16(mut_i))};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
@ -108,7 +110,7 @@ namespace example
bsl::touch();
}
release_on_error.ignore();
mut_release_on_error.ignore();
return bsl::errc_success;
}
@ -122,15 +124,19 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
/// NOTE:
/// - Release functions are usually only needed in the event of
/// an error, or during unit testing.
///
for (bsl::safe_uintmax i{}; i < m_pool.size(); ++i) {
m_pool.at_if(i)->release(gs, tls, sys, intrinsic);
for (bsl::safe_uintmax mut_i{}; mut_i < m_pool.size(); ++mut_i) {
m_pool.at_if(mut_i)->release(gs, tls, sys, intrinsic);
}
}
@ -140,7 +146,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vpid the ID of the VP to assign the newly created VPS to
/// @param ppid the ID of the PP to assign the newly created VPS to
@ -149,16 +155,13 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vpid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::safe_uint16
{
bsl::errc_type ret{};
bsl::safe_uint16 vpsid{};
/// NOTE:
/// - Ask the microkernel to create a VPS and return the ID of the
/// newly created VPS. We do not check in this function if the
@ -168,7 +171,7 @@ namespace example
/// them to another function.
///
vpsid = sys.bf_vps_op_create_vps(vpid, ppid);
auto const vpsid{mut_sys.bf_vps_op_create_vps(vpid, ppid)};
if (bsl::unlikely_assert(!vpsid)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::safe_uint16::failure();
@ -181,8 +184,8 @@ namespace example
/// ignore() function, which we do at the end when all is good.
///
bsl::finally destroy_vps_on_error{[&sys, &vpsid]() noexcept -> void {
bsl::discard(sys.bf_vps_op_destroy_vps(vpsid));
bsl::finally mut_destroy_vps_on_error{[&mut_sys, &vpsid]() noexcept -> void {
bsl::discard(mut_sys.bf_vps_op_destroy_vps(vpsid));
}};
/// NOTE:
@ -192,8 +195,8 @@ namespace example
/// the microkernel did not use the same max limits.
///
auto *const vps{m_pool.at_if(bsl::to_umax(vpsid))};
if (bsl::unlikely(nullptr == vps)) {
auto *const pmut_vps{m_pool.at_if(bsl::to_umax(vpsid))};
if (bsl::unlikely(nullptr == pmut_vps)) {
bsl::error() << "vpsid " // --
<< bsl::hex(vpsid) // --
<< " provided by the microkernel is invalid" // --
@ -213,13 +216,13 @@ namespace example
/// more than once.
///
ret = vps->allocate(gs, tls, sys, intrinsic, vpid, ppid);
auto const ret{pmut_vps->allocate(gs, tls, mut_sys, intrinsic, vpid, ppid)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::safe_uint16::failure();
}
destroy_vps_on_error.ignore();
mut_destroy_vps_on_error.ignore();
return vpsid;
}
};

View file

@ -55,7 +55,7 @@ namespace example
/// and friends otherwise
///
[[nodiscard]] static constexpr auto
initialize(gs_t &gs, tls_t &tls) noexcept -> bsl::errc_type
initialize(gs_t const &gs, tls_t const &tls) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -76,7 +76,7 @@ namespace example
/// @param tls the tls_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls) noexcept
release(gs_t const &gs, tls_t const &tls) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -94,22 +94,23 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param mut_rax the index used by CPUID, returns resulting rax
/// @param mut_rbx returns resulting rbx
/// @param mut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param mut_rdx returns resulting rdx
///
static constexpr void
cpuid(
gs_t &gs,
tls_t &tls,
bsl::safe_uint64 &rax,
bsl::safe_uint64 &rbx,
bsl::safe_uint64 &rcx,
bsl::safe_uint64 &rdx) noexcept
gs_t const &gs,
tls_t const &tls,
bsl::safe_uint64 &mut_rax,
bsl::safe_uint64 &mut_rbx,
bsl::safe_uint64 &mut_rcx,
bsl::safe_uint64 &mut_rdx) noexcept
{
bsl::discard(tls);
intrinsic_cpuid_impl(&gs, rax.data(), rbx.data(), rcx.data(), rdx.data());
intrinsic_cpuid_impl(
&gs, mut_rax.data(), mut_rbx.data(), mut_rcx.data(), mut_rdx.data());
}
};
}

View file

@ -65,12 +65,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -100,12 +100,12 @@ namespace example
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -126,7 +126,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -136,19 +136,17 @@ namespace example
///
[[nodiscard]] static constexpr auto
handle_cpuid(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid) noexcept -> bsl::errc_type
{
bsl::discard(vp_pool);
bsl::discard(vps_pool);
bsl::errc_type ret{};
/// NOTE:
/// - The first thing that we need to do is get the current values
/// of RAX, RBX, RCX and RDX. We use the full 64bit versions to
@ -157,10 +155,10 @@ namespace example
/// correctly.
///
auto rax{sys.bf_tls_rax()};
auto rbx{sys.bf_tls_rbx()};
auto rcx{sys.bf_tls_rcx()};
auto rdx{sys.bf_tls_rdx()};
auto mut_rax{mut_sys.bf_tls_rax()};
auto mut_rbx{mut_sys.bf_tls_rbx()};
auto mut_rcx{mut_sys.bf_tls_rcx()};
auto mut_rdx{mut_sys.bf_tls_rdx()};
/// NOTE:
/// - Before we execute CPUID, we need to check to see if we have
@ -168,8 +166,8 @@ namespace example
/// CPUID differently.
///
if (loader::CPUID_COMMAND_EAX == bsl::to_u32_unsafe(rax)) {
switch (bsl::to_u32_unsafe(rcx).get()) {
if (loader::CPUID_COMMAND_EAX == bsl::to_u32_unsafe(mut_rax)) {
switch (bsl::to_u32_unsafe(mut_rcx).get()) {
case loader::CPUID_COMMAND_ECX_STOP.get(): {
/// NOTE:
@ -181,7 +179,7 @@ namespace example
/// being over used.
///
if (sys.bf_tls_ppid() == (sys.bf_tls_online_pps() - 1_u16)) {
if (mut_sys.bf_tls_ppid() == (mut_sys.bf_tls_online_pps() - 1_u16)) {
bsl::print() << bsl::endl;
syscall::bf_debug_op_dump_page_pool();
bsl::print() << bsl::endl;
@ -202,9 +200,9 @@ namespace example
/// to decode anything, so that is up to you.
///
if constexpr (BSL_DEBUG_LEVEL > bsl::V) {
if constexpr (bsl::debug_level_is_at_least_vv()) {
bsl::print() << bsl::endl;
syscall::bf_debug_op_dump_vmexit_log(sys.bf_tls_ppid());
syscall::bf_debug_op_dump_vmexit_log(mut_sys.bf_tls_ppid());
}
/// NOTE:
@ -219,17 +217,17 @@ namespace example
/// it is "done", because it might fail.
///
bsl::debug() << bsl::rst << "about to" // --
<< bsl::red << " promote " // --
<< bsl::rst << "root OS on pp " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
bsl::debug() << bsl::rst << "about to" // --
<< bsl::red << " promote " // --
<< bsl::rst << "root OS on pp " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
/// NOTE:
/// - Report success
///
sys.bf_tls_set_rax(loader::CPUID_COMMAND_RAX_SUCCESS);
mut_sys.bf_tls_set_rax(loader::CPUID_COMMAND_RAX_SUCCESS);
/// NOTE:
/// - Before we can stop, we need to advance RIP.
@ -239,7 +237,7 @@ namespace example
/// exit before then so we need to advance now.
///
ret = sys.bf_vps_op_advance_ip(vpsid);
auto const ret{mut_sys.bf_vps_op_advance_ip(vpsid)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
@ -254,7 +252,7 @@ namespace example
/// hypervisor turned off.
///
return sys.bf_vps_op_promote(vpsid);
return mut_sys.bf_vps_op_promote(vpsid);
}
case loader::CPUID_COMMAND_ECX_REPORT_ON.get(): {
@ -265,13 +263,13 @@ namespace example
/// want here, this is just the default behavior.
///
bsl::debug() << bsl::rst << "root OS had been" // --
<< bsl::grn << " demoted " // --
<< bsl::rst << "to vm " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_vmid()) // --
<< bsl::rst << " on pp " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
bsl::debug() << bsl::rst << "root OS had been" // --
<< bsl::grn << " demoted " // --
<< bsl::rst << "to vm " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_vmid()) // --
<< bsl::rst << " on pp " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
break;
}
@ -292,7 +290,7 @@ namespace example
default: {
bsl::error() << "unsupported cpuid command " // --
<< bsl::hex(rcx) // --
<< bsl::hex(mut_rcx) // --
<< bsl::endl // --
<< bsl::here(); // --
@ -305,7 +303,7 @@ namespace example
/// the currently loaded VM, VP and VPS.
///
return sys.bf_vps_op_advance_ip_and_run_current();
return mut_sys.bf_vps_op_advance_ip_and_run_current();
}
/// NOTE:
@ -314,7 +312,7 @@ namespace example
/// returning the results.
///
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
intrinsic.cpuid(gs, tls, mut_rax, mut_rbx, mut_rcx, mut_rdx);
/// NOTE:
/// - Write the results of CPUID to the VP's registers. Note that
@ -323,17 +321,17 @@ namespace example
/// sure that we are emulating CPUID properly.
///
sys.bf_tls_set_rax(rax);
sys.bf_tls_set_rbx(rbx);
sys.bf_tls_set_rcx(rcx);
sys.bf_tls_set_rdx(rdx);
mut_sys.bf_tls_set_rax(mut_rax);
mut_sys.bf_tls_set_rbx(mut_rbx);
mut_sys.bf_tls_set_rcx(mut_rcx);
mut_sys.bf_tls_set_rdx(mut_rdx);
/// NOTE:
/// - Complete the emulation of CPUID by advancing RIP and running
/// the currently loaded VM, VP and VPS.
///
return sys.bf_vps_op_advance_ip_and_run_current();
return mut_sys.bf_vps_op_advance_ip_and_run_current();
}
/// <!-- description -->
@ -342,7 +340,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -353,12 +351,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid,
bsl::safe_uint64 const &exit_reason) noexcept -> bsl::errc_type
{
@ -375,7 +373,7 @@ namespace example
switch (exit_reason.get()) {
case exit_reason_cpuid.get(): {
return handle_cpuid(gs, tls, sys, intrinsic, vp_pool, vps_pool, vpsid);
return handle_cpuid(gs, tls, mut_sys, intrinsic, vp_pool, vps_pool, vpsid);
}
default: {

View file

@ -68,10 +68,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -137,7 +137,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -160,7 +164,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vpid the ID of the VP to assign the vps_t to
/// @param ppid the ID of the PP to assign the vps_t to
@ -169,10 +173,10 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vpid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{
@ -180,7 +184,7 @@ namespace example
bsl::discard(tls);
bsl::discard(intrinsic);
bsl::errc_type ret{};
bsl::errc_type mut_ret{};
/// NOTE:
/// - The following is a pedantic check to make sure we have
@ -273,10 +277,10 @@ namespace example
///
if (ppid == m_id) {
ret = sys.bf_vps_op_init_as_root(m_id);
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_init_as_root(m_id);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
bsl::touch();
@ -300,13 +304,12 @@ namespace example
/// VPSs are assigned to VPs).
///
constexpr auto guest_asid_idx{0x0058_u64};
constexpr auto guest_asid_val{0x1_u32};
ret = sys.bf_vps_op_write32(m_id, guest_asid_idx, guest_asid_val);
if (bsl::unlikely_assert(!ret)) {
constexpr auto guest_asid_val{0x1_u64};
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_guest_asid, guest_asid_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -314,21 +317,20 @@ namespace example
/// VMRun, and CPUID if we plan to support reporting and stopping.
///
constexpr auto intercept_instr1_idx{0x000C_u64};
constexpr auto intercept_instr1_val{0x00040000_u32};
constexpr auto intercept_instr2_idx{0x0010_u64};
constexpr auto intercept_instr2_val{0x00000001_u32};
ret = sys.bf_vps_op_write32(m_id, intercept_instr1_idx, intercept_instr1_val);
if (bsl::unlikely_assert(!ret)) {
constexpr auto intercept_instr1_val{0x00040000_u64};
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_intercept_instruction1, intercept_instr1_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
ret = sys.bf_vps_op_write32(m_id, intercept_instr2_idx, intercept_instr2_val);
if (bsl::unlikely_assert(!ret)) {
constexpr auto intercept_instr2_val{0x00000001_u64};
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_intercept_instruction2, intercept_instr2_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:

View file

@ -55,7 +55,7 @@ namespace example
/// and friends otherwise
///
[[nodiscard]] static constexpr auto
initialize(gs_t &gs, tls_t &tls) noexcept -> bsl::errc_type
initialize(gs_t const &gs, tls_t const &tls) noexcept -> bsl::errc_type
{
bsl::discard(gs);
bsl::discard(tls);
@ -76,7 +76,7 @@ namespace example
/// @param tls the tls_t to use
///
static constexpr void
release(gs_t &gs, tls_t &tls) noexcept
release(gs_t const &gs, tls_t const &tls) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -94,22 +94,24 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param mut_rax the index used by CPUID, returns resulting rax
/// @param mut_rbx returns resulting rbx
/// @param mut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param mut_rdx returns resulting rdx
///
static constexpr void
cpuid(
gs_t &gs,
tls_t &tls,
bsl::safe_uint64 &rax,
bsl::safe_uint64 &rbx,
bsl::safe_uint64 &rcx,
bsl::safe_uint64 &rdx) noexcept
gs_t const &gs,
tls_t const &tls,
bsl::safe_uint64 &mut_rax,
bsl::safe_uint64 &mut_rbx,
bsl::safe_uint64 &mut_rcx,
bsl::safe_uint64 &mut_rdx) noexcept
{
bsl::discard(tls);
intrinsic_cpuid_impl(&gs, rax.data(), rbx.data(), rcx.data(), rdx.data());
intrinsic_cpuid_impl(
&gs, mut_rax.data(), mut_rbx.data(), mut_rcx.data(), mut_rdx.data());
}
};
}

View file

@ -42,6 +42,20 @@
namespace example
{
/// @brief used to enable the NMI window exiting bit
constexpr auto VMCS_SET_NMI_WINDOW_EXITING{0x400000_u64};
/// @brief used to disable the NMI window exiting bit
constexpr auto VMCS_CLEAR_NMI_WINDOW_EXITING{0xFFBFFFFF_u64};
/// @brief used to inject an interrupt
constexpr auto VMCS_ENTRY_INTERRUPT_INFO_VAL{0x80000202_u64};
/// @brief define the NMI exit reason
constexpr auto EXIT_REASON_NMI{0x0_u64};
/// @brief define the NMI window exit reason
constexpr auto EXIT_REASON_NMI_WINDOW{0x8_u64};
/// @brief define the CPUID exit reason
constexpr auto EXIT_REASON_CPUID{0xA_u64};
/// @class example::vmexit_t
///
/// <!-- description -->
@ -54,9 +68,9 @@ namespace example
/// @brief Initializes this vmexit_t.
///
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param mut_gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -65,20 +79,20 @@ namespace example
///
[[nodiscard]] static constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept -> bsl::errc_type
gs_t &mut_gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept -> bsl::errc_type
{
bsl::discard(tls);
bsl::discard(intrinsic);
bsl::discard(vp_pool);
bsl::discard(vps_pool);
gs.msr_bitmap = sys.bf_mem_op_alloc_page(gs.msr_bitmap_phys);
if (bsl::unlikely_assert(nullptr == gs.msr_bitmap)) {
mut_gs.msr_bitmap = mut_sys.bf_mem_op_alloc_page(mut_gs.msr_bitmap_phys);
if (bsl::unlikely_assert(nullptr == mut_gs.msr_bitmap)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
@ -95,24 +109,22 @@ namespace example
/// @brief Release the vmexit_t.
///
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param mut_gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
///
static constexpr void
release(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool) noexcept
gs_t &mut_gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool) noexcept
{
bsl::errc_type ret{};
bsl::discard(tls);
bsl::discard(intrinsic);
bsl::discard(vp_pool);
@ -123,7 +135,7 @@ namespace example
/// an error, or during unit testing.
///
ret = sys.bf_mem_op_free_page(gs.msr_bitmap);
auto const ret{mut_sys.bf_mem_op_free_page(mut_gs.msr_bitmap)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
}
@ -131,8 +143,8 @@ namespace example
bsl::touch();
}
gs.msr_bitmap = {};
gs.msr_bitmap_phys = {};
mut_gs.msr_bitmap = {};
mut_gs.msr_bitmap_phys = {};
}
/// <!-- description -->
@ -141,7 +153,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -151,12 +163,12 @@ namespace example
///
[[nodiscard]] static constexpr auto
handle_nmi(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -175,27 +187,23 @@ namespace example
/// from there, inject the NMI into the appropriate VPS.
///
constexpr auto vmcs_procbased_ctls_idx{0x4002_u64};
constexpr auto vmcs_set_nmi_window_exiting{0x400000_u32};
bsl::safe_uint32 val{};
bsl::errc_type ret{};
val = sys.bf_vps_op_read32(vpsid, vmcs_procbased_ctls_idx);
if (bsl::unlikely_assert(!val)) {
auto mut_val{mut_sys.bf_vps_op_read(
vpsid, syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls)};
if (bsl::unlikely_assert(!mut_val)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
val |= vmcs_set_nmi_window_exiting;
mut_val |= VMCS_SET_NMI_WINDOW_EXITING;
ret = sys.bf_vps_op_write32(vpsid, vmcs_procbased_ctls_idx, val);
auto const ret{mut_sys.bf_vps_op_write(
vpsid, syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls, mut_val)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
}
return sys.bf_vps_op_run_current();
return mut_sys.bf_vps_op_run_current();
}
/// <!-- description -->
@ -204,7 +212,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -214,14 +222,16 @@ namespace example
///
[[nodiscard]] static constexpr auto
handle_nmi_window(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid) noexcept -> bsl::errc_type
{
bsl::errc_type mut_ret{};
bsl::discard(gs);
bsl::discard(tls);
bsl::discard(intrinsic);
@ -238,24 +248,20 @@ namespace example
/// on what hardware you are using (e.g., a laptop).
///
constexpr auto vmcs_procbased_ctls_idx{0x4002_u64};
constexpr auto vmcs_clear_nmi_window_exiting{0xFFBFFFFF_u32};
bsl::safe_uint32 val{};
bsl::errc_type ret{};
val = sys.bf_vps_op_read32(vpsid, vmcs_procbased_ctls_idx);
if (bsl::unlikely_assert(!val)) {
auto mut_val{mut_sys.bf_vps_op_read(
vpsid, syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls)};
if (bsl::unlikely_assert(!mut_val)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
val &= vmcs_clear_nmi_window_exiting;
mut_val &= VMCS_CLEAR_NMI_WINDOW_EXITING;
ret = sys.bf_vps_op_write32(vpsid, vmcs_procbased_ctls_idx, val);
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
vpsid, syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls, mut_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -265,17 +271,17 @@ namespace example
/// so we are required to implement it on Intel.
///
constexpr auto vmcs_entry_interrupt_info_idx{0x4016_u64};
constexpr auto vmcs_entry_interrupt_info_val{0x80000202_u32};
mut_ret = mut_sys.bf_vps_op_write(
vpsid,
syscall::bf_reg_t::bf_reg_t_vmentry_interrupt_information_field,
VMCS_ENTRY_INTERRUPT_INFO_VAL);
ret = sys.bf_vps_op_write32(
vpsid, vmcs_entry_interrupt_info_idx, vmcs_entry_interrupt_info_val);
if (bsl::unlikely_assert(!ret)) {
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
return sys.bf_vps_op_run_current();
return mut_sys.bf_vps_op_run_current();
}
/// <!-- description -->
@ -284,7 +290,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -294,19 +300,17 @@ namespace example
///
[[nodiscard]] static constexpr auto
handle_cpuid(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid) noexcept -> bsl::errc_type
{
bsl::discard(vp_pool);
bsl::discard(vps_pool);
bsl::errc_type ret{};
/// NOTE:
/// - The first thing that we need to do is get the current values
/// of RAX, RBX, RCX and RDX. We use the full 64bit versions to
@ -315,10 +319,10 @@ namespace example
/// correctly.
///
auto rax{sys.bf_tls_rax()};
auto rbx{sys.bf_tls_rbx()};
auto rcx{sys.bf_tls_rcx()};
auto rdx{sys.bf_tls_rdx()};
auto mut_rax{mut_sys.bf_tls_rax()};
auto mut_rbx{mut_sys.bf_tls_rbx()};
auto mut_rcx{mut_sys.bf_tls_rcx()};
auto mut_rdx{mut_sys.bf_tls_rdx()};
/// NOTE:
/// - Before we execute CPUID, we need to check to see if we have
@ -326,8 +330,8 @@ namespace example
/// CPUID differently.
///
if (loader::CPUID_COMMAND_EAX == bsl::to_u32_unsafe(rax)) {
switch (bsl::to_u32_unsafe(rcx).get()) {
if (loader::CPUID_COMMAND_EAX == bsl::to_u32_unsafe(mut_rax)) {
switch (bsl::to_u32_unsafe(mut_rcx).get()) {
case loader::CPUID_COMMAND_ECX_STOP.get(): {
/// NOTE:
@ -339,7 +343,7 @@ namespace example
/// being over used.
///
if (sys.bf_tls_ppid() == (sys.bf_tls_online_pps() - 1_u16)) {
if (mut_sys.bf_tls_ppid() == (mut_sys.bf_tls_online_pps() - 1_u16)) {
bsl::print() << bsl::endl;
syscall::bf_debug_op_dump_page_pool();
bsl::print() << bsl::endl;
@ -360,9 +364,9 @@ namespace example
/// to decode anything, so that is up to you.
///
if constexpr (BSL_DEBUG_LEVEL > bsl::V) {
if constexpr (bsl::debug_level_is_at_least_vv()) {
bsl::print() << bsl::endl;
syscall::bf_debug_op_dump_vmexit_log(sys.bf_tls_ppid());
syscall::bf_debug_op_dump_vmexit_log(mut_sys.bf_tls_ppid());
}
/// NOTE:
@ -377,17 +381,17 @@ namespace example
/// it is "done", because it might fail.
///
bsl::debug() << bsl::rst << "about to" // --
<< bsl::red << " promote " // --
<< bsl::rst << "root OS on pp " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
bsl::debug() << bsl::rst << "about to" // --
<< bsl::red << " promote " // --
<< bsl::rst << "root OS on pp " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
/// NOTE:
/// - Report success
///
sys.bf_tls_set_rax(loader::CPUID_COMMAND_RAX_SUCCESS);
mut_sys.bf_tls_set_rax(loader::CPUID_COMMAND_RAX_SUCCESS);
/// NOTE:
/// - Before we can stop, we need to advance RIP.
@ -397,7 +401,7 @@ namespace example
/// exit before then so we need to advance now.
///
ret = sys.bf_vps_op_advance_ip(vpsid);
auto const ret{mut_sys.bf_vps_op_advance_ip(vpsid)};
if (bsl::unlikely_assert(!ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
@ -412,7 +416,7 @@ namespace example
/// hypervisor turned off.
///
return sys.bf_vps_op_promote(vpsid);
return mut_sys.bf_vps_op_promote(vpsid);
}
case loader::CPUID_COMMAND_ECX_REPORT_ON.get(): {
@ -423,13 +427,13 @@ namespace example
/// want here, this is just the default behavior.
///
bsl::debug() << bsl::rst << "root OS had been" // --
<< bsl::grn << " demoted " // --
<< bsl::rst << "to vm " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_vmid()) // --
<< bsl::rst << " on pp " // --
<< bsl::cyn << bsl::hex(sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
bsl::debug() << bsl::rst << "root OS had been" // --
<< bsl::grn << " demoted " // --
<< bsl::rst << "to vm " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_vmid()) // --
<< bsl::rst << " on pp " // --
<< bsl::cyn << bsl::hex(mut_sys.bf_tls_ppid()) // --
<< bsl::rst << bsl::endl; // --
break;
}
@ -450,7 +454,7 @@ namespace example
default: {
bsl::error() << "unsupported cpuid command " // --
<< bsl::hex(rcx) // --
<< bsl::hex(mut_rcx) // --
<< bsl::endl // --
<< bsl::here(); // --
@ -463,7 +467,7 @@ namespace example
/// the currently loaded VM, VP and VPS.
///
return sys.bf_vps_op_advance_ip_and_run_current();
return mut_sys.bf_vps_op_advance_ip_and_run_current();
}
/// NOTE:
@ -472,7 +476,7 @@ namespace example
/// returning the results.
///
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
intrinsic.cpuid(gs, tls, mut_rax, mut_rbx, mut_rcx, mut_rdx);
/// NOTE:
/// - Write the results of CPUID to the VP's registers. Note that
@ -481,17 +485,17 @@ namespace example
/// sure that we are emulating CPUID properly.
///
sys.bf_tls_set_rax(rax);
sys.bf_tls_set_rbx(rbx);
sys.bf_tls_set_rcx(rcx);
sys.bf_tls_set_rdx(rdx);
mut_sys.bf_tls_set_rax(mut_rax);
mut_sys.bf_tls_set_rbx(mut_rbx);
mut_sys.bf_tls_set_rcx(mut_rcx);
mut_sys.bf_tls_set_rdx(mut_rdx);
/// NOTE:
/// - Complete the emulation of CPUID by advancing RIP and running
/// the currently loaded VM, VP and VPS.
///
return sys.bf_vps_op_advance_ip_and_run_current();
return mut_sys.bf_vps_op_advance_ip_and_run_current();
}
/// <!-- description -->
@ -500,7 +504,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vp_pool the vp_pool_t to use
/// @param vps_pool the vps_pool_t to use
@ -511,40 +515,30 @@ namespace example
///
[[nodiscard]] static constexpr auto
dispatch(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
vp_pool_t &vp_pool,
vps_pool_t &vps_pool,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
vp_pool_t const &vp_pool,
vps_pool_t const &vps_pool,
bsl::safe_uint16 const &vpsid,
bsl::safe_uint64 const &exit_reason) noexcept -> bsl::errc_type
{
/// NOTE:
/// - Define the different VMExits that this dispatcher will
/// support. At a minimum, we need to handle CPUID, and NMIs
/// on Intel (as there is no way to disable NMIs on Intel).
///
constexpr auto exit_reason_nmi{0x0_u64};
constexpr auto exit_reason_nmi_window{0x8_u64};
constexpr auto exit_reason_cpuid{0xA_u64};
/// NOTE:
/// - Dispatch and handle each VMExit.
///
switch (exit_reason.get()) {
case exit_reason_nmi.get(): {
return handle_nmi(gs, tls, sys, intrinsic, vp_pool, vps_pool, vpsid);
case EXIT_REASON_NMI.get(): {
return handle_nmi(gs, tls, mut_sys, intrinsic, vp_pool, vps_pool, vpsid);
}
case exit_reason_nmi_window.get(): {
return handle_nmi_window(gs, tls, sys, intrinsic, vp_pool, vps_pool, vpsid);
case EXIT_REASON_NMI_WINDOW.get(): {
return handle_nmi_window(gs, tls, mut_sys, intrinsic, vp_pool, vps_pool, vpsid);
}
case exit_reason_cpuid.get(): {
return handle_cpuid(gs, tls, sys, intrinsic, vp_pool, vps_pool, vpsid);
case EXIT_REASON_CPUID.get(): {
return handle_cpuid(gs, tls, mut_sys, intrinsic, vp_pool, vps_pool, vpsid);
}
default: {

View file

@ -48,11 +48,11 @@ namespace example
/// @return The masked version of the control fields.
///
[[nodiscard]] constexpr auto
ctls_mask(bsl::safe_uint64 const &val) noexcept -> bsl::safe_uint32
ctls_mask(bsl::safe_uint64 const &val) noexcept -> bsl::safe_uint64
{
constexpr auto mask{0x00000000FFFFFFFF_u64};
constexpr auto shift{32_u64};
return bsl::to_u32_unsafe((val & mask) & (val >> shift));
return (val & mask) & (val >> shift);
};
/// @class example::vps_t
@ -84,10 +84,10 @@ namespace example
///
[[nodiscard]] constexpr auto
initialize(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &i) noexcept -> bsl::errc_type
{
bsl::discard(gs);
@ -153,7 +153,11 @@ namespace example
/// @param intrinsic the intrinsic_t to use
///
constexpr void
release(gs_t &gs, tls_t &tls, syscall::bf_syscall_t &sys, intrinsic_t &intrinsic) noexcept
release(
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t const &sys,
intrinsic_t const &intrinsic) noexcept
{
bsl::discard(gs);
bsl::discard(tls);
@ -176,7 +180,7 @@ namespace example
/// <!-- inputs/outputs -->
/// @param gs the gs_t to use
/// @param tls the tls_t to use
/// @param sys the bf_syscall_t to use
/// @param mut_sys the bf_syscall_t to use
/// @param intrinsic the intrinsic_t to use
/// @param vpid the ID of the VP to assign the vps_t to
/// @param ppid the ID of the PP to assign the vps_t to
@ -185,10 +189,10 @@ namespace example
///
[[nodiscard]] constexpr auto
allocate(
gs_t &gs,
tls_t &tls,
syscall::bf_syscall_t &sys,
intrinsic_t &intrinsic,
gs_t const &gs,
tls_t const &tls,
syscall::bf_syscall_t &mut_sys,
intrinsic_t const &intrinsic,
bsl::safe_uint16 const &vpid,
bsl::safe_uint16 const &ppid) noexcept -> bsl::errc_type
{
@ -196,7 +200,7 @@ namespace example
bsl::discard(tls);
bsl::discard(intrinsic);
bsl::errc_type ret{};
bsl::errc_type mut_ret{};
/// NOTE:
/// - The following is a pedantic check to make sure we have
@ -289,10 +293,10 @@ namespace example
///
if (ppid == m_id) {
ret = sys.bf_vps_op_init_as_root(m_id);
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_init_as_root(m_id);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
bsl::touch();
@ -312,26 +316,24 @@ namespace example
/// - Set up VPID
///
constexpr auto vmcs_vpid_idx{0x0000_u64};
constexpr auto vmcs_vpid_val{0x1_u16};
ret = sys.bf_vps_op_write16(m_id, vmcs_vpid_idx, vmcs_vpid_val);
if (bsl::unlikely_assert(!ret)) {
constexpr auto vmcs_vpid_val{0x1_u64};
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_virtual_processor_identifier, vmcs_vpid_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
/// - Set up the VMCS link pointer
///
constexpr auto vmcs_link_ptr_idx{0x2800_u64};
constexpr auto vmcs_link_ptr_val{0xFFFFFFFFFFFFFFFF_u64};
ret = sys.bf_vps_op_write64(m_id, vmcs_link_ptr_idx, vmcs_link_ptr_val);
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_vmcs_link_pointer, vmcs_link_ptr_val);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -357,34 +359,29 @@ namespace example
/// project.
///
constexpr auto vmcs_pinbased_ctls_idx{0x4000_u64};
constexpr auto vmcs_procbased_ctls_idx{0x4002_u64};
constexpr auto vmcs_exit_ctls_idx{0x400C_u64};
constexpr auto vmcs_entry_ctls_idx{0x4012_u64};
constexpr auto vmcs_procbased_ctls2_idx{0x401E_u64};
constexpr auto ia32_vmx_true_pinbased_ctls{0x48D_u32};
constexpr auto ia32_vmx_true_procbased_ctls{0x48E_u32};
constexpr auto ia32_vmx_true_exit_ctls{0x48F_u32};
constexpr auto ia32_vmx_true_entry_ctls{0x490_u32};
constexpr auto ia32_vmx_true_procbased_ctls2{0x48B_u32};
bsl::safe_uintmax ctls{};
bsl::safe_uintmax mut_ctls{};
/// NOTE:
/// - Configure the pin based controls
///
ctls = sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_pinbased_ctls);
if (bsl::unlikely_assert(!ctls)) {
mut_ctls = mut_sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_pinbased_ctls);
if (bsl::unlikely_assert(!mut_ctls)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
ret = sys.bf_vps_op_write32(m_id, vmcs_pinbased_ctls_idx, ctls_mask(ctls));
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_pin_based_vm_execution_ctls, ctls_mask(mut_ctls));
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -394,51 +391,57 @@ namespace example
constexpr auto enable_msr_bitmaps{0x10000000_u64};
constexpr auto enable_procbased_ctls2{0x80000000_u64};
ctls = sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_procbased_ctls);
if (bsl::unlikely_assert(!ctls)) {
mut_ctls = mut_sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_procbased_ctls);
if (bsl::unlikely_assert(!mut_ctls)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
ctls |= enable_msr_bitmaps;
ctls |= enable_procbased_ctls2;
mut_ctls |= enable_msr_bitmaps;
mut_ctls |= enable_procbased_ctls2;
ret = sys.bf_vps_op_write32(m_id, vmcs_procbased_ctls_idx, ctls_mask(ctls));
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id,
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
ctls_mask(mut_ctls));
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
/// - Configure the exit controls
///
ctls = sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_exit_ctls);
if (bsl::unlikely_assert(!ctls)) {
mut_ctls = mut_sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_exit_ctls);
if (bsl::unlikely_assert(!mut_ctls)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
ret = sys.bf_vps_op_write32(m_id, vmcs_exit_ctls_idx, ctls_mask(ctls));
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_vmexit_ctls, ctls_mask(mut_ctls));
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
/// - Configure the entry controls
///
ctls = sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_entry_ctls);
if (bsl::unlikely_assert(!ctls)) {
mut_ctls = mut_sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_entry_ctls);
if (bsl::unlikely_assert(!mut_ctls)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
ret = sys.bf_vps_op_write32(m_id, vmcs_entry_ctls_idx, ctls_mask(ctls));
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_vmentry_ctls, ctls_mask(mut_ctls));
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -451,22 +454,26 @@ namespace example
constexpr auto enable_xsave{0x00100000_u64};
constexpr auto enable_uwait{0x04000000_u64};
ctls = sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_procbased_ctls2);
if (bsl::unlikely_assert(!ctls)) {
mut_ctls = mut_sys.bf_intrinsic_op_rdmsr(ia32_vmx_true_procbased_ctls2);
if (bsl::unlikely_assert(!mut_ctls)) {
bsl::print<bsl::V>() << bsl::here();
return bsl::errc_failure;
}
ctls |= enable_vpid;
ctls |= enable_rdtscp;
ctls |= enable_invpcid;
ctls |= enable_xsave;
ctls |= enable_uwait;
mut_ctls |= enable_vpid;
mut_ctls |= enable_rdtscp;
mut_ctls |= enable_invpcid;
mut_ctls |= enable_xsave;
mut_ctls |= enable_uwait;
ret = sys.bf_vps_op_write32(m_id, vmcs_procbased_ctls2_idx, ctls_mask(ctls));
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id,
syscall::bf_reg_t::bf_reg_t_secondary_proc_based_vm_execution_ctls,
ctls_mask(mut_ctls));
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -476,12 +483,11 @@ namespace example
/// CPUs you are running on.
///
constexpr auto vmcs_msr_bitmaps{0x2004_u64};
ret = sys.bf_vps_op_write64(m_id, vmcs_msr_bitmaps, gs.msr_bitmap_phys);
if (bsl::unlikely_assert(!ret)) {
mut_ret = mut_sys.bf_vps_op_write(
m_id, syscall::bf_reg_t::bf_reg_t_address_of_msr_bitmaps, gs.msr_bitmap_phys);
if (bsl::unlikely_assert(!mut_ret)) {
bsl::print<bsl::V>() << bsl::here();
return ret;
return mut_ret;
}
/// NOTE:
@ -492,7 +498,7 @@ namespace example
m_assigned_vpid = vpid;
m_assigned_ppid = ppid;
return bsl::errc_success;
return mut_ret;
}
};
}

View file

@ -37,17 +37,17 @@ namespace example
///
/// <!-- inputs/outputs -->
/// @param gs ignored
/// @param rax the index used by CPUID, returns resulting rax
/// @param rbx returns resulting rbx
/// @param rcx the subindex used by CPUID, returns the resulting rcx
/// @param rdx returns resulting rdx
/// @param pmut_rax the index used by CPUID, returns resulting rax
/// @param pmut_rbx returns resulting rbx
/// @param pmut_rcx the subindex used by CPUID, returns the resulting rcx
/// @param pmut_rdx returns resulting rdx
///
extern "C" void intrinsic_cpuid_impl(
gs_t *const gs,
bsl::uint64 *const rax,
bsl::uint64 *const rbx,
bsl::uint64 *const rcx,
bsl::uint64 *const rdx) noexcept;
gs_t const *const gs,
bsl::uint64 *const pmut_rax,
bsl::uint64 *const pmut_rbx,
bsl::uint64 *const pmut_rcx,
bsl::uint64 *const pmut_rdx) noexcept;
}
#endif

View file

@ -23,23 +23,19 @@ Checks:
'
-*,
bsl-*,
-bsl-template-generic-param,
-bsl-literals-user-defined,
-bsl-lambda-implicit-capture,
bugprone-*,
-bugprone-branch-clone,
cert-*,
-cert-dcl21-cpp,
-cert-oop54-cpp,
clang-analyzer-*,
-clang-analyzer-core.CallAndMessage,
-clang-analyzer-core.NullDereference,
cppcoreguidelines-*,
-cppcoreguidelines-avoid-non-const-global-variables,
-cppcoreguidelines-avoid-magic-numbers,
hicpp-*,
-hicpp-function-size,
misc-*,
-misc-misplaced-const,
-misc-non-private-member-variables-in-classes,
modernize-*,
-modernize-use-default-member-init,
performance-*,
@ -47,7 +43,8 @@ Checks:
-readability-redundant-member-init,
-readability-avoid-const-params-in-decls,
-readability-static-accessed-through-instance,
-readability-function-size
-readability-function-size,
-readability-magic-numbers
'
WarningsAsErrors: '*'
HeaderFilterRegex: '.*'

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,18 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_when{} = [&]() noexcept {
bootstrap.set_initialize(bsl::errc_failure);
mut_bootstrap.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(!mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
};
};
};
@ -61,48 +54,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_then{} = [&]() noexcept {
bootstrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_bootstrap.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_when{} = [&]() noexcept {
bootstrap.set_dispatch(bsl::errc_failure);
mut_bootstrap.set_dispatch(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
bsl::ut_check(!mut_bootstrap.dispatch({}, {}, {}, {}, {}, {}, {}));
};
};
};
@ -110,16 +84,9 @@ namespace example
bsl::ut_scenario{"dispatch success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
bsl::ut_check(mut_bootstrap.dispatch({}, {}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::bootstrap_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::bootstrap_t m_boostrap{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - bootstrap_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::bootstrap_t{});
bsl::discard(m_boostrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_boostrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_boostrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,31 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::bootstrap_t boostrap{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::bootstrap_t mut_boostrap{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::bootstrap_t{}));
static_assert(
noexcept(boostrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(boostrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(boostrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_boostrap.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_boostrap.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_boostrap.dispatch({}, {}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -40,19 +40,13 @@ namespace example
[[nodiscard]] constexpr auto
tests() noexcept -> bsl::exit_code
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_scenario{"initialize mut_fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_when{} = [&]() noexcept {
fail.set_initialize(bsl::errc_failure);
mut_fail.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(!mut_fail.initialize({}, {}, {}, {}, {}, {}));
};
};
};
@ -60,48 +54,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_fail.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_fail.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch fails"} = []() noexcept {
bsl::ut_scenario{"dispatch mut_fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_when{} = [&]() noexcept {
fail.set_dispatch(bsl::errc_failure);
mut_fail.set_dispatch(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(!mut_fail.dispatch({}, {}, {}, {}, {}, {}, {}, {}));
};
};
};
@ -109,16 +84,9 @@ namespace example
bsl::ut_scenario{"dispatch success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(mut_fail.dispatch({}, {}, {}, {}, {}, {}, {}, {}));
};
};
};
@ -128,8 +96,8 @@ namespace example
}
/// <!-- description -->
/// @brief Main function for this unit test. If a call to bsl::ut_check() fails
/// the application will fast fail. If all calls to bsl::ut_check() pass, this
/// @brief Main function for this unit test. If a call to bsl::ut_check() mut_fails
/// the application will fast mut_fail. If all calls to bsl::ut_check() pass, this
/// function will successfully return with bsl::exit_success.
///
/// <!-- inputs/outputs -->

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::fail_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::fail_t m_fail{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - fail_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::fail_t{});
bsl::discard(m_fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,30 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::fail_t fail{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::fail_t mut_fail{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::fail_t{}));
static_assert(
noexcept(fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(noexcept(fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_fail.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_fail.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_fail.dispatch({}, {}, {}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,13 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_when{} = [&]() noexcept {
intrinsic.set_initialize(bsl::errc_failure);
mut_intrinsic.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!intrinsic.initialize(gs, tls));
bsl::ut_check(!mut_intrinsic.initialize({}, {}));
};
};
};
@ -56,22 +54,18 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(intrinsic.initialize(gs, tls));
bsl::ut_check(mut_intrinsic.initialize({}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};

View file

@ -30,38 +30,6 @@
namespace
{
constinit example::intrinsic_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::intrinsic_t m_intrinsic{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - intrinsic_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
bsl::discard(example::intrinsic_t{});
bsl::discard(m_intrinsic.initialize(gs, tls));
m_intrinsic.release(gs, tls);
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -81,23 +49,11 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::intrinsic_t intrinsic{};
example::gs_t gs{};
example::tls_t tls{};
example::intrinsic_t mut_intrinsic{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::intrinsic_t{}));
static_assert(noexcept(intrinsic.initialize(gs, tls)));
static_assert(noexcept(intrinsic.release(gs, tls)));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_intrinsic.initialize({}, {})));
static_assert(noexcept(mut_intrinsic.release({}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,18 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_when{} = [&]() noexcept {
vmexit.set_initialize(bsl::errc_failure);
mut_vmexit.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(!mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
};
};
};
@ -61,48 +54,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_then{} = [&]() noexcept {
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_when{} = [&]() noexcept {
vmexit.set_dispatch(bsl::errc_failure);
mut_vmexit.set_dispatch(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(!mut_vmexit.dispatch({}, {}, {}, {}, {}, {}, {}, {}));
};
};
};
@ -110,16 +84,9 @@ namespace example
bsl::ut_scenario{"dispatch success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(mut_vmexit.dispatch({}, {}, {}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::vmexit_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vmexit_t m_vmexit{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vmexit_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::vmexit_t{});
bsl::discard(m_vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,30 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vmexit_t vmexit{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::vmexit_t mut_vmexit{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vmexit_t{}));
static_assert(
noexcept(vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(noexcept(vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vmexit.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_vmexit.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_vmexit.dispatch({}, {}, {}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_when{} = [&]() noexcept {
vp_pool.set_initialize(bsl::errc_failure);
mut_vp_pool.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(!mut_vp_pool.initialize({}, {}, {}, {}));
};
};
};
@ -58,41 +54,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(mut_vp_pool.initialize({}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_then{} = [&]() noexcept {
vp_pool.release(gs, tls, sys, intrinsic);
mut_vp_pool.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_when{} = [&]() noexcept {
vp_pool.set_allocate(bsl::safe_uint16::failure());
mut_vp_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp_pool.allocate({}, {}, {}, {}, {}, {}));
};
};
};
@ -100,13 +84,9 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vp_pool.allocate({}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vp_pool_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vp_pool_t m_vp_pool{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vp_pool_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vp_pool_t{});
bsl::discard(m_vp_pool.initialize(gs, tls, sys, intrinsic));
m_vp_pool.release(gs, tls, sys, intrinsic);
bsl::discard(m_vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vp_pool_t vp_pool{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t mut_vp_pool{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vp_pool_t{}));
static_assert(noexcept(vp_pool.initialize(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp_pool.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp_pool.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vp_pool.initialize({}, {}, {}, {})));
static_assert(noexcept(mut_vp_pool.release({}, {}, {}, {})));
static_assert(noexcept(mut_vp_pool.allocate({}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,71 +42,47 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp.initialize(gs, tls, sys, intrinsic, {}));
};
vp_t mut_vp{};
tls_t const tls{bsl::errc_failure};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!mut_vp.initialize({}, tls, {}, {}, {}));
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(mut_vp.initialize({}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_then{} = [&]() noexcept {
vp.release(gs, tls, sys, intrinsic);
mut_vp.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp.allocate(gs, tls, sys, intrinsic, {}, {}));
};
vp_t mut_vp{};
tls_t const tls{bsl::errc_failure};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!mut_vp.allocate({}, tls, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vp.allocate({}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vp_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vp_t m_vp{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vp_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vp_t{});
bsl::discard(m_vp.initialize(gs, tls, sys, intrinsic, {}));
m_vp.release(gs, tls, sys, intrinsic);
bsl::discard(m_vp.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vp_t vp{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_t mut_vp{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vp_t{}));
static_assert(noexcept(vp.initialize(gs, tls, sys, intrinsic, {})));
static_assert(noexcept(vp.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vp.initialize({}, {}, {}, {}, {})));
static_assert(noexcept(mut_vp.release({}, {}, {}, {})));
static_assert(noexcept(mut_vp.allocate({}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
vps_pool.set_initialize(bsl::errc_failure);
mut_vps_pool.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(!mut_vps_pool.initialize({}, {}, {}, {}));
};
};
};
@ -58,41 +54,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(mut_vps_pool.initialize({}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_then{} = [&]() noexcept {
vps_pool.release(gs, tls, sys, intrinsic);
mut_vps_pool.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
vps_pool.set_allocate(bsl::safe_uint16::failure());
mut_vps_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps_pool.allocate({}, {}, {}, {}, {}, {}));
};
};
};
@ -100,13 +84,9 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vps_pool.allocate({}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vps_pool_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vps_pool_t m_vps_pool{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vps_pool_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vps_pool_t{});
bsl::discard(m_vps_pool.initialize(gs, tls, sys, intrinsic));
m_vps_pool.release(gs, tls, sys, intrinsic);
bsl::discard(m_vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vps_pool_t vps_pool{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vps_pool_t mut_vps_pool{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vps_pool_t{}));
static_assert(noexcept(vps_pool.initialize(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps_pool.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps_pool.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vps_pool.initialize({}, {}, {}, {})));
static_assert(noexcept(mut_vps_pool.release({}, {}, {}, {})));
static_assert(noexcept(mut_vps_pool.allocate({}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,71 +42,47 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.initialize(gs, tls, sys, intrinsic, {}));
};
vps_t mut_vps{};
tls_t const tls{bsl::errc_failure};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!mut_vps.initialize({}, tls, {}, {}, {}));
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(mut_vps.initialize({}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_then{} = [&]() noexcept {
vps.release(gs, tls, sys, intrinsic);
mut_vps.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
};
vps_t mut_vps{};
tls_t const tls{bsl::errc_failure};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!mut_vps.allocate({}, tls, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vps.allocate({}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vps_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vps_t m_vps{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vps_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vps_t{});
bsl::discard(m_vps.initialize(gs, tls, sys, intrinsic, {}));
m_vps.release(gs, tls, sys, intrinsic);
bsl::discard(m_vps.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vps_t vps{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vps_t mut_vps{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vps_t{}));
static_assert(noexcept(vps.initialize(gs, tls, sys, intrinsic, {})));
static_assert(noexcept(vps.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vps.initialize({}, {}, {}, {}, {})));
static_assert(noexcept(mut_vps.release({}, {}, {}, {})));
static_assert(noexcept(mut_vps.allocate({}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,13 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_when{} = [&]() noexcept {
intrinsic.set_initialize(bsl::errc_failure);
mut_intrinsic.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!intrinsic.initialize(gs, tls));
bsl::ut_check(!mut_intrinsic.initialize({}, {}));
};
};
};
@ -56,48 +54,40 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(intrinsic.initialize(gs, tls));
bsl::ut_check(mut_intrinsic.initialize({}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
bsl::ut_scenario{"cpuid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
constexpr auto input{0x1234567800000000_u64};
constexpr auto output{0x42_u32};
constexpr auto expected_result{0x1234567800000042_u64};
constexpr auto eax{0x42_u32};
constexpr auto ebx{0x42_u32};
constexpr auto ecx{0x42_u32};
constexpr auto edx{0x42_u32};
auto rax{0x1234567800000000_u64};
auto rbx{0x1234567800000000_u64};
auto rcx{0x1234567800000000_u64};
auto rdx{0x1234567800000000_u64};
auto mut_rax{input};
auto mut_rbx{input};
auto mut_rcx{input};
auto mut_rdx{input};
bsl::ut_when{} = [&]() noexcept {
intrinsic.set_cpuid(eax, ebx, ecx, edx);
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
mut_intrinsic.set_cpuid(output, output, output, output);
mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(rax == expected_result);
bsl::ut_check(rbx == expected_result);
bsl::ut_check(rcx == expected_result);
bsl::ut_check(rdx == expected_result);
bsl::ut_check(mut_rax == expected_result);
bsl::ut_check(mut_rbx == expected_result);
bsl::ut_check(mut_rcx == expected_result);
bsl::ut_check(mut_rdx == expected_result);
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::intrinsic_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::intrinsic_t m_intrinsic{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - intrinsic_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
bsl::discard(example::intrinsic_t{});
bsl::discard(m_intrinsic.initialize(gs, tls));
m_intrinsic.release(gs, tls);
m_intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,28 +49,22 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::intrinsic_t intrinsic{};
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
example::intrinsic_t mut_intrinsic{};
example::intrinsic_t const intrinsic{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::intrinsic_t{}));
static_assert(noexcept(intrinsic.initialize(gs, tls)));
static_assert(noexcept(intrinsic.release(gs, tls)));
static_assert(noexcept(intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx)));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_intrinsic.initialize({}, {})));
static_assert(noexcept(mut_intrinsic.release({}, {})));
static_assert(
noexcept(mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
static_assert(
noexcept(intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,13 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_when{} = [&]() noexcept {
intrinsic.set_initialize(bsl::errc_failure);
mut_intrinsic.set_initialize(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!intrinsic.initialize(gs, tls));
bsl::ut_check(!mut_intrinsic.initialize({}, {}));
};
};
};
@ -56,48 +54,40 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(intrinsic.initialize(gs, tls));
bsl::ut_check(mut_intrinsic.initialize({}, {}));
};
};
};
bsl::ut_scenario{"release executes"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
bsl::ut_scenario{"cpuid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
constexpr auto input{0x1234567800000000_u64};
constexpr auto output{0x42_u32};
constexpr auto expected_result{0x1234567800000042_u64};
constexpr auto eax{0x42_u32};
constexpr auto ebx{0x42_u32};
constexpr auto ecx{0x42_u32};
constexpr auto edx{0x42_u32};
auto rax{0x1234567800000000_u64};
auto rbx{0x1234567800000000_u64};
auto rcx{0x1234567800000000_u64};
auto rdx{0x1234567800000000_u64};
auto mut_rax{input};
auto mut_rbx{input};
auto mut_rcx{input};
auto mut_rdx{input};
bsl::ut_when{} = [&]() noexcept {
intrinsic.set_cpuid(eax, ebx, ecx, edx);
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
mut_intrinsic.set_cpuid(output, output, output, output);
mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(rax == expected_result);
bsl::ut_check(rbx == expected_result);
bsl::ut_check(rcx == expected_result);
bsl::ut_check(rdx == expected_result);
bsl::ut_check(mut_rax == expected_result);
bsl::ut_check(mut_rbx == expected_result);
bsl::ut_check(mut_rcx == expected_result);
bsl::ut_check(mut_rdx == expected_result);
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::intrinsic_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::intrinsic_t m_intrinsic{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - intrinsic_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
bsl::discard(example::intrinsic_t{});
bsl::discard(m_intrinsic.initialize(gs, tls));
m_intrinsic.release(gs, tls);
m_intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,28 +49,22 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::intrinsic_t intrinsic{};
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
example::intrinsic_t mut_intrinsic{};
example::intrinsic_t const intrinsic{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::intrinsic_t{}));
static_assert(noexcept(intrinsic.initialize(gs, tls)));
static_assert(noexcept(intrinsic.release(gs, tls)));
static_assert(noexcept(intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx)));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_intrinsic.initialize({}, {})));
static_assert(noexcept(mut_intrinsic.release({}, {})));
static_assert(
noexcept(mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
static_assert(
noexcept(intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -43,37 +43,43 @@ namespace example
{
bsl::ut_scenario{"intrinsic_cpuid_impl invalid inputs doesn't crash"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
gs_t gs{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
gs_t const gs{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
bsl::ut_when{} = [&]() noexcept {
intrinsic_cpuid_impl(nullptr, rax.data(), rbx.data(), rcx.data(), rdx.data());
intrinsic_cpuid_impl(&gs, nullptr, rbx.data(), rcx.data(), rdx.data());
intrinsic_cpuid_impl(&gs, rax.data(), nullptr, rcx.data(), rdx.data());
intrinsic_cpuid_impl(&gs, rax.data(), rbx.data(), nullptr, rdx.data());
intrinsic_cpuid_impl(&gs, rax.data(), rbx.data(), rcx.data(), nullptr);
intrinsic_cpuid_impl(
nullptr, mut_rax.data(), mut_rbx.data(), mut_rcx.data(), mut_rdx.data());
intrinsic_cpuid_impl(
&gs, nullptr, mut_rbx.data(), mut_rcx.data(), mut_rdx.data());
intrinsic_cpuid_impl(
&gs, mut_rax.data(), nullptr, mut_rcx.data(), mut_rdx.data());
intrinsic_cpuid_impl(
&gs, mut_rax.data(), mut_rbx.data(), nullptr, mut_rdx.data());
intrinsic_cpuid_impl(
&gs, mut_rax.data(), mut_rbx.data(), mut_rcx.data(), nullptr);
};
};
};
bsl::ut_scenario{"intrinsic_cpuid_impl"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
gs_t gs{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
gs_t mut_gs{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
constexpr auto expected_result{42_u64};
bsl::ut_when{} = [&]() noexcept {
gs.cpuid_val = expected_result;
intrinsic_cpuid_impl(&gs, rax.data(), rbx.data(), rcx.data(), rdx.data());
mut_gs.cpuid_val = expected_result;
intrinsic_cpuid_impl(
&mut_gs, mut_rax.data(), mut_rbx.data(), mut_rcx.data(), mut_rdx.data());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(rax == expected_result);
bsl::ut_check(rbx == expected_result);
bsl::ut_check(rcx == expected_result);
bsl::ut_check(rdx == expected_result);
bsl::ut_check(mut_rax == expected_result);
bsl::ut_check(mut_rbx == expected_result);
bsl::ut_check(mut_rcx == expected_result);
bsl::ut_check(mut_rdx == expected_result);
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,48 +42,29 @@ namespace example
{
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_then{} = [&]() noexcept {
bootstrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_bootstrap.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bootstrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_bootstrap.release({}, {}, {}, {}, {}, {});
};
};
};
@ -91,20 +72,16 @@ namespace example
bsl::ut_scenario{"dispatch vp_pool allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
syscall::bf_syscall_t mut_sys{};
vp_pool_t mut_vp_pool{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
vp_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_required_step(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
mut_vp_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
bsl::ut_check(!mut_bootstrap.dispatch(
{}, {}, mut_sys, {}, mut_vp_pool, mut_vps_pool, {}));
};
};
};
@ -112,20 +89,16 @@ namespace example
bsl::ut_scenario{"dispatch vps_pool allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
syscall::bf_syscall_t mut_sys{};
vp_pool_t mut_vp_pool{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
vps_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_required_step(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
mut_vps_pool.set_allocate(bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
bsl::ut_check(!mut_bootstrap.dispatch(
{}, {}, mut_sys, {}, mut_vp_pool, mut_vps_pool, {}));
};
};
};
@ -133,19 +106,15 @@ namespace example
bsl::ut_scenario{"dispatch success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bootstrap_t bootstrap{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
bootstrap_t mut_bootstrap{};
syscall::bf_syscall_t mut_sys{};
vp_pool_t mut_vp_pool{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_bootstrap.initialize({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
bsl::ut_check(mut_bootstrap.dispatch(
{}, {}, mut_sys, {}, mut_vp_pool, mut_vps_pool, {}));
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::bootstrap_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::bootstrap_t m_bootstrap{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - bootstrap_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::bootstrap_t{});
bsl::discard(m_bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_bootstrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,31 +49,16 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::bootstrap_t bootstrap{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::bootstrap_t mut_bootstrap{};
syscall::bf_syscall_t mut_sys{};
example::vp_pool_t mut_vp_pool{};
example::vps_pool_t mut_vps_pool{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::bootstrap_t{}));
static_assert(
noexcept(bootstrap.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(bootstrap.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(bootstrap.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_bootstrap.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_bootstrap.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(
mut_bootstrap.dispatch({}, {}, mut_sys, {}, mut_vp_pool, mut_vps_pool, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,65 +42,39 @@ namespace example
{
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_fail.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_fail.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_fail.initialize({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_fail.release({}, {}, {}, {}, {}, {});
};
};
};
};
bsl::ut_scenario{"dispatch always fails"} = []() noexcept {
bsl::ut_scenario{"dispatch always mut_fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fail_t fail{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
fail_t mut_fail{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(!mut_fail.dispatch({}, {}, {}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::fail_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::fail_t m_fail{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - fail_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::fail_t{});
bsl::discard(m_fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,30 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::fail_t fail{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::fail_t mut_fail{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::fail_t{}));
static_assert(
noexcept(fail.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(noexcept(fail.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(fail.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_fail.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_fail.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_fail.dispatch({}, {}, {}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -39,28 +39,28 @@
namespace example
{
/// @brief stores the bf_syscall_t that this code will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern syscall::bf_syscall_t g_sys;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern syscall::bf_syscall_t g_mut_sys;
/// @brief stores the intrinsic_t that this code will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern intrinsic_t g_intrinsic;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern intrinsic_t g_mut_intrinsic;
/// @brief stores the pool of VPs that we will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern vp_pool_t g_vp_pool;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern vp_pool_t g_mut_vp_pool;
/// @brief stores the pool of VPSs that we will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern vps_pool_t g_vps_pool;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern vps_pool_t g_mut_vps_pool;
/// @brief stores the bootstrap_t that this code will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern bootstrap_t g_bootstrap;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern bootstrap_t g_mut_bootstrap;
/// @brief stores the fail_t that this code will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern fail_t g_fail;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern fail_t g_mut_fail;
/// @brief stores the vmexit_t that this code will use
// NOLINTNEXTLINE(bsl-non-pod-static)
extern vmexit_t g_vmexit;
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
extern vmexit_t g_mut_vmexit;
/// <!-- description -->
/// @brief Implements the bootstrap entry function. This function is
@ -104,288 +104,6 @@ namespace example
/// microkernel speak the same ABI.
///
extern "C" void ext_main_entry(bsl::uint32 const version) noexcept;
/// <!-- description -->
/// @brief Used to execute the actual checks. We put the checks in this
/// function so that we can validate the tests both at compile-time
/// and at run-time. If a bsl::ut_check fails, the tests will either
/// fail fast at run-time, or will produce a compile-time error.
///
/// <!-- inputs/outputs -->
/// @return Always returns bsl::exit_success.
///
[[nodiscard]] constexpr auto
tests() noexcept -> bsl::exit_code
{
bsl::ut_scenario{"bootstrap_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_bootstrap.set_dispatch(bsl::errc_failure);
bootstrap_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"bootstrap_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_bootstrap.set_dispatch(bsl::errc_success);
bootstrap_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"fail_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_fail.set_dispatch(bsl::errc_failure);
fail_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"fail_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_fail.set_dispatch(bsl::errc_success);
fail_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"vmexit_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_vmexit.set_dispatch(bsl::errc_failure);
vmexit_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"vmexit_entry success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
g_vmexit.set_dispatch(bsl::errc_success);
vmexit_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"main unsupported version"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main bf_syscall_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_failure);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main intrinsic_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_failure);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vp_pool_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_failure);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vps_pool_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_failure);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main bootstrap_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_failure);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main fail_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_failure);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vmexit_t initialize fails"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_failure);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main success"} = []() noexcept {
bsl::ut_given_at_runtime{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_bf_control_op_exit_impl_executed = {};
syscall::g_bf_control_op_wait_impl_executed = {};
g_sys.set_initialize(bsl::errc_success);
g_intrinsic.set_initialize(bsl::errc_success);
g_vp_pool.set_initialize(bsl::errc_success);
g_vps_pool.set_initialize(bsl::errc_success);
g_bootstrap.set_initialize(bsl::errc_success);
g_fail.set_initialize(bsl::errc_success);
g_vmexit.set_initialize(bsl::errc_success);
ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(!syscall::g_bf_control_op_exit_impl_executed);
bsl::ut_check(syscall::g_bf_control_op_wait_impl_executed);
};
};
};
};
return bsl::ut_success();
}
}
/// <!-- description -->
@ -401,6 +119,272 @@ main() noexcept -> bsl::exit_code
{
bsl::enable_color();
static_assert(example::tests() == bsl::ut_success());
return example::tests();
bsl::ut_scenario{"bootstrap_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_bootstrap.set_dispatch(bsl::errc_failure);
example::bootstrap_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"bootstrap_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_bootstrap.set_dispatch(bsl::errc_success);
example::bootstrap_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"fail_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_fail.set_dispatch(bsl::errc_failure);
example::fail_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"fail_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_fail.set_dispatch(bsl::errc_success);
example::fail_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"vmexit_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_vmexit.set_dispatch(bsl::errc_failure);
example::vmexit_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"vmexit_entry success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
example::g_mut_vmexit.set_dispatch(bsl::errc_success);
example::vmexit_entry({}, {});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
};
};
};
};
bsl::ut_scenario{"main unsupported version"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry({});
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main bf_syscall_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_failure);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main intrinsic_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_failure);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vp_pool_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_failure);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vps_pool_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_failure);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main bootstrap_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_failure);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main fail_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_failure);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main vmexit_t initialize fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_failure);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(!syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
bsl::ut_scenario{"main success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
bsl::ut_when{} = []() noexcept {
syscall::g_mut_bf_control_op_exit_impl_executed = {};
syscall::g_mut_bf_control_op_wait_impl_executed = {};
example::g_mut_sys.set_initialize(bsl::errc_success);
example::g_mut_intrinsic.set_initialize(bsl::errc_success);
example::g_mut_vp_pool.set_initialize(bsl::errc_success);
example::g_mut_vps_pool.set_initialize(bsl::errc_success);
example::g_mut_bootstrap.set_initialize(bsl::errc_success);
example::g_mut_fail.set_initialize(bsl::errc_success);
example::g_mut_vmexit.set_initialize(bsl::errc_success);
example::ext_main_entry(syscall::BF_ALL_SPECS_SUPPORTED_VAL.get());
bsl::ut_then{} = []() noexcept {
bsl::ut_check(!syscall::g_mut_bf_control_op_exit_impl_executed);
bsl::ut_check(syscall::g_mut_bf_control_op_wait_impl_executed);
};
};
};
};
return bsl::ut_success();
}

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,12 @@ namespace example
{
bsl::ut_scenario{"initialize vp_t reports failure"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
tls_t mut_tls{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
mut_tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(!mut_vp_pool.initialize({}, mut_tls, {}, {}));
};
};
};
@ -58,41 +55,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(mut_vp_pool.initialize({}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_then{} = [&]() noexcept {
vp_pool.release(gs, tls, sys, intrinsic);
mut_vp_pool.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_required_step(mut_vp_pool.initialize({}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vp_pool.release(gs, tls, sys, intrinsic);
mut_vp_pool.release({}, {}, {}, {});
};
};
};
@ -100,16 +85,13 @@ namespace example
bsl::ut_scenario{"allocate bf_vp_op_create_vp fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp_pool.initialize(gs, tls, sys, intrinsic));
sys.set_bf_vp_op_create_vp({}, {}, bsl::safe_uint16::failure());
bsl::ut_required_step(mut_vp_pool.initialize({}, {}, {}, {}));
mut_sys.set_bf_vp_op_create_vp({}, {}, bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -117,16 +99,13 @@ namespace example
bsl::ut_scenario{"allocate bf_vp_op_create_vp returns invalid id"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp_pool.initialize(gs, tls, sys, intrinsic));
sys.set_bf_vp_op_create_vp({}, {}, syscall::BF_INVALID_ID);
bsl::ut_required_step(mut_vp_pool.initialize({}, {}, {}, {}));
mut_sys.set_bf_vp_op_create_vp({}, {}, syscall::BF_INVALID_ID);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -134,16 +113,14 @@ namespace example
bsl::ut_scenario{"allocate vp_t allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
tls_t mut_tls{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp_pool.initialize(gs, tls, sys, intrinsic));
tls.test_ret = bsl::errc_failure;
bsl::ut_required_step(mut_vp_pool.initialize({}, {}, {}, {}));
mut_tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp_pool.allocate({}, mut_tls, mut_sys, {}, {}, {}));
};
};
};
@ -151,15 +128,12 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_pool_t vp_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t mut_vp_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_required_step(mut_vp_pool.initialize({}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vp_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vp_pool_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vp_pool_t m_vp_pool{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vp_pool_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vp_pool_t{});
bsl::discard(m_vp_pool.initialize(gs, tls, sys, intrinsic));
m_vp_pool.release(gs, tls, sys, intrinsic);
bsl::discard(m_vp_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,13 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vp_pool_t vp_pool{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t mut_vp_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vp_pool_t{}));
static_assert(noexcept(vp_pool.initialize(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp_pool.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp_pool.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vp_pool.initialize({}, {}, {}, {})));
static_assert(noexcept(mut_vp_pool.release({}, {}, {}, {})));
static_assert(noexcept(mut_vp_pool.allocate({}, {}, mut_sys, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize twice fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(!mut_vp.initialize({}, {}, {}, {}, {}));
};
};
};
@ -58,68 +54,47 @@ namespace example
bsl::ut_scenario{"initialize invalid id #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(
!vp.initialize(gs, tls, sys, intrinsic, bsl::safe_uint16::failure()));
bsl::ut_check(!mut_vp.initialize({}, {}, {}, {}, bsl::safe_uint16::failure()));
};
};
};
bsl::ut_scenario{"initialize invalid id #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(!vp.initialize(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID));
bsl::ut_check(!mut_vp.initialize({}, {}, {}, {}, syscall::BF_INVALID_ID));
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(mut_vp.initialize({}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
vp.release(gs, tls, sys, intrinsic);
mut_vp.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vp.release(gs, tls, sys, intrinsic);
mut_vp.release({}, {}, {}, {});
};
};
};
@ -127,29 +102,21 @@ namespace example
bsl::ut_scenario{"allocate not initialized"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp.allocate({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"allocate already allocated"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(vp.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_required_step(mut_vp.allocate({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vp.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vp.allocate({}, {}, {}, {}, {}, {}));
};
};
};
@ -157,16 +124,12 @@ namespace example
bsl::ut_scenario{"allocate invalid vmid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vp.allocate(gs, tls, sys, intrinsic, bsl::safe_uint16::failure(), {}));
!mut_vp.allocate({}, {}, {}, {}, bsl::safe_uint16::failure(), {}));
};
};
};
@ -174,16 +137,11 @@ namespace example
bsl::ut_scenario{"allocate invalid vmid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vp.allocate(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID, {}));
bsl::ut_check(!mut_vp.allocate({}, {}, {}, {}, syscall::BF_INVALID_ID, {}));
};
};
};
@ -191,16 +149,12 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vp.allocate(gs, tls, sys, intrinsic, {}, bsl::safe_uint16::failure()));
!mut_vp.allocate({}, {}, {}, {}, {}, bsl::safe_uint16::failure()));
};
};
};
@ -208,16 +162,11 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vp.allocate(gs, tls, sys, intrinsic, {}, syscall::BF_INVALID_ID));
bsl::ut_check(!mut_vp.allocate({}, {}, {}, {}, {}, syscall::BF_INVALID_ID));
};
};
};
@ -225,15 +174,11 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vp_t vp{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_t mut_vp{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vp.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vp.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vp.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vp.allocate({}, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vp_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vp_t m_vp{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vp_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vp_t{});
bsl::discard(m_vp.initialize(gs, tls, sys, intrinsic, {}));
m_vp.release(gs, tls, sys, intrinsic);
bsl::discard(m_vp.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,12 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vp_t vp{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_t mut_vp{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vp_t{}));
static_assert(noexcept(vp.initialize(gs, tls, sys, intrinsic, {})));
static_assert(noexcept(vp.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vp.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vp.initialize({}, {}, {}, {}, {})));
static_assert(noexcept(mut_vp.release({}, {}, {}, {})));
static_assert(noexcept(mut_vp.allocate({}, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,12 @@ namespace example
{
bsl::ut_scenario{"initialize vps_t reports failure"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
tls_t mut_tls{};
bsl::ut_when{} = [&]() noexcept {
tls.test_ret = bsl::errc_failure;
mut_tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(!mut_vps_pool.initialize({}, mut_tls, {}, {}));
};
};
};
@ -58,41 +55,29 @@ namespace example
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_check(mut_vps_pool.initialize({}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_then{} = [&]() noexcept {
vps_pool.release(gs, tls, sys, intrinsic);
mut_vps_pool.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_required_step(mut_vps_pool.initialize({}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vps_pool.release(gs, tls, sys, intrinsic);
mut_vps_pool.release({}, {}, {}, {});
};
};
};
@ -100,16 +85,13 @@ namespace example
bsl::ut_scenario{"allocate bf_vps_op_create_vps fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps_pool.initialize(gs, tls, sys, intrinsic));
sys.set_bf_vps_op_create_vps({}, {}, bsl::safe_uint16::failure());
bsl::ut_required_step(mut_vps_pool.initialize({}, {}, {}, {}));
mut_sys.set_bf_vps_op_create_vps({}, {}, bsl::safe_uint16::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -117,16 +99,13 @@ namespace example
bsl::ut_scenario{"allocate bf_vps_op_create_vps returns invalid id"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps_pool.initialize(gs, tls, sys, intrinsic));
sys.set_bf_vps_op_create_vps({}, {}, syscall::BF_INVALID_ID);
bsl::ut_required_step(mut_vps_pool.initialize({}, {}, {}, {}));
mut_sys.set_bf_vps_op_create_vps({}, {}, syscall::BF_INVALID_ID);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -134,16 +113,14 @@ namespace example
bsl::ut_scenario{"allocate vps_t allocate fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
tls_t mut_tls{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps_pool.initialize(gs, tls, sys, intrinsic));
tls.test_ret = bsl::errc_failure;
bsl::ut_required_step(mut_vps_pool.initialize({}, {}, {}, {}));
mut_tls.test_ret = bsl::errc_failure;
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps_pool.allocate({}, mut_tls, mut_sys, {}, {}, {}));
};
};
};
@ -151,15 +128,12 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_pool_t vps_pool{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_pool_t mut_vps_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps_pool.initialize(gs, tls, sys, intrinsic));
bsl::ut_required_step(mut_vps_pool.initialize({}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vps_pool.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vps_pool_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vps_pool_t m_vps_pool{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vps_pool_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vps_pool_t{});
bsl::discard(m_vps_pool.initialize(gs, tls, sys, intrinsic));
m_vps_pool.release(gs, tls, sys, intrinsic);
bsl::discard(m_vps_pool.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,13 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vps_pool_t vps_pool{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vps_pool_t mut_vps_pool{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vps_pool_t{}));
static_assert(noexcept(vps_pool.initialize(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps_pool.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps_pool.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vps_pool.initialize({}, {}, {}, {})));
static_assert(noexcept(mut_vps_pool.release({}, {}, {}, {})));
static_assert(noexcept(mut_vps_pool.allocate({}, {}, mut_sys, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -43,35 +43,29 @@ namespace example
{
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(intrinsic.initialize(gs, tls));
bsl::ut_check(mut_intrinsic.initialize({}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(intrinsic.initialize(gs, tls));
bsl::ut_required_step(mut_intrinsic.initialize({}, {}));
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
@ -79,22 +73,21 @@ namespace example
bsl::ut_scenario{"cpuid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
intrinsic_t const intrinsic{};
gs_t mut_gs{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
constexpr auto expected_result{42_u64};
bsl::ut_when{} = [&]() noexcept {
gs.cpuid_val = expected_result;
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
mut_gs.cpuid_val = expected_result;
intrinsic.cpuid(mut_gs, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(rax == expected_result);
bsl::ut_check(rbx == expected_result);
bsl::ut_check(rcx == expected_result);
bsl::ut_check(rdx == expected_result);
bsl::ut_check(mut_rax == expected_result);
bsl::ut_check(mut_rbx == expected_result);
bsl::ut_check(mut_rcx == expected_result);
bsl::ut_check(mut_rdx == expected_result);
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::intrinsic_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::intrinsic_t m_intrinsic{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - intrinsic_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
bsl::discard(example::intrinsic_t{});
bsl::discard(m_intrinsic.initialize(gs, tls));
m_intrinsic.release(gs, tls);
m_intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,28 +49,22 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::intrinsic_t intrinsic{};
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
example::intrinsic_t mut_intrinsic{};
example::intrinsic_t const intrinsic{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::intrinsic_t{}));
static_assert(noexcept(intrinsic.initialize(gs, tls)));
static_assert(noexcept(intrinsic.release(gs, tls)));
static_assert(noexcept(intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx)));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_intrinsic.initialize({}, {})));
static_assert(noexcept(mut_intrinsic.release({}, {})));
static_assert(
noexcept(mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
static_assert(
noexcept(intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -53,48 +53,29 @@ namespace example
{
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_then{} = [&]() noexcept {
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release({}, {}, {}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release({}, {}, {}, {}, {}, {});
};
};
};
@ -102,24 +83,18 @@ namespace example
bsl::ut_scenario{"dispatch cpuid stop"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_online_pps(online_pps);
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_online_pps(online_pps);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -127,25 +102,19 @@ namespace example
bsl::ut_scenario{"dispatch cpuid stop last ppid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_ppid(online_pps - 1_u16);
sys.bf_tls_set_online_pps(online_pps);
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_ppid(online_pps - 1_u16);
mut_sys.bf_tls_set_online_pps(online_pps);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -153,25 +122,19 @@ namespace example
bsl::ut_scenario{"dispatch cpuid stop bf_vps_op_advance_ip fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_online_pps(online_pps);
sys.set_bf_vps_op_advance_ip({}, bsl::errc_failure);
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_online_pps(online_pps);
mut_sys.set_bf_vps_op_advance_ip({}, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -179,22 +142,16 @@ namespace example
bsl::ut_scenario{"dispatch report on"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_ON));
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_ON));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -202,22 +159,16 @@ namespace example
bsl::ut_scenario{"dispatch report off"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_OFF));
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_OFF));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -225,25 +176,20 @@ namespace example
bsl::ut_scenario{"dispatch cpuid default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
intrinsic_t mut_intrinsic{};
constexpr auto exit_reason{0x72_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
intrinsic.set_cpuid(ANSWER32, ANSWER32, ANSWER32, ANSWER32);
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_intrinsic.set_cpuid(ANSWER32, ANSWER32, ANSWER32, ANSWER32);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(sys.bf_tls_rax() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rbx() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rcx() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rdx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_vmexit.dispatch(
{}, {}, mut_sys, mut_intrinsic, {}, {}, {}, exit_reason));
bsl::ut_check(mut_sys.bf_tls_rax() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rbx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rcx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rdx() == bsl::to_u64(ANSWER32));
};
};
};
@ -251,21 +197,15 @@ namespace example
bsl::ut_scenario{"dispatch invalid command"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x72_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
};
};
@ -273,19 +213,12 @@ namespace example
bsl::ut_scenario{"dispatch fails by default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize({}, {}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
bsl::ut_check(!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, {}));
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::vmexit_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vmexit_t m_vmexit{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vmexit_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::vmexit_t{});
bsl::discard(m_vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,30 +49,13 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vmexit_t vmexit{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::vmexit_t mut_vmexit{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vmexit_t{}));
static_assert(
noexcept(vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(noexcept(vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vmexit.initialize({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_vmexit.release({}, {}, {}, {}, {}, {})));
static_assert(noexcept(mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize twice fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, {}));
};
};
};
@ -58,68 +54,47 @@ namespace example
bsl::ut_scenario{"initialize invalid id #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(
!vps.initialize(gs, tls, sys, intrinsic, bsl::safe_uint16::failure()));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, bsl::safe_uint16::failure()));
};
};
};
bsl::ut_scenario{"initialize invalid id #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(!vps.initialize(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, syscall::BF_INVALID_ID));
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_check(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(mut_vps.initialize({}, {}, {}, {}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
vps.release(gs, tls, sys, intrinsic);
mut_vps.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vps.release(gs, tls, sys, intrinsic);
mut_vps.release({}, {}, {}, {});
};
};
};
@ -127,29 +102,23 @@ namespace example
bsl::ut_scenario{"allocate not initialized"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
bsl::ut_scenario{"allocate already allocated"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_required_step(mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -157,16 +126,13 @@ namespace example
bsl::ut_scenario{"allocate invalid vpid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(
gs, tls, sys, intrinsic, bsl::safe_uint16::failure(), {}));
bsl::ut_check(!mut_vps.allocate(
{}, {}, mut_sys, {}, bsl::safe_uint16::failure(), {}));
};
};
};
@ -174,16 +140,13 @@ namespace example
bsl::ut_scenario{"allocate invalid vpid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vps.allocate(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID, {}));
!mut_vps.allocate({}, {}, mut_sys, {}, syscall::BF_INVALID_ID, {}));
};
};
};
@ -191,16 +154,13 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(
gs, tls, sys, intrinsic, {}, bsl::safe_uint16::failure()));
bsl::ut_check(!mut_vps.allocate(
{}, {}, mut_sys, {}, {}, bsl::safe_uint16::failure()));
};
};
};
@ -208,16 +168,13 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vps.allocate(gs, tls, sys, intrinsic, {}, syscall::BF_INVALID_ID));
!mut_vps.allocate({}, {}, mut_sys, {}, {}, syscall::BF_INVALID_ID));
};
};
};
@ -225,90 +182,81 @@ namespace example
bsl::ut_scenario{"allocate bf_vps_op_init_as_root fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_init_as_root({}, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_init_as_root({}, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate when ppid does not match vpsid"} = []() noexcept {
bsl::ut_scenario{"allocate when ppid does not match mut_vpsid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto ppid{42_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.allocate(gs, tls, sys, intrinsic, {}, ppid));
bsl::ut_check(mut_vps.allocate({}, {}, mut_sys, {}, {}, ppid));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for asid"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for asid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x0058_u64};
constexpr auto val{0x1_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x1_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{}, syscall::bf_reg_t::bf_reg_t_guest_asid, val, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for intercept 1"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for intercept 1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x000C_u64};
constexpr auto val{0x00040000_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x00040000_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_intercept_instruction1,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for intercept 2"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for intercept 2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x0010_u64};
constexpr auto val{0x00000001_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x00000001_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_intercept_instruction2,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -316,15 +264,12 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vps_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vps_t m_vps{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vps_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vps_t{});
bsl::discard(m_vps.initialize(gs, tls, sys, intrinsic, {}));
m_vps.release(gs, tls, sys, intrinsic);
bsl::discard(m_vps.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,13 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vps_t vps{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vps_t{}));
static_assert(noexcept(vps.initialize(gs, tls, sys, intrinsic, {})));
static_assert(noexcept(vps.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vps.initialize({}, {}, {}, {}, {})));
static_assert(noexcept(mut_vps.release({}, {}, {}, {})));
static_assert(noexcept(mut_vps.allocate({}, {}, mut_sys, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -43,35 +43,29 @@ namespace example
{
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(intrinsic.initialize(gs, tls));
bsl::ut_check(mut_intrinsic.initialize({}, {}));
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
intrinsic_t mut_intrinsic{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(intrinsic.initialize(gs, tls));
bsl::ut_required_step(mut_intrinsic.initialize({}, {}));
bsl::ut_then{} = [&]() noexcept {
intrinsic.release(gs, tls);
mut_intrinsic.release({}, {});
};
};
};
@ -79,22 +73,21 @@ namespace example
bsl::ut_scenario{"cpuid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
intrinsic_t intrinsic{};
gs_t gs{};
tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
intrinsic_t const intrinsic{};
gs_t mut_gs{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
constexpr auto expected_result{42_u64};
bsl::ut_when{} = [&]() noexcept {
gs.cpuid_val = expected_result;
intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
mut_gs.cpuid_val = expected_result;
intrinsic.cpuid(mut_gs, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(rax == expected_result);
bsl::ut_check(rbx == expected_result);
bsl::ut_check(rcx == expected_result);
bsl::ut_check(rdx == expected_result);
bsl::ut_check(mut_rax == expected_result);
bsl::ut_check(mut_rbx == expected_result);
bsl::ut_check(mut_rcx == expected_result);
bsl::ut_check(mut_rdx == expected_result);
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::intrinsic_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::intrinsic_t m_intrinsic{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - intrinsic_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
bsl::discard(example::intrinsic_t{});
bsl::discard(m_intrinsic.initialize(gs, tls));
m_intrinsic.release(gs, tls);
m_intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx);
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,28 +49,22 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::intrinsic_t intrinsic{};
example::gs_t gs{};
example::tls_t tls{};
bsl::safe_uintmax rax{};
bsl::safe_uintmax rbx{};
bsl::safe_uintmax rcx{};
bsl::safe_uintmax rdx{};
example::intrinsic_t mut_intrinsic{};
example::intrinsic_t const intrinsic{};
bsl::safe_uintmax mut_rax{};
bsl::safe_uintmax mut_rbx{};
bsl::safe_uintmax mut_rcx{};
bsl::safe_uintmax mut_rdx{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::intrinsic_t{}));
static_assert(noexcept(intrinsic.initialize(gs, tls)));
static_assert(noexcept(intrinsic.release(gs, tls)));
static_assert(noexcept(intrinsic.cpuid(gs, tls, rax, rbx, rcx, rdx)));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_intrinsic.initialize({}, {})));
static_assert(noexcept(mut_intrinsic.release({}, {})));
static_assert(
noexcept(mut_intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
static_assert(
noexcept(intrinsic.cpuid({}, {}, mut_rax, mut_rbx, mut_rcx, mut_rdx)));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -53,441 +53,360 @@ namespace example
{
bsl::ut_scenario{"initialize bf_mem_op_alloc_page fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
sys.set_bf_mem_op_alloc_page(bsl::errc_failure);
mut_sys.set_bf_mem_op_alloc_page(bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(!mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_check(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = [&]() noexcept {
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
};
bsl::ut_scenario{"dispatch nmi bf_vps_op_read32 fails for proc ctls"} = []() noexcept {
bsl::ut_scenario{"dispatch nmi bf_vps_op_read fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0_u64};
constexpr auto idx{0x4002_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.set_bf_vps_op_read32({}, idx, bsl::safe_uint32::failure());
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.set_bf_vps_op_read(
{},
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi bf_vps_op_write32 fails for proc ctls"} = []() noexcept {
bsl::ut_scenario{"dispatch nmi bf_vps_op_write fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0_u64};
constexpr auto idx{0x4002_u64};
constexpr auto val{0x400000_u32};
constexpr auto val{0x400000_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi window bf_vps_op_read32 fails for proc ctls"} =
[]() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
constexpr auto exit_reason{0x8_u64};
constexpr auto idx{0x4002_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.set_bf_vps_op_read32({}, idx, bsl::safe_uint32::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
};
};
};
bsl::ut_scenario{"dispatch nmi bf_vps_op_write32 fails for proc ctls"} = []() noexcept {
bsl::ut_scenario{"dispatch nmi window bf_vps_op_read fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x8_u64};
constexpr auto idx{0x4002_u64};
constexpr auto val{0x0_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.set_bf_vps_op_read(
{},
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi bf_vps_op_write32 fails for int info"} = []() noexcept {
bsl::ut_scenario{"dispatch nmi bf_vps_op_write fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x8_u64};
constexpr auto idx{0x4016_u64};
constexpr auto val{0x80000202_u32};
constexpr auto val{0x0_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi bf_vps_op_write fails for int info"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x8_u64};
constexpr auto val{0x80000202_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_vmentry_interrupt_information_field,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch nmi window default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0x8_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch cpuid stop"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_online_pps(online_pps);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_online_pps(online_pps);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch cpuid stop last ppid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_ppid(online_pps - 1_u16);
sys.bf_tls_set_online_pps(online_pps);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_ppid(online_pps - 1_u16);
mut_sys.bf_tls_set_online_pps(online_pps);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch cpuid stop bf_vps_op_advance_ip fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
constexpr auto online_pps{0x2_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
sys.bf_tls_set_online_pps(online_pps);
sys.set_bf_vps_op_advance_ip({}, bsl::errc_failure);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_STOP));
mut_sys.bf_tls_set_online_pps(online_pps);
mut_sys.set_bf_vps_op_advance_ip({}, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch report on"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_ON));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_ON));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch report off"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_OFF));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
mut_sys.bf_tls_set_rcx(bsl::to_u64(loader::CPUID_COMMAND_ECX_REPORT_OFF));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch cpuid default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
intrinsic_t mut_intrinsic{};
constexpr auto exit_reason{0xA_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
intrinsic.set_cpuid(ANSWER32, ANSWER32, ANSWER32, ANSWER32);
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_intrinsic.set_cpuid(ANSWER32, ANSWER32, ANSWER32, ANSWER32);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(sys.bf_tls_rax() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rbx() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rcx() == bsl::to_u64(ANSWER32));
bsl::ut_check(sys.bf_tls_rdx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_vmexit.dispatch(
{}, {}, mut_sys, mut_intrinsic, {}, {}, {}, exit_reason));
bsl::ut_check(mut_sys.bf_tls_rax() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rbx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rcx() == bsl::to_u64(ANSWER32));
bsl::ut_check(mut_sys.bf_tls_rdx() == bsl::to_u64(ANSWER32));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch invalid command"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xA_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
mut_sys.bf_tls_set_rax(bsl::to_u64(loader::CPUID_COMMAND_EAX));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};
bsl::ut_scenario{"dispatch fails by default"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vmexit_t vmexit{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vp_pool_t vp_pool{};
vps_pool_t vps_pool{};
vmexit_t mut_vmexit{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto exit_reason{0xFF_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(
vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
bsl::ut_required_step(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vmexit.dispatch(
gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, exit_reason));
bsl::ut_check(
!mut_vmexit.dispatch({}, {}, mut_sys, {}, {}, {}, {}, exit_reason));
};
vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {});
};
};
};

View file

@ -30,43 +30,6 @@
namespace
{
constinit example::vmexit_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vmexit_t m_vmexit{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vmexit_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
bsl::discard(example::vmexit_t{});
bsl::discard(m_vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool));
m_vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool);
bsl::discard(m_vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -86,30 +49,15 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vmexit_t vmexit{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vp_pool_t vp_pool{};
example::vps_pool_t vps_pool{};
example::vmexit_t mut_vmexit{};
example::gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vmexit_t{}));
static_assert(noexcept(mut_vmexit.initialize(mut_gs, {}, mut_sys, {}, {}, {})));
static_assert(noexcept(mut_vmexit.release(mut_gs, {}, mut_sys, {}, {}, {})));
static_assert(
noexcept(vmexit.initialize(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(noexcept(vmexit.release(gs, tls, sys, intrinsic, vp_pool, vps_pool)));
static_assert(
noexcept(vmexit.dispatch(gs, tls, sys, intrinsic, vp_pool, vps_pool, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
noexcept(mut_vmexit.dispatch(mut_gs, {}, mut_sys, {}, {}, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

View file

@ -42,15 +42,11 @@ namespace example
{
bsl::ut_scenario{"initialize twice fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, {}));
};
};
};
@ -58,41 +54,28 @@ namespace example
bsl::ut_scenario{"initialize invalid id #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vps.initialize(gs, tls, sys, intrinsic, bsl::safe_uint16::failure()));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, bsl::safe_uint16::failure()));
};
};
};
bsl::ut_scenario{"initialize invalid id #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.initialize(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID));
bsl::ut_check(!mut_vps.initialize({}, {}, {}, {}, syscall::BF_INVALID_ID));
};
};
};
bsl::ut_scenario{"initialize success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_check(mut_vps.initialize({}, {}, {}, {}, {}));
};
};
};
@ -100,28 +83,20 @@ namespace example
bsl::ut_scenario{"release executes without initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
vps.release(gs, tls, sys, intrinsic);
mut_vps.release({}, {}, {}, {});
};
};
};
bsl::ut_scenario{"release executes with initialize"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
vps.release(gs, tls, sys, intrinsic);
mut_vps.release({}, {}, {}, {});
};
};
};
@ -129,29 +104,23 @@ namespace example
bsl::ut_scenario{"allocate not initialized"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
bsl::ut_scenario{"allocate already allocated"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_required_step(mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -159,16 +128,13 @@ namespace example
bsl::ut_scenario{"allocate invalid vpid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(
gs, tls, sys, intrinsic, bsl::safe_uint16::failure(), {}));
bsl::ut_check(!mut_vps.allocate(
{}, {}, mut_sys, {}, bsl::safe_uint16::failure(), {}));
};
};
};
@ -176,16 +142,13 @@ namespace example
bsl::ut_scenario{"allocate invalid vpid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vps.allocate(gs, tls, sys, intrinsic, syscall::BF_INVALID_ID, {}));
!mut_vps.allocate({}, {}, mut_sys, {}, syscall::BF_INVALID_ID, {}));
};
};
};
@ -193,16 +156,13 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #1"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(
gs, tls, sys, intrinsic, {}, bsl::safe_uint16::failure()));
bsl::ut_check(!mut_vps.allocate(
{}, {}, mut_sys, {}, {}, bsl::safe_uint16::failure()));
};
};
};
@ -210,16 +170,13 @@ namespace example
bsl::ut_scenario{"allocate invalid ppid #2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(
!vps.allocate(gs, tls, sys, intrinsic, {}, syscall::BF_INVALID_ID));
!mut_vps.allocate({}, {}, mut_sys, {}, {}, syscall::BF_INVALID_ID));
};
};
};
@ -227,71 +184,62 @@ namespace example
bsl::ut_scenario{"allocate bf_vps_op_init_as_root fails"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_init_as_root({}, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_init_as_root({}, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate when ppid does not match vpsid"} = []() noexcept {
bsl::ut_scenario{"allocate when ppid does not match mut_vpsid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto ppid{42_u16};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.allocate(gs, tls, sys, intrinsic, {}, ppid));
bsl::ut_check(mut_vps.allocate({}, {}, mut_sys, {}, {}, ppid));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write16 fails for vpid"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for vpid"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x0000_u64};
constexpr auto val{0x1_u16};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x1_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write16({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_virtual_processor_identifier,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write64 fails for link ptr"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for link ptr"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x2800_u64};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0xFFFFFFFFFFFFFFFF_u64};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write64({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{}, syscall::bf_reg_t::bf_reg_t_vmcs_link_pointer, val, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -299,38 +247,35 @@ namespace example
bsl::ut_scenario{"allocate bf_intrinsic_op_rdmsr fails for pin ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto msr{0x48D_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for pin ctls"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for pin ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x4000_u64};
constexpr auto val{0x0_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x0_u64};
constexpr auto msr{0x48D_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, {});
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, {});
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_pin_based_vm_execution_ctls,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -338,38 +283,35 @@ namespace example
bsl::ut_scenario{"allocate bf_intrinsic_op_rdmsr fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto msr{0x48E_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for proc ctls"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for proc ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x4002_u64};
constexpr auto val{0x0_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x0_u64};
constexpr auto msr{0x48E_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, {});
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, {});
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_primary_proc_based_vm_execution_ctls,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -377,38 +319,32 @@ namespace example
bsl::ut_scenario{"allocate bf_intrinsic_op_rdmsr fails for exit ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto msr{0x48F_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for exit ctls"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for exit ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x400C_u64};
constexpr auto val{0x0_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x0_u64};
constexpr auto msr{0x48F_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, {});
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, {});
mut_sys.set_bf_vps_op_write(
{}, syscall::bf_reg_t::bf_reg_t_vmexit_ctls, val, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -416,38 +352,32 @@ namespace example
bsl::ut_scenario{"allocate bf_intrinsic_op_rdmsr fails for entry ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto msr{0x490_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for entry ctls"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for entry ctls"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x4012_u64};
constexpr auto val{0x0_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x0_u64};
constexpr auto msr{0x490_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, {});
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, {});
mut_sys.set_bf_vps_op_write(
{}, syscall::bf_reg_t::bf_reg_t_vmentry_ctls, val, bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
@ -455,58 +385,56 @@ namespace example
bsl::ut_scenario{"allocate bf_intrinsic_op_rdmsr fails for proc ctls2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto msr{0x48B_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, bsl::safe_uint64::failure());
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write32 fails for proc ctls2"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for proc ctls2"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x401E_u64};
constexpr auto val{0x0_u32};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{0x0_u64};
constexpr auto msr{0x48B_u32};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_intrinsic_op_rdmsr(msr, {});
sys.set_bf_vps_op_write32({}, idx, val, bsl::errc_failure);
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_intrinsic_op_rdmsr(msr, {});
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_secondary_proc_based_vm_execution_ctls,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};
};
bsl::ut_scenario{"allocate bf_vps_op_write64 fails for msr bitmap"} = []() noexcept {
bsl::ut_scenario{"allocate bf_vps_op_write fails for msr bitmap"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
constexpr auto idx{0x2004_u64};
vps_t mut_vps{};
gs_t mut_gs{};
syscall::bf_syscall_t mut_sys{};
constexpr auto val{42_umax};
bsl::ut_when{} = [&]() noexcept {
gs.msr_bitmap_phys = val;
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
sys.set_bf_vps_op_write64({}, idx, val, bsl::errc_failure);
mut_gs.msr_bitmap_phys = val;
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
mut_sys.set_bf_vps_op_write(
{},
syscall::bf_reg_t::bf_reg_t_address_of_msr_bitmaps,
val,
bsl::errc_failure);
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(!vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(!mut_vps.allocate(mut_gs, {}, mut_sys, {}, {}, {}));
};
};
};
@ -514,15 +442,12 @@ namespace example
bsl::ut_scenario{"allocate success"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
vps_t vps{};
gs_t gs{};
tls_t tls{};
syscall::bf_syscall_t sys{};
intrinsic_t intrinsic{};
vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_when{} = [&]() noexcept {
bsl::ut_required_step(vps.initialize(gs, tls, sys, intrinsic, {}));
bsl::ut_required_step(mut_vps.initialize({}, {}, {}, {}, {}));
bsl::ut_then{} = [&]() noexcept {
bsl::ut_check(vps.allocate(gs, tls, sys, intrinsic, {}, {}));
bsl::ut_check(mut_vps.allocate({}, {}, mut_sys, {}, {}, {}));
};
};
};

View file

@ -30,41 +30,6 @@
namespace
{
constinit example::vps_t const g_verify_constinit{};
// NOLINTNEXTLINE(bsl-user-defined-type-names-match-header-name)
class fixture_t final
{
example::vps_t m_vps{};
public:
[[nodiscard]] static constexpr auto
test_member_const() noexcept -> bool
{
/// NOTE:
/// - vps_t does not contain const member functions
///
return true;
}
[[nodiscard]] constexpr auto
test_member_nonconst() noexcept -> bool
{
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
bsl::discard(example::vps_t{});
bsl::discard(m_vps.initialize(gs, tls, sys, intrinsic, {}));
m_vps.release(gs, tls, sys, intrinsic);
bsl::discard(m_vps.allocate(gs, tls, sys, intrinsic, {}, {}));
return true;
}
};
constexpr fixture_t FIXTURE1{};
}
/// <!-- description -->
@ -84,26 +49,13 @@ main() noexcept -> bsl::exit_code
bsl::ut_scenario{"verify noexcept"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
example::vps_t vps{};
example::gs_t gs{};
example::tls_t tls{};
syscall::bf_syscall_t sys{};
example::intrinsic_t intrinsic{};
example::vps_t mut_vps{};
syscall::bf_syscall_t mut_sys{};
bsl::ut_then{} = []() noexcept {
static_assert(noexcept(example::vps_t{}));
static_assert(noexcept(vps.initialize(gs, tls, sys, intrinsic, {})));
static_assert(noexcept(vps.release(gs, tls, sys, intrinsic)));
static_assert(noexcept(vps.allocate(gs, tls, sys, intrinsic, {}, {})));
};
};
};
bsl::ut_scenario{"verify constness"} = []() noexcept {
bsl::ut_given{} = []() noexcept {
fixture_t fixture2{};
bsl::ut_then{} = [&]() noexcept {
static_assert(FIXTURE1.test_member_const());
bsl::ut_check(fixture2.test_member_nonconst());
static_assert(noexcept(mut_vps.initialize({}, {}, {}, {}, {})));
static_assert(noexcept(mut_vps.release({}, {}, {}, {})));
static_assert(noexcept(mut_vps.allocate({}, {}, mut_sys, {}, {}, {})));
};
};
};

View file

@ -49,11 +49,7 @@
# using constinit, constness and noexcept. None of the code in this test
# actually runs and instead it is there to ensure the code signatures make
# sense. The "behavior" test is where the code is actually executed to make
# sure it executes as expected. This code will run the tests both at compile
# time and at runtime. If a specific test cannot be run at compile time
# (which hopefully is minimal if the code is structured properly), you can
# use the bsl::ut_given_at_runtime instead of bsl::ut_given, which will
# exclude the test from compile time checks.
# sure it executes as expected.
#
# - Each test only includes the one thing that is trying to test. For example,
# suppose we are testing the bootstrap_t logic. This file includes a number

Some files were not shown because too many files have changed in this diff Show more