Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: Add Windows Hypervisor Platform APIs #767

Draft
wants to merge 1 commit into
base: 0.3
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,9 @@ winefs = []
winevt = []
wingdi = []
winhttp = []
winhvemulation = []
winhvplatform = []
winhvplatformdefs = []
wininet = []
winineti = []
winioctl = []
Expand Down
3 changes: 3 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,9 @@ const DATA: &'static [(&'static str, &'static [&'static str], &'static [&'static
("winevt", &["basetsd", "guiddef", "minwinbase", "minwindef", "vcruntime", "winnt"], &["wevtapi"]),
("wingdi", &["basetsd", "minwindef", "windef", "winnt"], &["gdi32", "msimg32", "opengl32", "winspool"]),
("winhttp", &["basetsd", "minwinbase", "minwindef", "winnt"], &["winhttp"]),
("winhvemulation", &["basetsd", "winerror", "winhvplatformdefs"], &["winhvemulation"]),
("winhvplatform", &["basetsd", "winerror", "winhvplatformdefs"], &["winhvplatform"]),
("winhvplatformdefs", &["basetsd", "minwindef"], &[]),
("wininet", &["basetsd", "minwinbase", "minwindef", "ntdef", "windef", "winineti", "winnt"], &["wininet"]),
("winineti", &["minwindef"], &[]),
("winioctl", &["basetsd", "devpropdef", "guiddef", "minwindef", "winnt"], &[]),
Expand Down
3 changes: 3 additions & 0 deletions src/um/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,9 @@ pub mod gl;
#[cfg(feature = "winevt")] pub mod winevt;
#[cfg(feature = "wingdi")] pub mod wingdi;
#[cfg(feature = "winhttp")] pub mod winhttp;
#[cfg(feature = "winhvemulation")] pub mod winhvemulation;
#[cfg(feature = "winhvplatform")] pub mod winhvplatform;
#[cfg(feature = "winhvplatformdefs")] pub mod winhvplatformdefs;
#[cfg(feature = "wininet")] pub mod wininet;
#[cfg(feature = "winineti")] pub mod winineti;
#[cfg(feature = "winioctl")] pub mod winioctl;
Expand Down
103 changes: 103 additions & 0 deletions src/um/winhvemulation.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use ctypes::{c_void};
use shared::basetsd::{UINT32, UINT16, UINT8};
use shared::winerror::HRESULT;
use um::winhvplatformdefs::{
WHV_GUEST_PHYSICAL_ADDRESS,
WHV_REGISTER_NAME,
WHV_REGISTER_VALUE,
WHV_GUEST_VIRTUAL_ADDRESS,
WHV_TRANSLATE_GVA_FLAGS,
WHV_TRANSLATE_GVA_RESULT_CODE,
WHV_VP_EXIT_CONTEXT,
WHV_X64_IO_PORT_ACCESS_CONTEXT,
WHV_MEMORY_ACCESS_CONTEXT,
};

STRUCT!{struct WHV_EMULATOR_STATUS {
AsUINT32: UINT32,
}}
BITFIELD!{WHV_EMULATOR_STATUS AsUINT32: UINT32 [
EmulationSuccessful set_EmulationSuccessful[0..1],
InternalEmulationFailure set_InternalEmulationFailure[1..2],
IoPortCallbackFailed set_IoPortCallbackFailed[2..3],
MemoryCallbackFailed set_MemoryCallbackFailed[3..4],
TranslateGvaPageCallbackFailed set_TranslateGvaPageCallbackFailed[4..5],
TranslateGvaPageCallbackGpaIsNotAligned set_TranslateGvaPageCallbackGpaIsNotAligned[5..6],
GetVirtualProcessorRegistersCallbackFailed set_GetVirtualProcessorRegistersCallbackFailed[6..7],
SetVirtualProcessorRegistersCallbackFailed set_SetVirtualProcessorRegistersCallbackFailed[7..8],
InterruptCausedIntercept set_InterruptCausedIntercept[8..9],
GuestCannotBeFaulted set_GuestCannotBeFaulted[9..10],
Reserved set_Reserved[10..32],
]}
STRUCT!{struct WHV_EMULATOR_MEMORY_ACCESS_INFO {
GpaAddress: WHV_GUEST_PHYSICAL_ADDRESS,
Direction: UINT8,
AccessSize: UINT8,
Data: [UINT8; 3],
}}
STRUCT!{struct WHV_EMULATOR_IO_ACCESS_INFO {
Direction: UINT8,
Port: UINT16,
AccessSize: UINT16,
Data: UINT32,
}}
FN!{stdcall WHV_EMULATOR_IO_PORT_CALLBACK(
Context: *mut c_void,
IoAccess: *mut WHV_EMULATOR_IO_ACCESS_INFO,
) -> HRESULT}
FN!{stdcall WHV_EMULATOR_MEMORY_CALLBACK(
Context: *mut c_void,
MemoryAccess: *mut WHV_EMULATOR_MEMORY_ACCESS_INFO,
) -> HRESULT}
FN!{stdcall WHV_EMULATOR_GET_VIRTUAL_PROCESSOR_REGISTERS_CALLBACK(
Context: *mut c_void,
RegisterNames: *const WHV_REGISTER_NAME,
RegisterCount: UINT32,
RegisterValues: *mut WHV_REGISTER_VALUE,
) -> HRESULT}
FN!{stdcall WHV_EMULATOR_SET_VIRTUAL_PROCESSOR_REGISTERS_CALLBACK(
Context: *mut c_void,
RegisterNames: *const WHV_REGISTER_NAME,
RegisterCount: UINT32,
RegisterValues: *const WHV_REGISTER_VALUE,
) -> HRESULT}
FN!{stdcall WHV_EMULATOR_TRANSLATE_GVA_PAGE_CALLBACK(
Context: *mut c_void,
Gva: WHV_GUEST_VIRTUAL_ADDRESS,
TranslateFlags: WHV_TRANSLATE_GVA_FLAGS,
TranslationResult: *mut WHV_TRANSLATE_GVA_RESULT_CODE,
Gpa: *mut WHV_GUEST_PHYSICAL_ADDRESS,
) -> HRESULT}
STRUCT!{struct WHV_EMULATOR_CALLBACKS {
Size: UINT32,
Reserved: UINT32,
WHvEmulatorIoPortCallback: WHV_EMULATOR_IO_PORT_CALLBACK,
WHvEmulatorMemoryCallback: WHV_EMULATOR_MEMORY_CALLBACK,
WHvEmulatorGetVirtualProcessorRegisters: WHV_EMULATOR_GET_VIRTUAL_PROCESSOR_REGISTERS_CALLBACK,
WHvEmulatorSetVirtualProcessorRegisters: WHV_EMULATOR_SET_VIRTUAL_PROCESSOR_REGISTERS_CALLBACK,
WHvEmulatorTranslateGvaPage: WHV_EMULATOR_TRANSLATE_GVA_PAGE_CALLBACK,
}}
pub type WHV_EMULATOR_HANDLE = *mut c_void;
extern "system" {
pub fn WHvEmulatorCreateEmulator(
Callbacks: *const WHV_EMULATOR_CALLBACKS,
Emulator: *mut WHV_EMULATOR_HANDLE,
) -> HRESULT;
pub fn WHvEmulatorDestroyEmulator(
Emulator: WHV_EMULATOR_HANDLE,
) -> HRESULT;
pub fn WHvEmulatorTryIoEmulation(
Emulator: WHV_EMULATOR_HANDLE,
Context: *mut c_void,
VpContext: *const WHV_VP_EXIT_CONTEXT,
IoInstructionContext: *const WHV_X64_IO_PORT_ACCESS_CONTEXT,
EmulatorReturnStatus: *mut WHV_EMULATOR_STATUS,
) -> HRESULT;
pub fn WHvEmulatorTryMmioEmulation(
Emulator: WHV_EMULATOR_HANDLE,
Context: *mut c_void,
VpContext: *const WHV_VP_EXIT_CONTEXT,
MmioInstructionContext: *const WHV_MEMORY_ACCESS_CONTEXT,
EmulatorReturnStatus: *mut WHV_EMULATOR_STATUS,
) -> HRESULT;
}
162 changes: 162 additions & 0 deletions src/um/winhvplatform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use ctypes::{c_void};
use shared::basetsd::{UINT32, UINT64};
use shared::winerror::HRESULT;
use um::winhvplatformdefs::{
WHV_CAPABILITY_CODE,
WHV_PARTITION_HANDLE,
WHV_PARTITION_PROPERTY_CODE,
WHV_GUEST_PHYSICAL_ADDRESS,
WHV_MAP_GPA_RANGE_FLAGS,
WHV_GUEST_VIRTUAL_ADDRESS,
WHV_TRANSLATE_GVA_FLAGS,
WHV_TRANSLATE_GVA_RESULT,
WHV_REGISTER_NAME,
WHV_REGISTER_VALUE,
WHV_INTERRUPT_CONTROL,
WHV_PARTITION_COUNTER_SET,
WHV_PROCESSOR_COUNTER_SET,
};

extern "system" {
pub fn WHvGetCapability(
CapabilityCode: WHV_CAPABILITY_CODE,
CapabilityBuffer: *mut c_void,
CapabilityBufferSizeInBytes: UINT32,
WrittenSizeInBytes: *mut UINT32,
) -> HRESULT;
pub fn WHvCreatePartition(
Partition: *mut WHV_PARTITION_HANDLE,
) -> HRESULT;
pub fn WHvSetupPartition(
Partition: WHV_PARTITION_HANDLE,
) -> HRESULT;
pub fn WHvDeletePartition(
Partition: WHV_PARTITION_HANDLE,
) -> HRESULT;
pub fn WHvGetPartitionProperty(
Partition: WHV_PARTITION_HANDLE,
PropertyCode: WHV_PARTITION_PROPERTY_CODE,
PropertyBuffer: *mut c_void,
PropertyBufferSizeInBytes: UINT32,
WrittenSizeInBytes: *mut UINT32,
) -> HRESULT;
pub fn WHvSetPartitionProperty(
Partition: WHV_PARTITION_HANDLE,
PropertyCode: WHV_PARTITION_PROPERTY_CODE,
PropertyBuffer: *const c_void,
PropertyBufferSizeInBytes: UINT32,
) -> HRESULT;
pub fn WHvSuspendPartitionTime(
Partition: WHV_PARTITION_HANDLE,
) -> HRESULT;
pub fn WHvResumePartitionTime(
Partition: WHV_PARTITION_HANDLE,
) -> HRESULT;
pub fn WHvMapGpaRange(
Partition: WHV_PARTITION_HANDLE,
SourceAddress: *mut c_void,
GuestAddress: WHV_GUEST_PHYSICAL_ADDRESS,
SizeInBytes: UINT64,
Flags: WHV_MAP_GPA_RANGE_FLAGS,
) -> HRESULT;
pub fn WHvUnmapGpaRange(
Partition: WHV_PARTITION_HANDLE,
GuestAddress: WHV_GUEST_PHYSICAL_ADDRESS,
SizeInBytes: UINT64,
) -> HRESULT;
pub fn WHvTranslateGva(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
Gva: WHV_GUEST_VIRTUAL_ADDRESS,
TranslateFlags: WHV_TRANSLATE_GVA_FLAGS,
TranslationResult: *mut WHV_TRANSLATE_GVA_RESULT,
Gpa: *mut WHV_GUEST_PHYSICAL_ADDRESS,
) -> HRESULT;
pub fn WHvCreateVirtualProcessor(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
Flags: UINT32,
) -> HRESULT;
pub fn WHvDeleteVirtualProcessor(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
) -> HRESULT;
pub fn WHvRunVirtualProcessor(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
ExitContext: *mut c_void,
ExitContextSizeInBytes: UINT32,
) -> HRESULT;
pub fn WHvCancelRunVirtualProcessor(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
Flags: UINT32,
) -> HRESULT;
pub fn WHvGetVirtualProcessorRegisters(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
RegisterNames: *const WHV_REGISTER_NAME,
RegisterCount: UINT32,
RegisterValues: *mut WHV_REGISTER_VALUE,
) -> HRESULT;
pub fn WHvSetVirtualProcessorRegisters(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
RegisterNames: *const WHV_REGISTER_NAME,
RegisterCount: UINT32,
RegisterValues: *const WHV_REGISTER_VALUE,
) -> HRESULT;
pub fn WHvGetVirtualProcessorInterruptControllerState(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
State: *mut c_void,
StateSize: UINT32,
WrittenSize: *mut UINT32,
) -> HRESULT;
pub fn WHvSetVirtualProcessorInterruptControllerState(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
State: *const c_void,
StateSize: UINT32,
) -> HRESULT;
pub fn WHvRequestInterrupt(
Partition: WHV_PARTITION_HANDLE,
Interrupt: *const WHV_INTERRUPT_CONTROL,
InterruptControlSize: UINT32,
) -> HRESULT;
pub fn WHvGetVirtualProcessorXsaveState(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
Buffer: *mut c_void,
BufferSizeInBytes: UINT32,
BytesWritten: *mut UINT32,
) -> HRESULT;
pub fn WHvSetVirtualProcessorXsaveState(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
Buffer: *const c_void,
BufferSizeInBytes: UINT32,
) -> HRESULT;
pub fn WHvQueryGpaRangeDirtyBitmap(
Partition: WHV_PARTITION_HANDLE,
GuestAddress: WHV_GUEST_PHYSICAL_ADDRESS,
RangeSizeInBytes: UINT64,
Bitmap: *mut UINT64,
BitmapSizeInBytes: UINT32,
) -> HRESULT;
pub fn WHvGetPartitionCounters(
Partition: WHV_PARTITION_HANDLE,
CounterSet: WHV_PARTITION_COUNTER_SET,
Buffer: *mut c_void,
BufferSizeInBytes: UINT32,
BytesWritten: *mut UINT32,
) -> HRESULT;
pub fn WHvGetVirtualProcessorCounters(
Partition: WHV_PARTITION_HANDLE,
VpIndex: UINT32,
CounterSet: WHV_PROCESSOR_COUNTER_SET,
Buffer: *mut c_void,
BufferSizeInBytes: UINT32,
BytesWritten: *mut UINT32,
) -> HRESULT;
}
Loading