WHvEmulatorTryIoEmulation and WHvEmulatorTryMmioEmulation
Note: A prerelease of this API is available starting in the Windows Insiders Preview Build 17083
HRESULT WINAPI WHvEmulatorTryIoEmulation( _In_ WHV_EMULATOR_HANDLE Emulator, _In_ VOID* Context, _In_ const WHV_VP_EXIT_CONTEXT* VpContext, _In_ const WHV_X64_IO_PORT_ACCESS_CONTEXT* IoInstructionContext, _Out_ WHV_EMULATOR_STATUS* EmulatorReturnStatus ); HRESULT WINAPI WHvEmulatorTryMmioEmulation( _In_ WHV_EMULATOR_HANDLE Emulator, _In_ VOID* Context, _In_ const WHV_VP_EXIT_CONTEXT* VpContext, _In_ const WHV_MEMORY_ACCESS_CONTEXT* MmioInstructionContext, _Out_ WHV_EMULATOR_STATUS* EmulatorReturnStatus );
Attempt to emulate a given type of instruction with the given instruction context
returned by the WinHv APIs from a
WHvRunVirtualProcessor call. This function returns
S_OK in most methods of operation, and
EmulatorReturnStatus will be returned with
additional information. If
Emulator, or the instruction context are malformed, this
function may return
E_INVALIDARG. Any other return value indicates catastrophic failure, and the extended status should not be checked.
Emulator is a valid emulator handle returned from
Context is a
void* which is passed into each callback method, used as a way
for the virtualization stack to identify this emulation call.
EmulatorReturnStatus is extended status information about the emulation call. This return value
is only valid if the function's return value was
EmulationSuccessful: This emulation call was successful, the
SetVirtualProcessorRegisterscallback was called and the virtualization stack should continue running the processor.
InternalEmulationFailure: Some internal emulation failure occurred.
IoPortCallbackFailed: The registered Io Port callback did not return
MemoryCallbackFailed: The registered Memory callback did not return
TranslateGvaPageCallbackFailed: The registered
TranslateGvaPagecallback did not return
GpaPageaddress returned in the
TranslateGvaPagecallback was not 4K aligned.
GetVirtualProcessorRegistersCallbackFailed: The registered
GetVirtualProcessorRegisterscallback did not return
SetVirtualProcessorRegistersCallbackFailed: The registered
SetVirtualProcessorRegisterscallback did not return
InterruptCausedIntercept: A pending interrupt or fault caused this intercept, which the emulator cannot handle.
GuestCannotBeFaulted: The guest is currently in a state where injecting a fault would do nothing, and instead must be terminated in other ways.
NOTE: The hypervisor is not guaranteed to always return
InstructionBytes in the exit context.
For simple IO instructions, this is fine. However, for IO string and MMIO instructions, the virtualization stack must fetch the
InstructionBytes to pass into the emulator. In this case, it is okay for the virtualization stack to fetch more than the next instruction, because the emulator will only emulate a single instruction regardless of the number of bytes present in
NOTE: Instructions that contain the x86 REP prefix will be internally resolved within the emulator by emulating that instruction multiple times, until the REP prefix condition is satisfied. This may result in multiple callbacks of the registered callback functions.
This function is not thread safe when reusing the same emulator handle in another thread. Other calling threads should either use a different instance of the emulator (ie one emulator per VP) or wait until the current emulation call has returned.