Changeset 71129 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Feb 26, 2018 3:58:50 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121015
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r71087 r71129 29 29 #include <iprt/nt/nt-and-windows.h> 30 30 #include <iprt/nt/hyperv.h> 31 #include <iprt/nt/vid.h> 31 32 #include <WinHvPlatform.h> 32 33 … … 78 79 79 80 80 #define NEM_WIN_USE_HYPERCALLS_FOR_PAGES81 #define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS82 83 81 84 82 /********************************************************************************************************************************* 85 83 * Structures and Typedefs * 86 84 *********************************************************************************************************************************/ 87 /** WHvRegisterInterruptState layout, reconstructed from the v7.1 DDK. */88 typedef union MISSINGINTERUPTSTATEREG89 {90 /** 64-bit view. */91 uint64_t au64[2];92 struct /* unamed */93 {94 uint64_t fInterruptShadow : 1;95 uint64_t fNmiMasked : 2;96 uint64_t uReserved0 : 61;97 uint64_t uReserved1;98 };99 } MISSINGINTERUPTSTATEREG;100 AssertCompileSize(MISSINGINTERUPTSTATEREG, 16);101 102 85 103 86 … … 116 99 static decltype(WHvUnmapGpaRange) * g_pfnWHvUnmapGpaRange; 117 100 static decltype(WHvTranslateGva) * g_pfnWHvTranslateGva; 101 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 118 102 static decltype(WHvCreateVirtualProcessor) * g_pfnWHvCreateVirtualProcessor; 119 103 static decltype(WHvDeleteVirtualProcessor) * g_pfnWHvDeleteVirtualProcessor; … … 123 107 static decltype(WHvGetVirtualProcessorRegisters) * g_pfnWHvGetVirtualProcessorRegisters; 124 108 static decltype(WHvSetVirtualProcessorRegisters) * g_pfnWHvSetVirtualProcessorRegisters; 109 #endif 125 110 /** @} */ 126 111 127 112 /** @name APIs imported from Vid.dll 128 113 * @{ */ 129 static BOOL (WINAPI *g_pfnVidGetHvPartitionId)(HANDLE hPartition, HV_PARTITION_ID *pidPartition); 114 static decltype(VidGetHvPartitionId) *g_pfnVidGetHvPartitionId; 115 static decltype(VidStartVirtualProcessor) *g_pfnVidStartVirtualProcessor; 116 static decltype(VidStopVirtualProcessor) *g_pfnVidStopVirtualProcessor; 117 static decltype(VidMessageSlotMap) *g_pfnVidMessageSlotMap; 118 static decltype(VidMessageSlotHandleAndGetNext) *g_pfnVidMessageSlotHandleAndGetNext; 119 #ifdef LOG_ENABLED 120 static decltype(VidGetVirtualProcessorRunningStatus) *g_pfnVidGetVirtualProcessorRunningStatus; 121 #endif 130 122 /** @} */ 131 123 … … 152 144 NEM_WIN_IMPORT(0, false, WHvUnmapGpaRange), 153 145 NEM_WIN_IMPORT(0, false, WHvTranslateGva), 146 #ifndef NEM_WIN_USE_OUR_OWN_RUN_API 154 147 NEM_WIN_IMPORT(0, false, WHvCreateVirtualProcessor), 155 148 NEM_WIN_IMPORT(0, false, WHvDeleteVirtualProcessor), 156 149 NEM_WIN_IMPORT(0, false, WHvRunVirtualProcessor), 150 NEM_WIN_IMPORT(0, false, WHvCancelRunVirtualProcessor), 157 151 NEM_WIN_IMPORT(0, false, WHvGetRunExitContextSize), 158 NEM_WIN_IMPORT(0, false, WHvCancelRunVirtualProcessor),159 152 NEM_WIN_IMPORT(0, false, WHvGetVirtualProcessorRegisters), 160 153 NEM_WIN_IMPORT(0, false, WHvSetVirtualProcessorRegisters), 154 #endif 161 155 NEM_WIN_IMPORT(1, false, VidGetHvPartitionId), 156 NEM_WIN_IMPORT(1, false, VidMessageSlotMap), 157 NEM_WIN_IMPORT(1, false, VidMessageSlotHandleAndGetNext), 158 NEM_WIN_IMPORT(1, false, VidStartVirtualProcessor), 159 NEM_WIN_IMPORT(1, false, VidStopVirtualProcessor), 160 #ifdef LOG_ENABLED 161 NEM_WIN_IMPORT(1, false, VidGetVirtualProcessorRunningStatus), 162 #endif 162 163 #undef NEM_WIN_IMPORT 163 164 }; … … 202 203 203 204 /** The real NtDeviceIoControlFile API in NTDLL. */ 204 static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile; 205 static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile; 206 /** Mapping slot for CPU #0. 207 * @{ */ 208 static VID_MESSAGE_MAPPING_HEADER *g_pMsgSlotMapping = NULL; 209 static const HV_MESSAGE_HEADER *g_pHvMsgHdr; 210 static const HV_X64_INTERCEPT_MESSAGE_HEADER *g_pX64MsgHdr; 211 /** @} */ 212 205 213 206 214 /** … … 214 222 PVOID pvOutput, ULONG cbOutput) 215 223 { 224 char szFunction[32]; 225 const char *pszFunction; 226 switch (uFunction) 227 { 228 case 0x2210cb: pszFunction = "VidMessageSlotHandleAndGetNext"; break; 229 case 0x2210cc: pszFunction = "VidMessageSlotMap"; break; 230 case 0x221164: pszFunction = "VidStopVirtualProcessor"; break; 231 case 0x221158: pszFunction = "VidStartVirtualProcessor"; break; 232 case 0x2210a7: pszFunction = "VidGetVirtualProcessorState"; break; 233 case 0x221153: pszFunction = "VidSetVirtualProcessorState"; break; 234 default: 235 RTStrPrintf(szFunction, sizeof(szFunction), "%#x", uFunction); 236 pszFunction = szFunction; 237 break; 238 } 239 240 if (cbInput > 0 && pvInput) 241 Log12(("VID!NtDeviceIoControlFile: %s/input: %.*Rhxs\n", pszFunction, RT_MIN(cbInput, 32), pvInput)); 216 242 NTSTATUS rcNt = g_pfnNtDeviceIoControlFile(hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, uFunction, 217 243 pvInput, cbInput, pvOutput, cbOutput); 218 244 if (!hEvt && !pfnApcCallback && !pvApcCtx) 219 Log12(("VID!NtDeviceIoControlFile: hFile=%#zx pIos=%p->{s:%#x, i:%#zx} uFunction=% #xInput=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n",220 hFile, pIos, pIos->Status, pIos->Information, uFunction, pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress()));245 Log12(("VID!NtDeviceIoControlFile: hFile=%#zx pIos=%p->{s:%#x, i:%#zx} uFunction=%s Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n", 246 hFile, pIos, pIos->Status, pIos->Information, pszFunction, pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress())); 221 247 else 222 Log12(("VID!NtDeviceIoControlFile: hFile=%#zx hEvt=%#zx Apc=%p/%p pIos=%p->{s:%#x, i:%#zx} uFunction=% #xInput=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n",223 hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pIos->Status, pIos->Information, uFunction,248 Log12(("VID!NtDeviceIoControlFile: hFile=%#zx hEvt=%#zx Apc=%p/%p pIos=%p->{s:%#x, i:%#zx} uFunction=%s Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n", 249 hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pIos->Status, pIos->Information, pszFunction, 224 250 pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress())); 251 if (cbOutput > 0 && pvOutput) 252 { 253 Log12(("VID!NtDeviceIoControlFile: %s/output: %.*Rhxs\n", pszFunction, RT_MIN(cbOutput, 32), pvOutput)); 254 if (uFunction == 0x2210cc && g_pMsgSlotMapping == NULL && cbOutput >= sizeof(void *)) 255 { 256 g_pMsgSlotMapping = *(VID_MESSAGE_MAPPING_HEADER **)pvOutput; 257 g_pHvMsgHdr = (const HV_MESSAGE_HEADER *)(g_pMsgSlotMapping + 1); 258 g_pX64MsgHdr = (const HV_X64_INTERCEPT_MESSAGE_HEADER *)(g_pHvMsgHdr + 1); 259 Log12(("VID!NtDeviceIoControlFile: Message slot mapping: %p\n", g_pMsgSlotMapping)); 260 } 261 } 262 if (g_pMsgSlotMapping && (uFunction == 0x2210cb || uFunction == 0x2210cc || uFunction == 0x221164)) 263 Log12(("VID!NtDeviceIoControlFile: enmVidMsgType=%#x cb=%#x msg=%#x payload=%u cs:rip=%04x:%08RX64 (%s)\n", 264 g_pMsgSlotMapping->enmVidMsgType, g_pMsgSlotMapping->cbMessage, 265 g_pHvMsgHdr->MessageType, g_pHvMsgHdr->PayloadSize, 266 g_pX64MsgHdr->CsSegment.Selector, g_pX64MsgHdr->Rip, pszFunction)); 267 225 268 return rcNt; 226 269 } … … 304 347 Assert(fSuccess); 305 348 } 306 #endif 307 349 350 #endif /* NEM_WIN_INTERCEPT_NT_IO_CTLS */ 308 351 309 352 … … 456 499 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 457 500 "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc (Last=%#x/%u)", 458 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);501 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 459 502 if (!Caps.HypervisorPresent) 460 503 { … … 475 518 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 476 519 "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc (Last=%#x/%u)", 477 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);520 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 478 521 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeExtendedVmExits", "%'#018RX64", Caps.ExtendedVmExits.AsUINT64); 479 522 pVM->nem.s.fExtendedMsrExit = RT_BOOL(Caps.ExtendedVmExits.X64MsrExit); … … 495 538 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 496 539 "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc (Last=%#x/%u)", 497 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);540 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 498 541 if (Caps.Features.AsUINT64 & ~(uint64_t)0) 499 542 LogRel(("NEM: Warning! Unknown feature definitions: %#RX64\n", Caps.Features.AsUINT64)); … … 508 551 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 509 552 "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc (Last=%#x/%u)", 510 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);553 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 511 554 switch (Caps.ProcessorVendor) 512 555 { … … 533 576 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 534 577 "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc (Last=%#x/%u)", 535 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);578 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 536 579 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorFeatures", "%'#018RX64", Caps.ProcessorFeatures.AsUINT64); 537 580 #define NEM_LOG_REL_CPU_FEATURE(a_Field) NEM_LOG_REL_CAP_SUB(#a_Field, Caps.ProcessorFeatures.a_Field) … … 592 635 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 593 636 "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc (Last=%#x/%u)", 594 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);637 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 595 638 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorClFlushSize", "2^%u", Caps.ProcessorClFlushSize); 596 639 if (Caps.ProcessorClFlushSize < 8 && Caps.ProcessorClFlushSize > 9) … … 650 693 if (FAILED(hrc)) 651 694 return RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, "WHvCreatePartition failed with %Rhrc (Last=%#x/%u)", 652 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);695 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 653 696 654 697 int rc; … … 696 739 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, 697 740 "Failed setting WHvPartitionPropertyCodeProcessorCount to %u: %Rhrc (Last=%#x/%u)", 698 pVM->cCpus, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);741 pVM->cCpus, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 699 742 WHvDeletePartition(hPartition); 700 743 … … 799 842 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 800 843 "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc (Last=%#x/%u)", 801 Property.ProcessorVendor, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);844 Property.ProcessorVendor, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 802 845 803 846 /* Not sure if we really need to set the cache line flush size. */ … … 809 852 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 810 853 "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc (Last=%#x/%u)", 811 pVM->nem.s.cCacheLineFlushShift, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);854 pVM->nem.s.cCacheLineFlushShift, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 812 855 813 856 /* … … 824 867 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 825 868 "Failed to set WHvPartitionPropertyCodeProcessorFeatures to %'#RX64: %Rhrc (Last=%#x/%u)", 826 pVM->nem.s.uCpuFeatures.u64, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);869 pVM->nem.s.uCpuFeatures.u64, hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 827 870 828 871 /* … … 836 879 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 837 880 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", 838 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);881 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()); 839 882 840 883 /* Get the handle. */ … … 858 901 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 859 902 "Failed to get device handle and/or partition ID for %p (hPartitionDevice=%p, Last=%#x/%u)", 860 hPartition, hPartitionDevice, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue);903 hPartition, hPartitionDevice, RTNtLastStatusValue(), RTNtLastErrorValue()); 861 904 pVM->nem.s.hPartitionDevice = hPartitionDevice; 862 905 pVM->nem.s.idHvPartition = idHvPartition; 863 906 864 907 /* 865 * Create EMTs.908 * Setup the EMTs. 866 909 */ 867 910 VMCPUID iCpu; 868 911 for (iCpu = 0; iCpu < pVM->cCpus; iCpu++) 869 912 { 913 PVMCPU pVCpu = &pVM->aCpus[iCpu]; 914 915 pVCpu->nem.s.hNativeThreadHandle = (RTR3PTR)RTThreadGetNativeHandle(VMR3GetThreadHandle(pVCpu->pUVCpu)); 916 Assert((HANDLE)pVCpu->nem.s.hNativeThreadHandle != INVALID_HANDLE_VALUE); 917 918 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 919 VID_MAPPED_MESSAGE_SLOT MappedMsgSlot = { NULL, UINT32_MAX, UINT32_MAX }; 920 if (g_pfnVidMessageSlotMap(hPartitionDevice, &MappedMsgSlot, iCpu)) 921 { 922 AssertLogRelMsg(MappedMsgSlot.iCpu == iCpu && MappedMsgSlot.uParentAdvisory == UINT32_MAX, 923 ("%#x %#x (iCpu=%#x)\n", MappedMsgSlot.iCpu, MappedMsgSlot.uParentAdvisory, iCpu)); 924 pVCpu->nem.s.pvMsgSlotMapping = MappedMsgSlot.pMsgBlock; 925 } 926 else 927 { 928 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 929 DWORD const dwErrLast = RTNtLastErrorValue(); 930 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 931 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 932 } 933 #else 870 934 hrc = WHvCreateVirtualProcessor(hPartition, iCpu, 0 /*fFlags*/); 871 935 if (FAILED(hrc)) 872 936 { 873 NTSTATUS const rcNtLast = RTNt CurrentTeb()->LastStatusValue;874 DWORD const dwErrLast = RTNt CurrentTeb()->LastErrorValue;937 NTSTATUS const rcNtLast = RTNtLastStatusValue(); 938 DWORD const dwErrLast = RTNtLastErrorValue(); 875 939 while (iCpu-- > 0) 876 940 { 877 941 HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu); 878 942 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 879 hPartition, iCpu, hrc2, RTNt CurrentTeb()->LastStatusValue,880 RTNt CurrentTeb()->LastErrorValue));943 hPartition, iCpu, hrc2, RTNtLastStatusValue(), 944 RTNtLastErrorValue())); 881 945 } 882 946 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 883 947 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 884 948 } 949 #endif /* !NEM_WIN_USE_OUR_OWN_RUN_API */ 885 950 } 886 951 pVM->nem.s.fCreatedEmts = true; … … 912 977 while (iCpu-- > 0) 913 978 { 979 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 980 pVM->aCpus[iCpu].nem.s.pvMsgSlotMapping = NULL; 981 #else 914 982 HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu); 915 983 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 916 hPartition, iCpu, hrc, RTNtCurrentTeb()->LastStatusValue, 917 RTNtCurrentTeb()->LastErrorValue)); 984 hPartition, iCpu, hrc, RTNtLastStatusValue(), 985 RTNtLastErrorValue())); 986 #endif 918 987 } 919 988 WHvDeletePartition(hPartition); … … 1293 1362 AssertLogRelMsgFailed(("WHvSetVirtualProcessorRegisters(%p, %u,,%u,) -> %Rhrc (Last=%#x/%u)\n", 1294 1363 pVM->nem.s.hPartition, pVCpu->idCpu, iReg, 1295 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));1364 hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 1296 1365 return VERR_INTERNAL_ERROR; 1297 1366 #endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ … … 1666 1735 AssertLogRelMsgFailed(("WHvGetVirtualProcessorRegisters(%p, %u,,%u,) -> %Rhrc (Last=%#x/%u)\n", 1667 1736 pVM->nem.s.hPartition, pVCpu->idCpu, cRegs, 1668 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));1737 hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 1669 1738 return VERR_INTERNAL_ERROR; 1670 1739 #endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */ … … 1673 1742 1674 1743 #ifdef LOG_ENABLED 1744 /** 1745 * Get the virtual processor running status. 1746 */ 1747 DECLINLINE(VID_PROCESSOR_STATUS) nemR3WinCpuGetRunningStatus(PVMCPU pVCpu) 1748 { 1749 RTERRVARS Saved; 1750 RTErrVarsSave(&Saved); 1751 1752 /* 1753 * This API is disabled in release builds, it seems. On build 17101 it requires 1754 * the following patch to be enabled (windbg): eb vid+12180 0f 84 98 00 00 00 1755 */ 1756 VID_PROCESSOR_STATUS enmCpuStatus = VidProcessorStatusUndefined; 1757 NTSTATUS rcNt = g_pfnVidGetVirtualProcessorRunningStatus(pVCpu->pVMR3->nem.s.hPartitionDevice, pVCpu->idCpu, &enmCpuStatus); 1758 AssertRC(rcNt); 1759 1760 RTErrVarsRestore(&Saved); 1761 return enmCpuStatus; 1762 } 1763 #endif 1764 1765 1766 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 1767 1768 /** 1769 * Our own WHvCancelRunVirtualProcessor that can later be moved to ring-0. 1770 * 1771 * This is an experiment only. 1772 * 1773 * @returns VBox status code. 1774 * @param pVM The cross context VM structure. 1775 * @param pVCpu The cross context virtual CPU structure of the 1776 * calling EMT. 1777 */ 1778 static int nemR3WinCancelRunVirtualProcessor(PVM pVM, PVMCPU pVCpu) 1779 { 1780 /* 1781 * Work the state. 1782 * 1783 * From the looks of things, we should let the EMT call VidStopVirtualProcessor. 1784 * So, we just need to modify the state and kick the EMT if it's waiting on 1785 * messages. For the latter we use QueueUserAPC / KeAlterThread. 1786 */ 1787 for (;;) 1788 { 1789 VMCPUSTATE enmState = VMCPU_GET_STATE(pVCpu); 1790 switch (enmState) 1791 { 1792 case VMCPUSTATE_STARTED_EXEC_NEM: 1793 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM)) 1794 { 1795 Log8(("nemR3WinCancelRunVirtualProcessor: Switched %u to canceled state\n", pVCpu->idCpu)); 1796 return VINF_SUCCESS; 1797 } 1798 break; 1799 1800 case VMCPUSTATE_STARTED_EXEC_NEM_WAIT: 1801 { 1802 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT)) 1803 { 1804 NTSTATUS rcNt = NtAlertThread(pVCpu->nem.s.hNativeThreadHandle); 1805 Log8(("nemR3WinCancelRunVirtualProcessor: Alerted %u: %#x\n", pVCpu->idCpu, rcNt)); 1806 Assert(rcNt == STATUS_SUCCESS); 1807 if (NT_SUCCESS(rcNt)) 1808 return VINF_SUCCESS; 1809 AssertLogRelMsgFailedReturn(("NtAlertThread failed: %#x\n", rcNt), RTErrConvertFromNtStatus(rcNt)); 1810 } 1811 break; 1812 } 1813 1814 default: 1815 return VINF_SUCCESS; 1816 } 1817 1818 ASMNopPause(); 1819 RT_NOREF(pVM); 1820 } 1821 } 1822 1823 1824 /** 1825 * Fills in WHV_VP_EXIT_CONTEXT from HV_X64_INTERCEPT_MESSAGE_HEADER. 1826 */ 1827 DECLINLINE(void) nemR3WinConvertX64MsgHdrToVpExitCtx(HV_X64_INTERCEPT_MESSAGE_HEADER const *pHdr, WHV_VP_EXIT_CONTEXT *pCtx) 1828 { 1829 pCtx->ExecutionState.AsUINT16 = pHdr->ExecutionState.AsUINT16; 1830 pCtx->InstructionLength = pHdr->InstructionLength; 1831 pCtx->Cs.Base = pHdr->CsSegment.Base; 1832 pCtx->Cs.Limit = pHdr->CsSegment.Limit; 1833 pCtx->Cs.Selector = pHdr->CsSegment.Selector; 1834 pCtx->Cs.Attributes = pHdr->CsSegment.Attributes; 1835 pCtx->Rip = pHdr->Rip; 1836 pCtx->Rflags = pHdr->Rflags; 1837 } 1838 1839 1840 /** 1841 * Convert hyper-V exit message to the WinHvPlatform structures. 1842 * 1843 * @returns VBox status code 1844 * @param pMsgHdr The message to convert. 1845 * @param pExitCtx The output structure. Assumes zeroed. 1846 */ 1847 static int nemR3WinRunVirtualProcessorConvertPending(HV_MESSAGE_HEADER const *pMsgHdr, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx) 1848 { 1849 switch (pMsgHdr->MessageType) 1850 { 1851 case HvMessageTypeUnmappedGpa: 1852 case HvMessageTypeGpaIntercept: 1853 { 1854 PCHV_X64_MEMORY_INTERCEPT_MESSAGE pMemMsg = (PCHV_X64_MEMORY_INTERCEPT_MESSAGE)(pMsgHdr + 1); 1855 Assert(pMsgHdr->PayloadSize == RT_UOFFSETOF(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment)); 1856 1857 pExitCtx->ExitReason = WHvRunVpExitReasonMemoryAccess; 1858 nemR3WinConvertX64MsgHdrToVpExitCtx(&pMemMsg->Header, &pExitCtx->MemoryAccess.VpContext); 1859 pExitCtx->MemoryAccess.InstructionByteCount = pMemMsg->InstructionByteCount; 1860 ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[0] = ((uint64_t const *)pMemMsg->InstructionBytes)[0]; 1861 ((uint64_t *)pExitCtx->MemoryAccess.InstructionBytes)[1] = ((uint64_t const *)pMemMsg->InstructionBytes)[1]; 1862 1863 pExitCtx->MemoryAccess.AccessInfo.AccessType = pMemMsg->Header.InterceptAccessType; 1864 pExitCtx->MemoryAccess.AccessInfo.GpaUnmapped = pMsgHdr->MessageType == HvMessageTypeUnmappedGpa; 1865 pExitCtx->MemoryAccess.AccessInfo.GvaValid = pMemMsg->MemoryAccessInfo.GvaValid; 1866 pExitCtx->MemoryAccess.AccessInfo.Reserved = pMemMsg->MemoryAccessInfo.Reserved; 1867 pExitCtx->MemoryAccess.Gpa = pMemMsg->GuestPhysicalAddress; 1868 pExitCtx->MemoryAccess.Gva = pMemMsg->GuestVirtualAddress; 1869 return VINF_SUCCESS; 1870 } 1871 1872 case HvMessageTypeX64IoPortIntercept: 1873 { 1874 PCHV_X64_IO_PORT_INTERCEPT_MESSAGE pPioMsg= (PCHV_X64_IO_PORT_INTERCEPT_MESSAGE)(pMsgHdr + 1); 1875 Assert(pMsgHdr->PayloadSize == sizeof(*pPioMsg)); 1876 1877 pExitCtx->ExitReason = WHvRunVpExitReasonX64IoPortAccess; 1878 nemR3WinConvertX64MsgHdrToVpExitCtx(&pPioMsg->Header, &pExitCtx->IoPortAccess.VpContext); 1879 pExitCtx->IoPortAccess.InstructionByteCount = pPioMsg->InstructionByteCount; 1880 ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[0] = ((uint64_t const *)pPioMsg->InstructionBytes)[0]; 1881 ((uint64_t *)pExitCtx->IoPortAccess.InstructionBytes)[1] = ((uint64_t const *)pPioMsg->InstructionBytes)[1]; 1882 1883 pExitCtx->IoPortAccess.AccessInfo.IsWrite = pPioMsg->Header.InterceptAccessType == HV_INTERCEPT_ACCESS_WRITE; 1884 pExitCtx->IoPortAccess.AccessInfo.AccessSize = pPioMsg->AccessInfo.AccessSize; 1885 pExitCtx->IoPortAccess.AccessInfo.StringOp = pPioMsg->AccessInfo.StringOp; 1886 pExitCtx->IoPortAccess.AccessInfo.RepPrefix = pPioMsg->AccessInfo.RepPrefix; 1887 pExitCtx->IoPortAccess.AccessInfo.Reserved = pPioMsg->AccessInfo.Reserved; 1888 pExitCtx->IoPortAccess.PortNumber = pPioMsg->PortNumber; 1889 pExitCtx->IoPortAccess.Rax = pPioMsg->Rax; 1890 pExitCtx->IoPortAccess.Rcx = pPioMsg->Rcx; 1891 pExitCtx->IoPortAccess.Rsi = pPioMsg->Rsi; 1892 pExitCtx->IoPortAccess.Rdi = pPioMsg->Rdi; 1893 pExitCtx->IoPortAccess.Ds.Base = pPioMsg->DsSegment.Base; 1894 pExitCtx->IoPortAccess.Ds.Limit = pPioMsg->DsSegment.Limit; 1895 pExitCtx->IoPortAccess.Ds.Selector = pPioMsg->DsSegment.Selector; 1896 pExitCtx->IoPortAccess.Ds.Attributes = pPioMsg->DsSegment.Attributes; 1897 pExitCtx->IoPortAccess.Es.Base = pPioMsg->EsSegment.Base; 1898 pExitCtx->IoPortAccess.Es.Limit = pPioMsg->EsSegment.Limit; 1899 pExitCtx->IoPortAccess.Es.Selector = pPioMsg->EsSegment.Selector; 1900 pExitCtx->IoPortAccess.Es.Attributes = pPioMsg->EsSegment.Attributes; 1901 return VINF_SUCCESS; 1902 } 1903 1904 case HvMessageTypeX64Halt: 1905 { 1906 PCHV_X64_HALT_MESSAGE pHaltMsg = (PCHV_X64_HALT_MESSAGE)(pMsgHdr + 1); 1907 AssertMsg(pHaltMsg->u64Reserved == 0, ("HALT reserved: %#RX64\n", pHaltMsg->u64Reserved)); 1908 pExitCtx->ExitReason = WHvRunVpExitReasonX64Halt; 1909 return VINF_SUCCESS; 1910 } 1911 1912 case HvMessageTypeX64InterruptWindow: 1913 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2); 1914 1915 case HvMessageTypeInvalidVpRegisterValue: 1916 case HvMessageTypeUnrecoverableException: 1917 case HvMessageTypeUnsupportedFeature: 1918 case HvMessageTypeTlbPageSizeMismatch: 1919 AssertLogRelMsgFailedReturn(("Message type %#x not implemented!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2); 1920 1921 case HvMessageTypeX64MsrIntercept: 1922 case HvMessageTypeX64CpuidIntercept: 1923 case HvMessageTypeX64ExceptionIntercept: 1924 case HvMessageTypeX64ApicEoi: 1925 case HvMessageTypeX64LegacyFpError: 1926 case HvMessageTypeX64RegisterIntercept: 1927 case HvMessageTypeApicEoi: 1928 case HvMessageTypeFerrAsserted: 1929 case HvMessageTypeEventLogBufferComplete: 1930 case HvMessageTimerExpired: 1931 AssertLogRelMsgFailedReturn(("Unexpected message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2); 1932 1933 default: 1934 AssertLogRelMsgFailedReturn(("Unknown message type #x!\n", pMsgHdr->MessageType), VERR_INTERNAL_ERROR_2); 1935 } 1936 } 1937 1938 1939 /** 1940 * Our own WHvRunVirtualProcessor that can later be moved to ring-0. 1941 * 1942 * This is an experiment only. 1943 * 1944 * @returns VBox status code. 1945 * @param pVM The cross context VM structure. 1946 * @param pVCpu The cross context virtual CPU structure of the 1947 * calling EMT. 1948 * @param pExitCtx Where to return exit information. 1949 * @param cbExitCtx Size of the exit information area. 1950 */ 1951 static int nemR3WinRunVirtualProcessor(PVM pVM, PVMCPU pVCpu, WHV_RUN_VP_EXIT_CONTEXT *pExitCtx, size_t cbExitCtx) 1952 { 1953 RT_BZERO(pExitCtx, cbExitCtx); 1954 1955 /* 1956 * Tell the CPU to execute stuff if we haven't got a pending message. 1957 */ 1958 VID_MESSAGE_MAPPING_HEADER volatile *pMappingHeader = (VID_MESSAGE_MAPPING_HEADER volatile *)pVCpu->nem.s.pvMsgSlotMapping; 1959 uint32_t fHandleAndGetFlags; 1960 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED)) 1961 { 1962 uint8_t const bMsgState = pVCpu->nem.s.bMsgState; 1963 if (bMsgState == NEM_WIN_MSG_STATE_PENDING_MSG) 1964 { 1965 Assert(pMappingHeader->enmVidMsgType == VidMessageHypervisorMessage); 1966 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE | VID_MSHAGN_F_HANDLE_MESSAGE; 1967 Log8(("nemR3WinRunVirtualProcessor: #1: msg pending, no need to start CPU (cpu state %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 1968 } 1969 else if (bMsgState != NEM_WIN_MSG_STATE_STARTED) 1970 { 1971 if (bMsgState == NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG) 1972 { 1973 Log8(("nemR3WinRunVirtualProcessor: #0: pending stop+message (cpu status %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 1974 /* ACK the pending message and get the stop message. */ 1975 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1976 VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000); 1977 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue())); 1978 1979 /* ACK the stop message. */ 1980 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 1981 VID_MSHAGN_F_HANDLE_MESSAGE, 5000); 1982 AssertLogRelMsg(fWait, ("dwErr=%u (%#x) rcNt=%#x\n", RTNtLastErrorValue(), RTNtLastErrorValue(), RTNtLastStatusValue())); 1983 1984 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED; 1985 } 1986 1987 Log8(("nemR3WinRunVirtualProcessor: #1: starting CPU (cpu status %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 1988 if (g_pfnVidStartVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu)) 1989 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED; 1990 else 1991 { 1992 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM); 1993 AssertLogRelMsgFailedReturn(("VidStartVirtualProcessor failed for CPU #%u: rcNt=%#x dwErr=%u\n", 1994 pVCpu->idCpu, RTNtLastStatusValue(), RTNtLastErrorValue()), 1995 VERR_INTERNAL_ERROR_3); 1996 } 1997 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; 1998 } 1999 else 2000 { 2001 /* This shouldn't happen. */ 2002 fHandleAndGetFlags = VID_MSHAGN_F_GET_NEXT_MESSAGE; 2003 Log8(("nemR3WinRunVirtualProcessor: #1: NO MSG PENDING! No need to start CPU (cpu state %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 2004 } 2005 } 2006 else 2007 { 2008 Log8(("nemR3WinRunVirtualProcessor: #1: state=%u -> canceled (cpu status %u)\n", 2009 VMCPU_GET_STATE(pVCpu), nemR3WinCpuGetRunningStatus(pVCpu))); 2010 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled; 2011 return VINF_SUCCESS; 2012 } 2013 2014 /* 2015 * Wait for it to stop and give us a reason to work with. 2016 */ 2017 uint32_t cMillies = 5000; // Starting low so we can experiment without getting stuck. 2018 for (;;) 2019 { 2020 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_WAIT, VMCPUSTATE_STARTED_EXEC_NEM)) 2021 { 2022 Log8(("nemR3WinRunVirtualProcessor: #2: Waiting %#x (cpu status %u)...\n", 2023 fHandleAndGetFlags, nemR3WinCpuGetRunningStatus(pVCpu))); 2024 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 2025 fHandleAndGetFlags, cMillies); 2026 if (fWait) 2027 { 2028 /* Not sure yet, but we have to check whether there is anything pending 2029 and retry if there isn't. */ 2030 VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType; 2031 if (enmVidMsgType == VidMessageHypervisorMessage) 2032 { 2033 if (!VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT)) 2034 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED); 2035 Log8(("nemR3WinRunVirtualProcessor: #3: wait succeeded: %#x / %#x (cpu status %u)\n", 2036 enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, 2037 nemR3WinCpuGetRunningStatus(pVCpu) )); 2038 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG; 2039 return nemR3WinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx); 2040 } 2041 2042 /* This shouldn't happen, and I think its wrong. */ 2043 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT); 2044 #ifdef DEBUG_bird 2045 __debugbreak(); 2046 #endif 2047 Log8(("nemR3WinRunVirtualProcessor: #3: wait succeeded, but nothing pending: %#x / %#x (cpu status %u)\n", 2048 enmVidMsgType, ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemR3WinCpuGetRunningStatus(pVCpu) )); 2049 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED; 2050 AssertLogRelMsgReturnStmt(enmVidMsgType == VidMessageStopRequestComplete, 2051 ("enmVidMsgType=%#x\n", enmVidMsgType), 2052 g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu), 2053 VERR_INTERNAL_ERROR_3); 2054 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE; 2055 } 2056 else 2057 { 2058 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED_EXEC_NEM_WAIT); 2059 2060 /* Note! VID.SYS merges STATUS_ALERTED and STATUS_USER_APC into STATUS_TIMEOUT. */ 2061 DWORD const dwErr = RTNtLastErrorValue(); 2062 AssertLogRelMsgReturnStmt( dwErr == STATUS_TIMEOUT 2063 || dwErr == STATUS_ALERTED || dwErr == STATUS_USER_APC, /* just in case */ 2064 ("dwErr=%u (%#x) (cpu status %u)\n", dwErr, dwErr, nemR3WinCpuGetRunningStatus(pVCpu)), 2065 g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu), 2066 VERR_INTERNAL_ERROR_3); 2067 Log8(("nemR3WinRunVirtualProcessor: #3: wait timed out (cpu status %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 2068 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STARTED; 2069 fHandleAndGetFlags &= ~VID_MSHAGN_F_HANDLE_MESSAGE; 2070 } 2071 } 2072 else 2073 { 2074 /* 2075 * State changed and we need to return. 2076 * 2077 * We must ensure that the processor is not running while we 2078 * return, and that can be a bit complicated. 2079 */ 2080 Log8(("nemR3WinRunVirtualProcessor: #4: state changed to %u (cpu status %u)\n", 2081 VMCPU_GET_STATE(pVCpu), nemR3WinCpuGetRunningStatus(pVCpu) )); 2082 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED); 2083 2084 /* If we haven't marked the pervious message as handled, simply return 2085 without doing anything special. */ 2086 if (fHandleAndGetFlags & VID_MSHAGN_F_HANDLE_MESSAGE) 2087 { 2088 Log8(("nemR3WinRunVirtualProcessor: #5: Didn't resume previous message.\n")); 2089 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_MSG; 2090 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled; 2091 return VINF_SUCCESS; 2092 } 2093 2094 /* The processor is running, so try stop it. */ 2095 BOOL fStop = g_pfnVidStopVirtualProcessor(pVM->nem.s.hPartitionDevice, pVCpu->idCpu); 2096 if (fStop) 2097 { 2098 Log8(("nemR3WinRunVirtualProcessor: #5: Stopping CPU succeeded (cpu status %u)\n", nemR3WinCpuGetRunningStatus(pVCpu) )); 2099 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED; 2100 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled; 2101 return VINF_SUCCESS; 2102 } 2103 2104 /* Dang, the CPU stopped by itself with a message pending. */ 2105 DWORD dwErr = RTNtLastErrorValue(); 2106 Log8(("nemR3WinRunVirtualProcessor: #5: Stopping CPU failed (%u/%#x) - cpu status %u\n", 2107 dwErr, dwErr, nemR3WinCpuGetRunningStatus(pVCpu) )); 2108 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled; 2109 AssertLogRelMsgReturn(dwErr == ERROR_VID_STOP_PENDING, ("dwErr=%#u\n", dwErr), VERR_INTERNAL_ERROR_3); 2110 2111 /* Get the pending message. */ 2112 BOOL fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 2113 VID_MSHAGN_F_GET_NEXT_MESSAGE, 5000); 2114 AssertLogRelMsgReturn(fWait, ("error=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3); 2115 2116 VID_MESSAGE_TYPE const enmVidMsgType = pMappingHeader->enmVidMsgType; 2117 if (enmVidMsgType == VidMessageHypervisorMessage) 2118 { 2119 Log8(("nemR3WinRunVirtualProcessor: #6: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType, 2120 ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemR3WinCpuGetRunningStatus(pVCpu) )); 2121 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG; 2122 return nemR3WinRunVirtualProcessorConvertPending((HV_MESSAGE_HEADER const *)(pMappingHeader + 1), pExitCtx); 2123 } 2124 2125 /* ACK the stop message, if that's what it is. Don't think we'll ever get here. */ 2126 Log8(("nemR3WinRunVirtualProcessor: #6b: wait succeeded: %#x / %#x (cpu status %u)\n", enmVidMsgType, 2127 ((HV_MESSAGE_HEADER const *)(pMappingHeader + 1))->MessageType, nemR3WinCpuGetRunningStatus(pVCpu) )); 2128 AssertLogRelMsgReturn(enmVidMsgType == VidMessageStopRequestComplete, ("enmVidMsgType=%#x\n", enmVidMsgType), 2129 VERR_INTERNAL_ERROR_3); 2130 fWait = g_pfnVidMessageSlotHandleAndGetNext(pVM->nem.s.hPartitionDevice, pVCpu->idCpu, 2131 VID_MSHAGN_F_HANDLE_MESSAGE, 5000); 2132 AssertLogRelMsgReturn(fWait, ("dwErr=%#u\n", RTNtLastErrorValue()), VERR_INTERNAL_ERROR_3); 2133 2134 pVCpu->nem.s.bMsgState = NEM_WIN_MSG_STATE_STOPPED; 2135 pExitCtx->ExitReason = WHvRunVpExitReasonCanceled; 2136 return VINF_SUCCESS; 2137 } 2138 2139 /** @todo check flags and stuff? */ 2140 } 2141 } 2142 2143 #endif /* NEM_WIN_USE_OUR_OWN_RUN_API */ 2144 2145 #ifdef LOG_ENABLED 2146 1675 2147 /** 1676 2148 * Log the full details of an exit reason. … … 1890 2362 #else 1891 2363 LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n", 1892 GCPhys, g_apszPageStates[*pu2NemState], hrc, hrc, RTNt CurrentTeb()->LastStatusValue,1893 RTNt CurrentTeb()->LastErrorValue, pVM->nem.s.cMappedPages));2364 GCPhys, g_apszPageStates[*pu2NemState], hrc, hrc, RTNtLastStatusValue(), 2365 RTNtLastErrorValue(), pVM->nem.s.cMappedPages)); 1894 2366 #endif 1895 2367 *pu2NemState = NEM_WIN_PAGE_STATE_NOT_SET; … … 2072 2544 #else 2073 2545 LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n", 2074 GCPhys, g_apszPageStates[u2State], hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue,2546 GCPhys, g_apszPageStates[u2State], hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue(), 2075 2547 pVM->nem.s.cMappedPages)); 2076 2548 … … 2315 2787 && !VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 2316 2788 { 2789 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 2790 int rc2 = nemR3WinRunVirtualProcessor(pVM, pVCpu, &ExitReason, sizeof(ExitReason)); 2791 AssertRCBreakStmt(rc2, rcStrict = rc2); 2792 #else 2793 Log8(("Calling WHvRunVirtualProcessor\n")); 2317 2794 VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM, VMCPUSTATE_STARTED); 2318 2795 HRESULT hrc = WHvRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, &ExitReason, sizeof(ExitReason)); … … 2320 2797 AssertLogRelMsgBreakStmt(SUCCEEDED(hrc), 2321 2798 ("WHvRunVirtualProcessor(%p, %u,,) -> %Rhrc (Last=%#x/%u)\n", pVM->nem.s.hPartition, pVCpu->idCpu, 2322 hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue),2799 hrc, RTNtLastStatusValue(), RTNtLastErrorValue()), 2323 2800 rcStrict = VERR_INTERNAL_ERROR); 2324 Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d)\n", hrc, ExitReason.ExitReason, ExitReason.ExitReason)); 2801 Log2(("WHvRunVirtualProcessor -> %#x; exit code %#x (%d) (cpu status %u)\n", 2802 hrc, ExitReason.ExitReason, ExitReason.ExitReason, nemR3WinCpuGetRunningStatus(pVCpu) )); 2803 #endif 2325 2804 } 2326 2805 else … … 2494 2973 void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags) 2495 2974 { 2975 #ifdef NEM_WIN_USE_OUR_OWN_RUN_API 2976 nemR3WinCancelRunVirtualProcessor(pVM, pVCpu); 2977 #else 2978 Log8(("nemR3NativeNotifyFF: canceling %u\n", pVCpu->idCpu)); 2496 2979 HRESULT hrc = WHvCancelRunVirtualProcessor(pVM->nem.s.hPartition, pVCpu->idCpu, 0); 2497 2980 AssertMsg(SUCCEEDED(hrc), ("WHvCancelRunVirtualProcessor -> hrc=%Rhrc\n", hrc)); 2498 2499 2981 RT_NOREF_PV(hrc); 2982 #endif 2500 2983 RT_NOREF_PV(fFlags); 2501 2984 } … … 2577 3060 { 2578 3061 LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2579 GCPhys, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3062 GCPhys, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2580 3063 return VERR_NEM_INIT_FAILED; 2581 3064 } … … 2644 3127 #else 2645 3128 LogRel(("nemR3WinUnsetForA20CheckerCallback/unmap: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2646 GCPhys, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3129 GCPhys, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2647 3130 return VERR_INTERNAL_ERROR_2; 2648 3131 #endif … … 2858 3341 { 2859 3342 LogRel(("nemR3NativeSetPhysPage/unmap: GCPhysDst=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2860 GCPhysDst, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3343 GCPhysDst, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2861 3344 return VERR_NEM_INIT_FAILED; 2862 3345 } … … 2901 3384 } 2902 3385 LogRel(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2903 GCPhysDst, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3386 GCPhysDst, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2904 3387 return VERR_NEM_INIT_FAILED; 2905 3388 } … … 2941 3424 } 2942 3425 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysDst=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2943 GCPhysDst, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3426 GCPhysDst, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2944 3427 return VERR_NEM_INIT_FAILED; 2945 3428 } … … 2988 3471 } 2989 3472 LogRel(("nemR3JustUnmapPageFromHyperV(%RGp): failed! hrc=%Rhrc (%#x) Last=%#x/%u\n", 2990 GCPhysDst, hrc, hrc, RTNt CurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));3473 GCPhysDst, hrc, hrc, RTNtLastStatusValue(), RTNtLastErrorValue())); 2991 3474 return VERR_INTERNAL_ERROR_3; 2992 3475 #endif -
trunk/src/VBox/VMM/VMMR3/VM.cpp
r71040 r71129 4533 4533 4534 4534 /** 4535 * Returns the native handleof the current EMT VMCPU thread.4535 * Returns the native ID of the current EMT VMCPU thread. 4536 4536 * 4537 4537 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise … … 4551 4551 4552 4552 /** 4553 * Returns the native handleof the current EMT VMCPU thread.4553 * Returns the native ID of the current EMT VMCPU thread. 4554 4554 * 4555 4555 * @returns Handle if this is an EMT thread; NIL_RTNATIVETHREAD otherwise … … 4582 4582 return NIL_RTTHREAD; 4583 4583 4584 return pUVCpu->vm.s.ThreadEMT; 4585 } 4586 4587 4588 /** 4589 * Returns the handle of the current EMT VMCPU thread. 4590 * 4591 * @returns The IPRT thread handle. 4592 * @param pUVCpu The user mode CPU handle. 4593 * @thread EMT 4594 */ 4595 VMMR3_INT_DECL(RTTHREAD) VMR3GetThreadHandle(PUVMCPU pUVCpu) 4596 { 4584 4597 return pUVCpu->vm.s.ThreadEMT; 4585 4598 } -
trunk/src/VBox/VMM/VMMR3/VMEmt.cpp
r71040 r71129 859 859 } 860 860 } 861 else if (enmState == VMCPUSTATE_STARTED_EXEC_NEM) 861 else if ( enmState == VMCPUSTATE_STARTED_EXEC_NEM 862 || enmState == VMCPUSTATE_STARTED_EXEC_NEM_WAIT) 862 863 NEMR3NotifyFF(pUVCpu->pVM, pVCpu, fFlags); 863 864 #ifdef VBOX_WITH_REM … … 1001 1002 { 1002 1003 VMCPUSTATE enmState = pVCpu->enmState; 1003 if (enmState == VMCPUSTATE_STARTED_EXEC_NEM) 1004 if ( enmState == VMCPUSTATE_STARTED_EXEC_NEM 1005 || enmState == VMCPUSTATE_STARTED_EXEC_NEM_WAIT) 1004 1006 NEMR3NotifyFF(pUVCpu->pVM, pVCpu, fFlags); 1005 1007 #ifdef VBOX_WITH_REM
Note:
See TracChangeset
for help on using the changeset viewer.