diff --git a/Sources/HostMain.c b/Sources/HostMain.c index 4195cf2..63e40cf 100644 --- a/Sources/HostMain.c +++ b/Sources/HostMain.c @@ -520,66 +520,21 @@ VOID HandleInitSignal ( _Inout_ GUEST_CONTEXT* GuestContext ) -{ - UNREFERENCED_PARAMETER(GuestContext); - - // - // For demonstration with VMware. On bare-metal, delay because of this logging - // may lead to failure of AP start up. - // - //LOG_INFO("Starting up processor #%d", GuestContext->Contexts->ProcessorNumber); - - // - // Simply put the processor into the "wait-for-SIPI" state. - // - // "All the processors on the system bus (...) execute the multiple processor - // (MP) initialization protocol. ... The application (non-BSP) processors - // (APs) go into a Wait For Startup IPI (SIPI) state while the BSP is executing - // initialization code." - // - // See: 9.1 INITIALIZATION OVERVIEW - // - // "Upon receiving an INIT ..., the processor responds by beginning the - // initialization process of the processor core and the local APIC. The state - // of the local APIC following an INIT reset is the same as it is after a - // power-up or hardware reset ... . This state is also referred to at the - // "wait-for-SIPI" state." - // - // See: 10.4.7.3 Local APIC State After an INIT Reset (“Wait-for-SIPI” State) - // - VmxWrite(VMCS_GUEST_ACTIVITY_STATE, VmxWaitForSipi); -} - -/*! - @brief Handles VM-exit due to the Startup-IPI (SIPI) signal. - - @param[in,out] GuestContext - A pointer to the guest context. - */ -static -VOID -HandleStartupIpi ( - _Inout_ GUEST_CONTEXT* GuestContext - ) { int regs[4]; CPUID_EAX_01 cpuVersionInfo; UINT64 extendedModel; - UINT64 vector; VMX_SEGMENT_ACCESS_RIGHTS accessRights; IA32_VMX_ENTRY_CTLS_REGISTER vmEntryControls; CR0 newCr0; CR4 newCr4; // - // Intel SDM suggest to issue SIPI twice. This does not appear to be - // implemented by many of kernels such as FreeBSD, Linux and Windows, but - // ignore it if this occurs, as we already initialized the processor with - // the first SIPI. + // For demonstration with VMware. On bare-metal, delay because of this logging + // may lead to failure of AP start up. // - if (VmxRead(VMCS_GUEST_ACTIVITY_STATE) == VmxActive) - { - goto Exit; - } + //LOG_INFO("Starting up processor #%d", GuestContext->Contexts->ProcessorNumber); + UNREFERENCED_PARAMETER(GuestContext); // // Initializes the processor to the state after INIT as described in the @@ -696,6 +651,40 @@ HandleStartupIpi ( vmEntryControls.Ia32EModeGuest = FALSE; VmxWrite(VMCS_CTRL_VMENTRY_CONTROLS, vmEntryControls.Flags); + // + // "All the processors on the system bus (...) execute the multiple processor + // (MP) initialization protocol. ... The application (non-BSP) processors + // (APs) go into a Wait For Startup IPI (SIPI) state while the BSP is executing + // initialization code." + // + // See: 9.1 INITIALIZATION OVERVIEW + // + // "Upon receiving an INIT ..., the processor responds by beginning the + // initialization process of the processor core and the local APIC. The state + // of the local APIC following an INIT reset is the same as it is after a + // power-up or hardware reset ... . This state is also referred to at the + // "wait-for-SIPI" state." + // + // See: 10.4.7.3 Local APIC State After an INIT Reset (“Wait-for-SIPI” State) + // + VmxWrite(VMCS_GUEST_ACTIVITY_STATE, VmxWaitForSipi); +} + +/*! + @brief Handles VM-exit due to the Startup-IPI (SIPI) signal. + + @param[in,out] GuestContext - A pointer to the guest context. + */ +static +VOID +HandleStartupIpi ( + _Inout_ GUEST_CONTEXT* GuestContext + ) +{ + UNREFERENCED_PARAMETER(GuestContext); + + UINT64 vector; + // // Then, emulate effects of SIPI by making further changes. // @@ -727,12 +716,13 @@ HandleStartupIpi ( InvalidateVpidDerivedCache((UINT16)VmxRead(VMCS_CTRL_VIRTUAL_PROCESSOR_IDENTIFIER)); // - // Done + // Done. Note that the 2nd SIPI will be ignored if that occurs after this. + // + // "If a logical processor is not in the wait-for-SIPI activity state when a + // SIPI arrives, no VM exit occurs and the SIPI is discarded" + // See: 25.2 OTHER CAUSES OF VM EXITS // VmxWrite(VMCS_GUEST_ACTIVITY_STATE, VmxActive); - -Exit: - return; } /*!