bareflank-hypervisor/docs/Microkernel Syscall Specification.md
Rian Quinn f5f39193e5 Unit/Integration Test and ARM support changes
This patch contains a massive number of changes that are the
result of finally adding unit/integration tests and ARM
support. ARM support moved a number of files that were duplicates
while the unit and integration tests identified a massive number
of structural issues. The cost of waiting so long to finally
add tests.
2021-06-29 20:30:53 -06:00

74 KiB

Table of Contents

1. Introduction

TBD

This specification is specific to 64bit Intel and AMD processors conforming to the amd64 specification. Future revisions of this specification may include ARM64 conforming to the aarch64 specification as well.

1.1. Reserved Values

Name Description
REVZ reserved zero
REVI reserved ignore

1.2. Document Revision

Version Description
Mk#1 The initial version of this specification

1.3. Glossary

Abbreviation Description
VM Virtual Machine
VP Virtual Processor
VPS Virtual Processor State
PP Physical Processor
VMID Virtual Machine Identifier
VPID Virtual Processor Identifier
VPSID Virtual Processor State Identifier
PPID Physical Processor Identifier
OS Operating System
BIOS Basic Input/Output System
UEFI Unified Extensible Firmware Interface
SPA A System Physical Address (SPA) refers to a physical address as seen by the system without the addition of virtualization
GPA A Guest Physical Address (GPA) refers to a physical address as seen by a VM and requires a translation to convert to a SPA
GVA A Guest Virtual Address (GVA) refers to a virtual address as seen by a VM and requires a guest controlled translation to convert to a GPA
Page Aligned A region of memory whose address is divisible by 0x1000
Page A page aligned region of memory that is 0x1000 bytes in size

1.4. Scalar Types

Name Type Description
bf_status_t uint64_t Defines the type used for returning status from a function
bf_uint8_t uint8_t Defines an unsigned 8bit integer
bf_uint16_t uint16_t Defines an unsigned 16bit integer
bf_uint32_t uint32_t Defines an unsigned 32bit integer
bf_uint64_t uint64_t Defines an unsigned 64bit integer
bf_ptr_t void * Defines a raw pointer type
bf_cptr_t void const * Defines a raw const pointer type

1.5. ID Types

Name Type
Virtual Machine ID (VMID) bf_uint64_t
Virtual Processor ID (VPID) bf_uint64_t
Virtual Processor State ID (VPSID) bf_uint64_t
Physical Processor ID (PPID) bf_uint64_t

1.6. Constants, Structures, Enumerations, and Bit Fields

1.6.1. Null

*const, void : BF_NULL

Value Description
0 Defines the value of a null pointer

1.6.2. Handle Type

The bf_handle_t structure is an opaque structure containing the handle used by most of the syscalls in this specification. The opaque structure is used internally by the C wrapper interface and should not be accessed directly. The C wrapper is allowed to redefine the internal layout of this structure at any time (e.g., the C wrapper might provide an alternative layout for unit testing).

struct: bf_handle_t

Name Type Offset Size Description
hndl bf_uint64_t 0x0 8 bytes The handle returned by bf_handle_op_open_handle

1.6.3. Register Type

Defines which register a syscall is requesting.

enum, bf_uint64_t: bf_reg_t

Name Value Description
bf_reg_t_rax 0 defines the rax register
bf_reg_t_rbx 1 defines the rbx register
bf_reg_t_rcx 2 defines the rcx register
bf_reg_t_rdx 3 defines the rdx register
bf_reg_t_rbp 4 defines the rbp register
bf_reg_t_rsi 5 defines the rsi register
bf_reg_t_rdi 6 defines the rdi register
bf_reg_t_r8 7 defines the r8 register
bf_reg_t_r9 8 defines the r9 register
bf_reg_t_r10 9 defines the r10 register
bf_reg_t_r11 10 defines the r11 register
bf_reg_t_r12 11 defines the r12 register
bf_reg_t_r13 12 defines the r13 register
bf_reg_t_r14 13 defines the r14 register
bf_reg_t_r15 14 defines the r15 register
bf_reg_t_rip 15 defines the rip register
bf_reg_t_rsp 16 defines the rsp register
bf_reg_t_rflags 17 defines the rflags register
bf_reg_t_gdtr_base_addr 18 defines the gdtr_base_addr register
bf_reg_t_gdtr_limit 19 defines the gdtr_limit register
bf_reg_t_idtr_base_addr 20 defines the idtr_base_addr register
bf_reg_t_idtr_limit 21 defines the idtr_limit register
bf_reg_t_es 22 defines the es register
bf_reg_t_es_base_addr 23 defines the es_base_addr register
bf_reg_t_es_limit 24 defines the es_limit register
bf_reg_t_es_attributes 25 defines the es_attributes register
bf_reg_t_cs 26 defines the cs register
bf_reg_t_cs_base_addr 27 defines the cs_base_addr register
bf_reg_t_cs_limit 28 defines the cs_limit register
bf_reg_t_cs_attributes 29 defines the cs_attributes register
bf_reg_t_ss 30 defines the ss register
bf_reg_t_ss_base_addr 31 defines the ss_base_addr register
bf_reg_t_ss_limit 32 defines the ss_limit register
bf_reg_t_ss_attributes 33 defines the ss_attributes register
bf_reg_t_ds 34 defines the ds register
bf_reg_t_ds_base_addr 35 defines the ds_base_addr register
bf_reg_t_ds_limit 36 defines the ds_limit register
bf_reg_t_ds_attributes 37 defines the ds_attributes register
bf_reg_t_fs 38 defines the fs register
bf_reg_t_fs_base_addr 39 defines the fs_base_addr register
bf_reg_t_fs_limit 40 defines the fs_limit register
bf_reg_t_fs_attributes 41 defines the fs_attributes register
bf_reg_t_gs 42 defines the gs register
bf_reg_t_gs_base_addr 43 defines the gs_base_addr register
bf_reg_t_gs_limit 44 defines the gs_limit register
bf_reg_t_gs_attributes 45 defines the gs_attributes register
bf_reg_t_ldtr 46 defines the ldtr register
bf_reg_t_ldtr_base_addr 47 defines the ldtr_base_addr register
bf_reg_t_ldtr_limit 48 defines the ldtr_limit register
bf_reg_t_ldtr_attributes 49 defines the ldtr_attributes register
bf_reg_t_tr 50 defines the tr register
bf_reg_t_tr_base_addr 51 defines the tr_base_addr register
bf_reg_t_tr_limit 52 defines the tr_limit register
bf_reg_t_tr_attributes 53 defines the tr_attributes register
bf_reg_t_cr0 54 defines the cr0 register
bf_reg_t_cr2 55 defines the cr2 register
bf_reg_t_cr3 56 defines the cr3 register
bf_reg_t_cr4 57 defines the cr4 register
bf_reg_t_dr6 58 defines the dr6 register
bf_reg_t_dr7 59 defines the dr7 register
bf_reg_t_ia32_efer 60 defines the ia32_efer register
bf_reg_t_ia32_star 61 defines ia32_star register
bf_reg_t_ia32_lstar 62 defines ia32_lstar register
bf_reg_t_ia32_cstar 63 defines ia32_cstar register
bf_reg_t_ia32_fmask 64 defines ia32_fmask register
bf_reg_t_ia32_fs_base 65 defines ia32_fs_base register
bf_reg_t_ia32_gs_base 66 defines ia32_gs_base register
bf_reg_t_ia32_kernel_gs_base 67 defines ia32_kernel_gs_base register
bf_reg_t_ia32_sysenter_cs 68 defines ia32_sysenter_cs register
bf_reg_t_ia32_sysenter_esp 69 defines ia32_sysenter_esp register
bf_reg_t_ia32_sysenter_eip 70 defines ia32_sysenter_eip register
bf_reg_t_ia32_pat 71 defines ia32_pat register
bf_reg_t_ia32_debugctl 72 defines ia32_debugctl register

1.6.4. Exit Type

Defines the exit type used by bf_control_op_exit

enum, bf_uint64_t: bf_exit_status_t

Name Value Description
bf_exit_status_t_success 0 Exit with a success code
bf_exit_status_t_failure 1 Exit with a failure code

1.6.5. Bootstrap Callback Handler Type

Defines the signature of the bootstrap callback handler

*typedef, void(bf_callback_handler_bootstrap_t)(bf_uint16_t)

1.6.6. VMExit Callback Handler Type

Defines the signature of the VM exit callback handler

*typedef, void(bf_callback_handler_vmexit_t)(bsl::bf_uint16_t, bf_uint64_t)

1.6.7. Fast Fail Callback Handler Type

Defines the signature of the fast fail callback handler

*typedef, void(bf_callback_handler_fail_t)(bf_status_t)

1.7. Invalid ID

The following defines an invalid ID which can be used for all ID types.

const, bf_uint16_t: BF_INVALID_ID

Value Description
0xFFFF Defines an invalid ID for an extension, VM, VP and VPS

const, bf_uint16_t: BF_BS_PPID

Value Description
0x0 Defines the bootstrap physical processor ID

const, bf_uint16_t: BF_ROOT_VMID

Value Description
0x0 Defines the root virtual machine ID

1.8. Host PAT (Intel/AMD Only)

The host PAT has the following layout. Indexes marked as XX are reserved for future use.

const, bf_uint64_t: BF_HOST_PAT

Value Description
0xXXXXXXXX00XXXX06 Defines the host PAT value

1.9. Endianness

This document only applies to 64bit Intel and AMD systems conforming to the amd64 architecture. As such, this document conforms to little-endian.

2. Syscall Interface

The following section defines the syscall interface used by this specification, and therefore Bareflank.

Kernel and user-space can execute syscalls from 64bit mode.

2.2. Syscall Status Codes

Every syscall returns a bf_status_t to indicate the success or failure of a syscall after execution. The following defines the layout of bf_status_t:

Bits Name Description
63:48 BF_STATUS_SIG Contains 0x0000 on success, 0xDEAD on failure
47:16 BF_STATUS_FLAGS Contains the flags associated with the bf_status_t
15:0 BF_STATUS_VALUE Contains the value of the bf_status_t

BF_STATUS_VALUE defines success or which type of error occurred. BF_STATUS_FLAGS provides additional information about why the error occurred. BF_STATUS_FLAGS is optional and used solely for diagnostics. As such, the microkernel may or may not provide it.

2.2.1. BF_STATUS_SUCCESS, VALUE=0

const, bf_status_t: BF_STATUS_SUCCESS

Value Description
0x0000000000000000 Used to indicated that the syscall returned successfully

2.2.2. BF_STATUS_FAILURE, VALUE=1

const, bf_status_t: BF_STATUS_FAILURE_UNKNOWN

Value Description
0xDEAD000000010001 Indicates an unknown error occurred

const, bf_status_t: BF_STATUS_FAILURE_UNSUPPORTED

Value Description
0xDEAD000000020001 Indicates the syscall is unsupported

const, bf_status_t: BF_STATUS_FAILURE_INVALID_HANDLE

Value Description
0xDEAD000000040001 Indicates the provided handle is invalid

2.2.3. BF_STATUS_INVALID_PERM, VALUE=2

BF_STATUS_INVALID_PERM defines a permissions failure.

const, bf_status_t: BF_STATUS_INVALID_PERM_EXT

Value Description
0xDEAD000000010002 Indicates the extension is not allowed to execute this syscall

const, bf_status_t: BF_STATUS_INVALID_PERM_DENIED

Value Description
0xDEAD000000020002 Indicates the policy engine denied the syscall

2.2.4. BF_STATUS_INVALID_PARAMS, VALUE=3

BF_STATUS_INVALID_PARAMS defines that one or more input/output parameters provided to the C wrapper was invalid.

const, bf_status_t: BF_STATUS_INVALID_PARAMS0

Value Description
0xDEAD000000010003 Indicates param 0 is invalid

const, bf_status_t: BF_STATUS_INVALID_PARAMS1

Value Description
0xDEAD000000020003 Indicates param 1 is invalid

const, bf_status_t: BF_STATUS_INVALID_PARAMS2

Value Description
0xDEAD000000040003 Indicates param 2 is invalid

const, bf_status_t: BF_STATUS_INVALID_PARAMS3

Value Description
0xDEAD000000080003 Indicates param 3 is invalid

const, bf_status_t: BF_STATUS_INVALID_PARAMS4

Value Description
0xDEAD000000100003 Indicates param 4 is invalid

const, bf_status_t: BF_STATUS_INVALID_PARAMS5

Value Description
0xDEAD000000200003 Indicates param 5 is invalid

2.3. Syscall Inputs

Before software can execute a syscall, it must first open a handle to the syscall interface by executing the bf_handle_op_open_handle syscall. This handle must be provided as the first argument to each syscall in RDI (i.e., REG0) and can be released using the bf_handle_op_close_handle syscall.

RDI:

Bits Name Description
63:0 BF_HANDLE The result of bf_handle_op_open_handle

Every syscall must provide information about the syscall by filling out RAX as follows:

RAX:

Bits Name Description
63:48 BF_SYSCALL_SIG 0x6642 = "Bf"
47:32 BF_SYSCALL_FLAGS Contains the syscall's flags
31:16 BF_SYSCALL_OP Contains the syscall's opcode
15:0 BF_SYSCALL_IDX Contains the syscall's index

const, bf_uint64_t: BF_SYSCALL_SIG_VAL

Value Description
0x6642000000000000 Defines the BF_SYSCALL_SIG field for RAX

const, bf_uint64_t: BF_HYPERCALL_SIG_MASK

Value Description
0xFFFF000000000000 Defines a mask for BF_SYSCALL_SIG

const, bf_uint64_t: BF_HYPERCALL_FLAGS_MASK

Value Description
0x0000FFFF00000000 Defines a mask for BF_SYSCALL_FLAGS

const, bf_uint64_t: BF_HYPERCALL_OPCODE_MASK

Value Description
0xFFFF0000FFFF0000 Defines a mask for BF_SYSCALL_OP

const, bf_uint64_t: BF_HYPERCALL_OPCODE_NOSIG_MASK

Value Description
0x00000000FFFF0000 Defines a mask for BF_SYSCALL_OP (with no signature added)

const, bf_uint64_t: BF_HYPERCALL_INDEX_MASK

Value Description
0x000000000000FFFF Defines a mask for BF_SYSCALL_IDX

BF_SYSCALL_SIG is used to ensure the syscall is, in fact, a Bareflank specific syscall. BF_SYSCALL_FLAGS is used to provide additional syscall options.

BF_SYSCALL_OP determines which opcode the syscall belongs to, logically grouping syscalls based on their function. BF_SYSCALL_OP is also used internally within the microkernel to dispatch the syscall to the proper handler. BF_SYSCALL_IDX, when combined with BF_SYSCALL_OP, uniquely identifies a specific syscall. This specification tightly packs the values assigned to both BF_SYSCALL_IDX and BF_SYSCALL_OP to ensure Bareflank (and variants) can use jump tables instead of branch logic (depends on the trade-off between retpoline mitigations and branch induced pipeline stalls).

The following defines the input registers for x64 based systems (i.e., x86_64 and amd64):

Arguments:

Register Name Description
RDI Set to the result of bf_handle_op_open_handle
RSI Stores the value of REG1 (syscall specific)
RDX Stores the value of REG2 (syscall specific)
R10 Stores the value of REG3 (syscall specific)
R8 Stores the value of REG4 (syscall specific)
R9 Stores the value of REG5 (syscall specific)

All unused registers by any syscall are considered REVI.

2.4. Syscall Outputs

After executing a syscall, a bf_status_t is returned in RAX to indicate if the syscall succeeded or failed and why.

RAX:

Bits Name Description
63:0 BF_STATUS Contains the value of bf_status_t

The following defines the output registers for x64 based systems (i.e., x86_64 and amd64):

Arguments:

Register Name Description
RDI Stores the value of REG0 (syscall specific)
RSI Stores the value of REG1 (syscall specific)
RDX Stores the value of REG2 (syscall specific)
R10 Stores the value of REG3 (syscall specific)
R8 Stores the value of REG4 (syscall specific)
R9 Stores the value of REG5 (syscall specific)

2.5. Syscall Opcodes

The following sections define the different opcodes that are supported by this specification. Note that each opcode includes the syscall signature making it easier to validate if the syscall is supported or not.

2.5.1. Control Support

const, bf_uint64_t: BF_CONTROL_OP_VAL

Value Description
0x6642000000000000 Defines the syscall opcode for bf_control_op

const, bf_uint64_t: BF_CONTROL_OP_NOSIG_VAL

Value Description
0x0000000000000000 Defines the syscall opcode for bf_control_op (nosig)

2.5.2. Handle Support

const, bf_uint64_t: BF_HANDLE_OP_VAL

Value Description
0x6642000000010000 Defines the syscall opcode for bf_handle_op

const, bf_uint64_t: BF_HANDLE_OP_NOSIG_VAL

Value Description
0x0000000000010000 Defines the syscall opcode for bf_handle_op (nosig)

2.5.3. Debug Support

const, bf_uint64_t: BF_DEBUG_OP_VAL

Value Description
0x6642000000020000 Defines the syscall opcode for bf_debug_op

const, bf_uint64_t: BF_DEBUG_OP_NOSIG_VAL

Value Description
0x00000000000020000 Defines the syscall opcode for bf_debug_op (nosig)

2.5.4. Callback Support

const, bf_uint64_t: BF_CALLBACK_OP_VAL

Value Description
0x6642000000030000 Defines the syscall opcode for bf_callback_op

const, bf_uint64_t: BF_CALLBACK_OP_NOSIG_VAL

Value Description
0x0000000000030000 Defines the syscall opcode for bf_callback_op (nosig)

2.5.5. VM Support

const, bf_uint64_t: BF_VM_OP_VAL

Value Description
0x6642000000040000 Defines the syscall opcode for bf_vm_op

const, bf_uint64_t: BF_VM_OP_NOSIG_VAL

Value Description
0x0000000000040000 Defines the syscall opcode for bf_vm_op (nosig)

2.5.6. VP Support

const, bf_uint64_t: BF_VP_OP_VAL

Value Description
0x6642000000050000 Defines the syscall opcode for bf_vp_op

const, bf_uint64_t: BF_VP_OP_NOSIG_VAL

Value Description
0x0000000000050000 Defines the syscall opcode for bf_vp_op (nosig)

2.5.7. VPS Support

const, bf_uint64_t: BF_VPS_OP_VAL

Value Description
0x6642000000060000 Defines the syscall opcode for bf_vps_op

const, bf_uint64_t: BF_VPS_OP_NOSIG_VAL

Value Description
0x0000000000060000 Defines the syscall opcode for bf_vps_op (nosig)

2.5.8. Intrinsic Support

const, bf_uint64_t: BF_INTRINSIC_OP_VAL

Value Description
0x6642000000070000 Defines the syscall opcode for bf_intrinsic_op

const, bf_uint64_t: BF_INTRINSIC_OP_NOSIG_VAL

Value Description
0x0000000000070000 Defines the syscall opcode for bf_intrinsic_op (nosig)

2.5.9. Mem Support

const, bf_uint64_t: BF_MEM_OP_VAL

Value Description
0x6642000000080000 Defines the syscall opcode for bf_mem_op

const, bf_uint64_t: BF_MEM_OP_NOSIG_VAL

Value Description
0x0000000000080000 Defines the syscall opcode for bf_mem_op (nosig)

2.5.10. Syscall Specification IDs

The following defines the specification IDs used when opening a handle. These provide software with a means to define which specification it implements. bf_handle_op_version defines which version of this spec the microkernel supports. For example, if bf_handle_op_version returns 0x2, it means that it supports version #1 of this spec, in which case, an extension can open a handle with BF_SPEC_ID1_VAL. If bf_handle_op_version returns a value of 0x6, it would mean that an extension could open a handle with BF_SPEC_ID1_VAL or BF_SPEC_ID2_VAL. Likewise, if bf_handle_op_version returns 0x4, it means that BF_SPEC_ID1_VAL is no longer supported, and the extension must open the handle with BF_SPEC_ID2_VAL.

const, bf_uint32_t: BF_SPEC_ID1_VAL

Value Description
0x31236642 Defines the ID for version #1 of this spec

const, bf_uint32_t: BF_SPEC_ID1_MASK

Value Description
0x2 Defines the mask for checking support for version #1 of this spec

const, bf_uint32_t: BF_ALL_SPECS_SUPPORTED_VAL

Value Description
0x2 Defines the value likely returned by bf_handle_op_version

2.6. Thread Local Storage

The microkernel defines a "thread" the same way both Intel and AMD define a thread (i.e., a logical core). For example, some Intel CPUs have 4 cores and 8 threads when hyper-threading is enabled, or 4 cores and 4 threads when hyper-threading is disabled. Each logical core is given one "thread" and that thread always executes on that logical core. The microkernel defines these logical cores as physical processors (i.e., PP).

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.

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.

2.6.1. TLS Offsets

*consts, void : bf_uint64_t

Name Value Description
TLS_OFFSET_RAX 0x800U stores the offset for rax
TLS_OFFSET_RBX 0x808U stores the offset for rbx
TLS_OFFSET_RCX 0x810U stores the offset for rcx
TLS_OFFSET_RDX 0x818U stores the offset for rdx
TLS_OFFSET_RBP 0x820U stores the offset for rbp
TLS_OFFSET_RSI 0x828U stores the offset for rsi
TLS_OFFSET_RDI 0x830U stores the offset for rdi
TLS_OFFSET_R8 0x838U stores the offset for r8
TLS_OFFSET_R9 0x840U stores the offset for r9
TLS_OFFSET_R10 0x848U stores the offset for r10
TLS_OFFSET_R11 0x850U stores the offset for r11
TLS_OFFSET_R12 0x858U stores the offset for r12
TLS_OFFSET_R13 0x860U stores the offset for r13
TLS_OFFSET_R14 0x868U stores the offset for r14
TLS_OFFSET_R15 0x870U stores the offset for r15
TLS_OFFSET_ACTIVE_EXTID 0xFF0U stores the offset of the active extid
TLS_OFFSET_ACTIVE_VMID 0xFF2U stores the offset of the active vmid
TLS_OFFSET_ACTIVE_VPID 0xFF4U stores the offset of the active vpid
TLS_OFFSET_ACTIVE_VPSID 0xFF6U stores the offset of the active vpsid
TLS_OFFSET_ACTIVE_PPID 0xFF8U stores the offset of the active ppid
TLS_OFFSET_ONLINE_PPS 0xFFAU stores the number of PPs that are online

2.7. Control Syscalls

2.7.1. bf_control_op_exit, OP=0x0, IDX=0x0

This syscall tells the microkernel to stop the execution of an extension, providing a means to fast fail.

const, bf_uint64_t: BF_CONTROL_OP_EXIT_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_control_op_exit

2.10.1. bf_control_op_wait, OP=0x0, IDX=0x1

This syscall tells the microkernel that the extension would like to wait for a callback. This syscall is a blocking syscall that never returns and should be used to return from the _start function.

const, bf_uint64_t: BF_CONTROL_OP_WAIT_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_control_op_wait

2.8. Handle Syscalls

2.8.1. bf_handle_op_open_handle, OP=0x1, IDX=0x0

This syscall returns the handle that is required to execute the remaining syscalls. Some versions of Bareflank might provide a certain degree of backward compatibility, queried using bf_handle_op_version. The version argument of this syscall indicates to the microkernel which version of this spec the software supports. If the software provides a version that Bareflank doesn't support (i.e., a version that is not listed by bf_handle_op_version), this syscall will fail.

Input:

Register Name Bits Description
REG0 31:0 The version of this spec that software supports
REG0 63:32 REVI

Output:

Register Name Bits Description
REG0 63:0 The value to set REG0 to for most other syscalls

const, bf_uint64_t: BF_HANDLE_OP_OPEN_HANDLE_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_handle_op_open_handle

2.8.2. bf_handle_op_close_handle, OP=0x1, IDX=0x1

This syscall closes a previously opened handle.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle

const, bf_uint64_t: BF_HANDLE_OP_CLOSE_HANDLE_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_handle_op_close_handle

2.9. Debug Syscalls

2.9.1. bf_debug_op_out, OP=0x2, IDX=0x0

This syscall tells the microkernel to output RDI and RSI to the console device the microkernel is currently using for debugging.

Input:

Register Name Bits Description
REG0 63:0 The first value to output to the microkernel's console
REG1 63:0 The second value to output to the microkernel's console

const, bf_uint64_t: BF_DEBUG_OP_OUT_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_debug_op_out

2.9.2. bf_debug_op_dump_vm, OP=0x2, IDX=0x1

This syscall tells the microkernel to output a VM's state to the console device the microkernel is currently using for debugging.

Input:

Register Name Bits Description
REG0 63:0 The VMID of the VM's state to output

const, bf_uint64_t: BF_DEBUG_OP_DUMP_VM_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_debug_op_dump_vm

2.9.3. bf_debug_op_dump_vp, OP=0x2, IDX=0x2

This syscall tells the microkernel to output a VP's state to the console device the microkernel is currently using for debugging.

Input:

Register Name Bits Description
REG0 63:0 The VPID of the VP's state to output

const, bf_uint64_t: BF_DEBUG_OP_DUMP_VP_IDX_VAL

Value Description
0x0000000000000002 Defines the syscall index for bf_debug_op_dump_vp

2.9.4. bf_debug_op_dump_vps, OP=0x2, IDX=0x3

This syscall tells the microkernel to output a VPS's state to the console device the microkernel is currently using for debugging.

Input:

Register Name Bits Description
REG0 63:0 The VPSID of the VPS's state to output

const, bf_uint64_t: BF_DEBUG_OP_DUMP_VPS_IDX_VAL

Value Description
0x0000000000000003 Defines the syscall index for bf_debug_op_dump_vps

2.9.5. bf_debug_op_dump_vmexit_log, OP=0x2, IDX=0x4

This syscall tells the microkernel to output the VMExit log. The VMExit log is a chronological log of the "X" number of exits that have occurred on a specific physical processor.

Input:

Register Name Bits Description
REG0 63:0 The PPID of the PP to dump the log from

const, bf_uint64_t: BF_DEBUG_OP_DUMP_VMEXIT_LOG_IDX_VAL

Value Description
0x0000000000000003 Defines the syscall index for bf_debug_op_dump_vmexit_log

2.9.6. bf_debug_op_write_c, OP=0x2, IDX=0x5

This syscall tells the microkernel to output a provided character to the microkernel's console.

Input:

Register Name Bits Description
REG0 7:0 The character to output
REG0 63:8 REVI

const, bf_uint64_t: BF_DEBUG_OP_WRITE_C_IDX_VAL

Value Description
0x0000000000000005 Defines the syscall index for bf_debug_op_write_c

2.9.7. bf_debug_op_write_str, OP=0x2, IDX=0x6

This syscall tells the microkernel to output a provided string to the microkernel's console.

Input:

Register Name Bits Description
REG0 63:0 The virtual address of a null terminated string to output

const, bf_uint64_t: BF_DEBUG_OP_WRITE_STR_IDX_VAL

Value Description
0x0000000000000006 Defines the syscall index for bf_debug_op_write_str

2.9.8. bf_debug_op_dump_ext, OP=0x2, IDX=0x7

This syscall tells the microkernel to output an extension's state to the console device the microkernel is currently using for debugging.

Input:

Register Name Bits Description
REG0 63:0 The EXTID of the extensions's state to output

const, bf_uint64_t: BF_DEBUG_OP_DUMP_EXT_IDX_VAL

Value Description
0x0000000000000007 Defines the syscall index for bf_debug_op_dump_ext

2.9.9. bf_debug_op_dump_page_pool, OP=0x2, IDX=0x8

This syscall tells the microkernel to output the page pool's stats to the console device the microkernel is currently using for debugging.

const, bf_uint64_t: BF_DEBUG_OP_DUMP_PAGE_POOL_IDX_VAL

Value Description
0x0000000000000008 Defines the syscall index for bf_debug_op_dump_page_pool

2.9.10. bf_debug_op_dump_huge_pool, OP=0x2, IDX=0x9

This syscall tells the microkernel to output the huge pool's stats to the console device the microkernel is currently using for debugging.

const, bf_uint64_t: BF_DEBUG_OP_DUMP_HUGE_POOL_IDX_VAL

Value Description
0x0000000000000009 Defines the syscall index for bf_debug_op_dump_huge_pool

2.10. Callback Syscalls

2.10.2. bf_callback_op_register_bootstrap, OP=0x3, IDX=0x2

This syscall tells the microkernel that the extension would like to receive callbacks for bootstrap events.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 Set to the virtual address of the callback

const, bf_uint64_t: BF_CALLBACK_OP_REGISTER_BOOTSTRAP_IDX_VAL

Value Description
0x0000000000000002 Defines the syscall index for bf_callback_op_register_bootstrap

2.10.3. bf_callback_op_register_vmexit, OP=0x3, IDX=0x3

This syscall tells the microkernel that the extension would like to receive callbacks for VM exits.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 Set to the virtual address of the callback

const, bf_uint64_t: BF_CALLBACK_OP_REGISTER_VMEXIT_IDX_VAL

Value Description
0x0000000000000003 Defines the syscall index for bf_callback_op_register_vmexit

2.10.4. bf_callback_op_register_fail, OP=0x3, IDX=0x4

This syscall tells the microkernel that the extension would like to receive callbacks for fast fail events. If a fast fail event occurs, something terrible has happened, and the extension must take action, or the physical processor will halt.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 Set to the virtual address of the callback

const, bf_uint64_t: BF_CALLBACK_OP_REGISTER_FAIL_IDX_VAL

Value Description
0x0000000000000004 Defines the syscall index for bf_callback_op_register_fail

2.11. Virtual Machine Syscalls

A Virtual Machine or VM virtually represents a physical computer. Although the microkernel has an internal representation of a VM, it doesn't understand what a VM is outside of resource management, and it is up to the extension to define what a VM is and how it should operate.

One important resource within the microkernel that changes when a VM changes is the direct map each extension is given. When a VM changes, the direct map an extension uses to access physical memory also changes.

2.11.1. Virtual Machine ID (VMID)

The Virtual Machine ID (VMID) is a 16bit number that uniquely identifies a VM.

2.11.2. bf_vm_op_create_vm, OP=0x4, IDX=0x0

This syscall tells the microkernel to create a VM and return its ID.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle

Output:

Register Name Bits Description
REG0 15:0 The resulting VMID of the newly created VM
REG0 63:16 REVI

const, bf_uint64_t: BF_VM_OP_CREATE_VM_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_vm_op_create_vm

2.11.3. bf_vm_op_destroy_vm, OP=0x4, IDX=0x1

This syscall tells the microkernel to destroy a VM given an ID.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The VMID of the VM to destroy
REG1 63:16 REVI

const, bf_uint64_t: BF_VM_OP_DESTROY_VM_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_vm_op_destroy_vm

2.12. Virtual Processor Syscalls

A Virtual Processor or VP virtually represents a logical core. Although the microkernel has an internal representation of a VP, it doesn't understand what a VP is outside of resource management, and it is up to the extension to define what a VM is and how it should operate.

Once a VP is run, it is assigned to the VM it was run on, and cannot be run on any other VM for the remainder of it's lifetime. A VP is also assigned to a specific PP (physical processor). Unlike the assigned VM, the assigned PP can be changed by migrating the VP to another PP.

2.12.1. Virtual Processor ID (VPID)

The Virtual Processor ID (VPID) is a 16bit number that uniquely identifies a VP.

2.12.2. bf_vp_op_create_vp, OP=0x5, IDX=0x0

This syscall tells the microkernel to create a VP given the IDs of the VM and PP the VP will be assigned to. Upon success, this syscall returns the ID of the newly created VP.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The ID of the VM to assign the newly created VP to
REG1 63:16 REVI
REG2 15:0 The ID of the PP to assign the newly created VP to
REG2 63:16 REVI

Output:

Register Name Bits Description
REG0 15:0 The resulting VPID of the newly created VP
REG0 63:16 REVI

const, bf_uint64_t: BF_VP_OP_CREATE_VP_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_vp_op_create_vp

2.12.3. bf_vp_op_destroy_vp, OP=0x5, IDX=0x1

This syscall tells the microkernel to destroy a VP given an ID.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The VPID of the VP to destroy
REG1 63:16 REVI

const, bf_uint64_t: BF_VP_OP_DESTROY_VP_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_vp_op_destroy_vp

2.12.3. bf_vp_op_migrate, OP=0x5, IDX=0x2

This syscall tells the microkernel to migrate a VP from one PP to another PP. This function does not execute the VP (use bf_vps_op_run for that), but instead allows bf_vps_op_run to execute a VP on a PP that it was not originally assigned to.

When a VP is migrated, all of the VPSs that are assigned to the requested VP are also migrated to this new PP as well. From an AMD/Intel point of view, this clears the VMCS/VMCB for each VPS assigned to the VP. On Intel, it also loads the newly cleared VPS and sets the launched state to false, ensuring the next bf_vps_op_run will use VMLaunch instead of VMResume.

It should be noted that the migration of a VPS from one PP to another does not happen during the execution of this ABI. This ABI simply tells the microkernel that the requested VP may now execute on the requested PP. This will cause a mismatch between the assigned PP for a VP and the assigned PP for a VPS. The microkernel will detect this mismatch when an extension attempts to execute bf_vps_op_run. When this occurs, the microkernel will ensure the VP is being run on the PP it was assigned to during migration, and then it will check to see if the PP of the VPS matches. If it doesn't, it will then perform a migration of that VPS at that time. This ensures that the microkernel is only migrations VPSs when it needs to, and it ensures the VPS is cleared an loaded (in the case of Intel) on the PP it will be executed on, which is a requirement for VMCS migration. An extension can determine which VPSs have been migrated by looking at the assigned PP of a VPS. If it doesn't match the VP it was assigned to, it has not been migrated. Finally, an extension is free to read/write to the VPSs state, even if it has not been migrated. The only requirement for migration is execution (meaning VMRun/VMLaunch/VMResume).

Any additional migration responsibilities, like TSC synchronization, must be performed by the extension.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The VPID of the VP to migrate
REG1 63:16 REVI
REG2 15:0 The ID of the PP to assign the provided VP to
REG2 63:16 REVI

const, bf_uint64_t: BF_VP_OP_MIGRATE_IDX_VAL

Value Description
0x0000000000000002 Defines the syscall index for bf_vp_op_migrate

2.12.4. Virtual Processor State Syscalls

A Virtual Processor State or VPS encapsulates the state associated with a virtual process. For example, on Intel this would be the VMCS, the registers that must be saved that the VMCS does not manage, and the general purpose registers.

Once a VPS is run, it is assigned to the VP it was run on, and cannot be run on any other VP for the remainder of it's lifetime. Since a VP is also assigned to a specific PP (physical processor), so is the VPS. When a VP is migrated, all VPSs assigned to that VP are also migrated.

2.12.5. Virtual Processor State ID (VPSID)

The Virtual Processor State ID (VPSID) is a 16bit number that uniquely identifies a VPS.

2.12.6. bf_vps_op_create_vps, OP=0x6, IDX=0x0

This syscall tells the microkernel to create a VPS given the IDs of the VP and PP the VPS will be assigned to. Upon success, this syscall returns the ID of the newly created VPS.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The ID of the VP to assign the newly created VPS to
REG1 63:16 REVI
REG2 15:0 The ID of the PP to assign the newly created VPS to
REG2 63:16 REVI

Output:

Register Name Bits Description
REG0 15:0 The resulting VPSID of the newly created VPS
REG0 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_CREATE_VPS_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_vps_op_create_vps

2.12.7. bf_vps_op_destroy_vps, OP=0x6, IDX=0x1

This syscall tells the microkernel to destroy a VPS given an ID.

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 destroy
REG1 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_DESTROY_VPS_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_vps_op_destroy_vps

2.12.8. bf_vps_op_init_as_root, OP=0x6, IDX=0x2

This syscall tells the microkernel to initialize a VPS using the root VP state provided by the loader using the current PPID.

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 initialize
REG1 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_INIT_AS_ROOT_IDX_VAL

Value Description
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

Reads a CPU register from the VPS given a bf_reg_t. Note that the bf_reg_t is architecture-specific.

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 A bf_reg_t defining which register to read

Output:

Register Name Bits Description
REG0 63:0 The resulting value

const, bf_uint64_t: BF_VPS_OP_READ_REG_IDX_VAL

Value Description
0x000000000000000B Defines the syscall index for bf_vps_op_read_reg

2.12.18. bf_vps_op_write_reg, 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.

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 to
REG1 63:16 REVI
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

Value Description
0x000000000000000C Defines the syscall index for bf_vps_op_write_reg

2.12.19. bf_vps_op_run, OP=0x5, IDX=0xD

bf_vps_op_run tells the microkernel to execute a given VPS on behalf of a given VP and VM. This system call only returns if an error occurs. On success, this system call will physically execute the requested VM and VP using the requested VPS, and the extension will only execute again on the next VMExit.

Unless an extension needs to change the active VM, VP or VPS, the extension should use bf_vps_op_run_current instead of bf_vps_op_run. bf_vps_op_run is slow as it must perform a series of checks to determine if it has any work to perform before execution of a VM can occur.

Unlike bf_vps_op_run_current which is really just a return to microkernel execution, bf_vps_op_run must perform the following operations:

  • It first verifies that the provided VM, VP and VPS are all created. Meaning, and extension must first use the create ABI to properly create a VM, VP and VPS before it may be used.
  • Next, it must ensure VM, VP and VPS assignment is correct. A newly created VP and VPS are unassigned. Once bf_vps_op_run is executed, the VP is assigned to the provided VM and the VPS is assigned to the provided VP. The VP and VPS are also both assigned to the PP bf_vps_op_run is executed on. Once these assignments take place, an extension cannot change them, and any attempt to run a VP or VPS on a VM, VP or PP they are not assigned to will fail. It is impossible to change the assigned of a VM or VP, but an extension can change the assignment of a VP and VPSs PP by using the bf_vp_op_migrate function.
  • Next, bf_vps_op_run must determine if it needs to migrate a VPS to the PP the VPS is being executed on by bf_vps_op_run. For more information about how this works, please see bf_vp_op_migrate.
  • Finally, bf_vps_op_run must ensure the active VM, VP and VPS are set to the VM, VP and VPS provided to this ABI. Any changes in the active state could cause additional operations to take place. For example, the VPS must transfer the TLS state of the general purpose registers to its internal cache so that the VPS that is about to become active can use the TLS block instead.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 15:0 The VMID of the VM to run
REG1 63:16 REVI
REG2 15:0 The VPID of the VP to run
REG2 63:16 REVI
REG3 15:0 The VPSID of the VPS to run
REG3 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_RUN_IDX_VAL

Value Description
0x000000000000000D Defines the syscall index for bf_vps_op_run

2.12.20. bf_vps_op_run_current, OP=0x5, IDX=0xE

bf_vps_op_run_current tells the microkernel to execute the currently active VPS, VP and VM.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle

const, bf_uint64_t: BF_VPS_OP_RUN_CURRENT_IDX_VAL

Value Description
0x000000000000000E Defines the syscall index for bf_vps_op_run_current

2.12.21. bf_vps_op_advance_ip, OP=0x5, IDX=0xF

This syscall tells the microkernel to advance the instruction pointer in the requested VPS.

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 advance the IP in
REG1 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_ADVANCE_IP_AND_RUN_CURRENT_IDX_VAL

Value Description
0x000000000000000F Defines the syscall index for bf_vps_op_advance_ip

2.12.22. bf_vps_op_advance_ip_and_run_current, OP=0x5, IDX=0x10

This syscall tells the microkernel to advance the instruction pointer in the currently active VPS and run the currently active VPS, VP and VM (i.e., this combines bf_vps_op_advance_ip and bf_vps_op_advance_ip).

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle

const, bf_uint64_t: BF_VPS_OP_ADVANCE_IP_IDX_VAL

Value Description
0x0000000000000010 Defines the syscall index for bf_vps_op_advance_ip_and_run_current

2.12.23. bf_vps_op_promote, OP=0x5, IDX=0x11

bf_vps_op_promote tells the microkernel to promote the requested VPS. bf_vps_op_promote will stop the hypervisor on the physical processor and replace its state with the state in the given VPS. Note that this syscall only returns on error.

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 promote
REG1 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_PROMOTE_IDX_VAL

Value Description
0x0000000000000011 Defines the syscall index for bf_vps_op_promote

2.12.24. bf_vps_op_clear_vps, OP=0x5, IDX=0x11

bf_vps_op_clear_vps tells the microkernel to clear the VPS's hardware cache, if one exists. How this is used depends entirely on the hardware and is associated with AMD's VMCB Clean Bits, and Intel's VMClear instruction. See the associated documentation for more details. On AMD, this ABI clears the entire VMCB. For more fine grained control, use the write ABIs to manually modify the VMCB.

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 clear
REG1 63:16 REVI

const, bf_uint64_t: BF_VPS_OP_CLEAR_IDX_VAL

Value Description
0x0000000000000012 Defines the syscall index for bf_vps_op_clear_vps

2.13. Intrinsic Syscalls

2.13.1. bf_intrinsic_op_rdmsr, OP=0x7, IDX=0x0

Reads an MSR directly from the CPU given the address of the MSR to read. Note that this is specific to Intel/AMD only. Also note that not all MSRs can be written to, and which MSRs that can be written to is up to the microkernel's internal policy as well as which architecture the hypervisor is running on.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 31:0 The address of the MSR to read
REG1 63:32 REVI

Output:

Register Name Bits Description
REG0 63:0 The resulting value

const, bf_uint64_t: BF_INTRINSIC_OP_RDMSR_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_intrinsic_op_rdmsr

2.13.2. bf_intrinsic_op_wrmsr, OP=0x7, IDX=0x1

Writes to an MSR directly from the CPU given the address of the MSR to write and the value to write. Note that this is specific to Intel/AMD only. Also note that not all MSRs can be written to, and which MSRs that can be written to is up to the microkernel's internal policy as well as which architecture the hypervisor is running on.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 31:0 The address of the MSR to write to
REG1 63:32 REVI
REG2 63:0 The value to write to the requested MSR

const, bf_uint64_t: BF_INTRINSIC_OP_WRMSR_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_intrinsic_op_wrmsr

2.13.3. bf_intrinsic_op_invlpga, OP=0x7, IDX=0x2

Invalidates the TLB mapping for a given virtual page and a given ASID. Note that this is specific to AMD only.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The address to invalidate
REG2 63:0 The ASID to invalidate

const, bf_uint64_t: BF_INTRINSIC_OP_INVLPGA_IDX_VAL

Value Description
0x0000000000000002 Defines the syscall index for bf_intrinsic_op_invlpga

2.13.4. bf_intrinsic_op_invept, OP=0x7, IDX=0x3

Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches that were derived from extended page tables (EPT). Note that this is specific to Intel only.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The EPTP to invalidate
REG2 63:0 The INVEPT type (see the Intel SDM for details)

const, bf_uint64_t: BF_INTRINSIC_OP_INVEPT_IDX_VAL

Value Description
0x0000000000000003 Defines the syscall index for bf_intrinsic_op_invept

2.13.5. bf_intrinsic_op_invvpid, OP=0x7, IDX=0x4

Invalidates mappings in the translation lookaside buffers (TLBs) and paging-structure caches based on virtual-processor identifier (VPID). Note that this is specific to Intel only.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The address to invalidate
REG2 15:0 The VPID to invalidate
REG2 63:16 REVI
REG3 63:0 The INVVPID type (see the Intel SDM for details)

const, bf_uint64_t: BF_INTRINSIC_OP_INVVPID_IDX_VAL

Value Description
0x0000000000000004 Defines the syscall index for bf_intrinsic_op_invvpid

2.14. Mem Syscalls

Each extension has access to several different memory pools:

  • The page pool (used for allocating pages)
  • The huge pool (used for allocating physically contiguous pages)
  • The heap pool (used for allocating heap memory)
  • TLS (used for thread-local storage)
  • The direct map

The page pool provides a means to allocate a page.

The huge pool provides a method for allocating physically contiguous memory. This pool is small and platform-dependent (as in less than a megabyte total). It should be noted that some microkernels may choose not to implement bf_mem_op_free_huge which is optional.

The heap pool provides memory that can only be grown, meaning the memory must always remain virtually contiguous. An extension is free to use heap memory or the page pool. The only difference between these two pools is the page pool can only allocate a single page at a time and may or may not be fragmented (depends on the implementation). The heap pool can allocate memory of any size (must be a multiple of a page) and never fragments.

Thread-Local Storage (TLS) memory (typically allocated using thread_local) provides per-physical processor storage. The amount of TLS available to an extension is 1 page per physical processor.

The direct map provides an extension with a means to access any physical address by accessing the direct map region of the virtual address space (depends on the hypervisor's configuration). By default, on Intel/AMD with 4-level paging, this region starts at 0x0000600000000000, but it can be changed using CMake. An extension can access any physical address by simply adding 0x0000600000000000 to the physical address and dereferencing the resulting value. When a VM is destroyed, all physical memory maps associated with that VM will be removed. The direct map is also where page and huge page allocations are mapped, providing an extension with a simple means for performing a virtual address to physical address (and vice versa) translations.

2.14.1. bf_mem_op_alloc_page, OP=0x7, IDX=0x0

bf_mem_op_alloc_page allocates a page, and maps this page into the direct map of the VM.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle

Output:

Register Name Bits Description
REG0 63:0 The virtual address of the resulting page
REG1 63:0 The physical address of the resulting page

const, bf_uint64_t: BF_MEM_OP_ALLOC_PAGE_IDX_VAL

Value Description
0x0000000000000000 Defines the syscall index for bf_mem_op_alloc_page

2.14.2. bf_mem_op_free_page, OP=0x7, IDX=0x1

Frees a page previously allocated by bf_mem_op_alloc_page. This operation is optional and not all microkernels may implement it.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The virtual address of the page to free

Output:

Register Name Bits Description

const, bf_uint64_t: BF_MEM_OP_FREE_PAGE_IDX_VAL

Value Description
0x0000000000000001 Defines the syscall index for bf_mem_op_free_page

2.14.3. bf_mem_op_alloc_huge, OP=0x7, IDX=0x2

bf_mem_op_alloc_huge allocates a physically contiguous block of memory. When allocating a page, the extension should keep in mind the following:

  • The total memory available to allocate from this pool is extremely limited. This should only be used when absolutely needed, and extensions should not expect more than 1 MB (might be less) of total memory available.
  • Memory allocated from the huge pool might be allocated using different schemes. For example, the microkernel might allocate in increments of a page, or it might use a buddy allocator that would allocate in multiples of 2. If the allocation size doesn't match the algorithm, internal fragmentation could occur, further limiting the total number of allocations this pool can support.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The total number of bytes to allocate

Output:

Register Name Bits Description
REG0 63:0 The virtual address of the resulting memory
REG1 63:0 The physical address of the resulting memory

const, bf_uint64_t: BF_MEM_OP_ALLOC_HUGE_IDX_VAL

Value Description
0x0000000000000002 Defines the syscall index for bf_mem_op_alloc_huge

2.14.4. bf_mem_op_free_huge, OP=0x7, IDX=0x3

Frees memory previously allocated by bf_mem_op_alloc_huge. This operation is optional and not all microkernels may implement it.

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The virtual address of the memory to free

Output:

Register Name Bits Description

const, bf_uint64_t: BF_MEM_OP_FREE_HUGE_IDX_VAL

Value Description
0x0000000000000003 Defines the syscall index for bf_mem_op_free_huge

2.14.5. bf_mem_op_alloc_heap, OP=0x7, IDX=0x4

bf_mem_op_alloc_heap allocates heap memory. When allocating heap memory, the extension should keep in mind the following:

  • This ABI is designed to work similar to sbrk() to support malloc/free implementations common with existing open source libraries.
  • Calling this ABI with with a size of 0 will return the current heap location.
  • Calling this ABI with a size (in bytes) will result in return the previous heap location. The current heap location will be set to the previous location, plus the provide size, rounded to the nearest page size.
  • The heap is not mapped into the direct map, so virtual to physical (and vice versa) translations are not possible.
  • There is no ability to free heap memory

Input:

Register Name Bits Description
REG0 63:0 Set to the result of bf_handle_op_open_handle
REG1 63:0 The number of bytes to increase the heap by

Output:

Register Name Bits Description
REG0 63:0 The virtual address of the previous heap location

const, bf_uint64_t: BF_MEM_OP_ALLOC_HEAP_IDX_VAL

Value Description
0x0000000000000004 Defines the syscall index for bf_mem_op_alloc_heap