Changeset 71131 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Feb 26, 2018 7:27:32 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 121017
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r71129 r71131 78 78 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) ) 79 79 80 81 82 /********************************************************************************************************************************* 83 * Structures and Typedefs * 84 *********************************************************************************************************************************/ 80 /** VID I/O control detection: Fake partition handle input. */ 81 #define NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE ((HANDLE)(uintptr_t)38479125) 82 /** VID I/O control detection: Fake partition ID return. */ 83 #define NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID UINT64_C(0xfa1e000042424242) 84 /** VID I/O control detection: Fake CPU index input. */ 85 #define NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX UINT32_C(42) 86 /** VID I/O control detection: Fake timeout input. */ 87 #define NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT UINT32_C(0x00080286) 85 88 86 89 … … 118 121 static decltype(VidMessageSlotHandleAndGetNext) *g_pfnVidMessageSlotHandleAndGetNext; 119 122 #ifdef LOG_ENABLED 123 static decltype(VidGetVirtualProcessorState) *g_pfnVidGetVirtualProcessorState; 124 static decltype(VidSetVirtualProcessorState) *g_pfnVidSetVirtualProcessorState; 120 125 static decltype(VidGetVirtualProcessorRunningStatus) *g_pfnVidGetVirtualProcessorRunningStatus; 121 126 #endif … … 159 164 NEM_WIN_IMPORT(1, false, VidStopVirtualProcessor), 160 165 #ifdef LOG_ENABLED 166 NEM_WIN_IMPORT(1, false, VidGetVirtualProcessorState), 167 NEM_WIN_IMPORT(1, false, VidSetVirtualProcessorState), 161 168 NEM_WIN_IMPORT(1, false, VidGetVirtualProcessorRunningStatus), 162 169 #endif 163 170 #undef NEM_WIN_IMPORT 164 171 }; 172 173 174 /** The real NtDeviceIoControlFile API in NTDLL. */ 175 static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile; 176 /** Pointer to the NtDeviceIoControlFile import table entry. */ 177 static decltype(NtDeviceIoControlFile) **g_ppfnVidNtDeviceIoControlFile; 178 /** Info about the VidGetHvPartitionId I/O control interface. */ 179 static NEMWINIOCTL g_IoCtlGetHvPartitionId; 180 /** Info about the VidStartVirtualProcessor I/O control interface. */ 181 static NEMWINIOCTL g_IoCtlStartVirtualProcessor; 182 /** Info about the VidStopVirtualProcessor I/O control interface. */ 183 static NEMWINIOCTL g_IoCtlStopVirtualProcessor; 184 /** Info about the VidMessageSlotHandleAndGetNext I/O control interface. */ 185 static NEMWINIOCTL g_IoCtlMessageSlotHandleAndGetNext; 186 #ifdef LOG_ENABLED 187 /** Info about the VidMessageSlotMap I/O control interface - for logging. */ 188 static NEMWINIOCTL g_IoCtlMessageSlotMap; 189 /* Info about the VidGetVirtualProcessorState I/O control interface - for logging. */ 190 static NEMWINIOCTL g_IoCtlGetVirtualProcessorState; 191 /* Info about the VidSetVirtualProcessorState I/O control interface - for logging. */ 192 static NEMWINIOCTL g_IoCtlSetVirtualProcessorState; 193 /** Pointer to what nemR3WinIoctlDetector_ForLogging should fill in. */ 194 static NEMWINIOCTL *g_pIoCtlDetectForLogging; 195 #endif 196 197 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 198 /** Mapping slot for CPU #0. 199 * @{ */ 200 static VID_MESSAGE_MAPPING_HEADER *g_pMsgSlotMapping = NULL; 201 static const HV_MESSAGE_HEADER *g_pHvMsgHdr; 202 static const HV_X64_INTERCEPT_MESSAGE_HEADER *g_pX64MsgHdr; 203 /** @} */ 204 #endif 165 205 166 206 … … 200 240 201 241 242 202 243 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 203 204 /** The real NtDeviceIoControlFile API in NTDLL. */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 213 214 244 /** 215 245 * Wrapper that logs the call from VID.DLL. … … 222 252 PVOID pvOutput, ULONG cbOutput) 223 253 { 254 224 255 char szFunction[32]; 225 256 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; 257 if (uFunction == g_IoCtlMessageSlotHandleAndGetNext.uFunction) 258 pszFunction = "VidMessageSlotHandleAndGetNext"; 259 else if (uFunction == g_IoCtlStartVirtualProcessor.uFunction) 260 pszFunction = "VidStartVirtualProcessor"; 261 else if (uFunction == g_IoCtlStopVirtualProcessor.uFunction) 262 pszFunction = "VidStopVirtualProcessor"; 263 else if (uFunction == g_IoCtlMessageSlotMap.uFunction) 264 pszFunction = "VidMessageSlotMap"; 265 else if (uFunction == g_IoCtlGetVirtualProcessorState.uFunction) 266 pszFunction = "VidGetVirtualProcessorState"; 267 else if (uFunction == g_IoCtlSetVirtualProcessorState.uFunction) 268 pszFunction = "VidSetVirtualProcessorState"; 269 else 270 { 271 RTStrPrintf(szFunction, sizeof(szFunction), "%#x", uFunction); 272 pszFunction = szFunction; 238 273 } 239 274 … … 260 295 } 261 296 } 262 if (g_pMsgSlotMapping && (uFunction == 0x2210cb || uFunction == 0x2210cc || uFunction == 0x221164)) 297 if ( g_pMsgSlotMapping 298 && ( uFunction == g_IoCtlMessageSlotHandleAndGetNext.uFunction 299 || uFunction == g_IoCtlStopVirtualProcessor.uFunction 300 || uFunction == g_IoCtlMessageSlotMap.uFunction 301 )) 263 302 Log12(("VID!NtDeviceIoControlFile: enmVidMsgType=%#x cb=%#x msg=%#x payload=%u cs:rip=%04x:%08RX64 (%s)\n", 264 303 g_pMsgSlotMapping->enmVidMsgType, g_pMsgSlotMapping->cbMessage, … … 268 307 return rcNt; 269 308 } 309 #endif /* NEM_WIN_INTERCEPT_NT_IO_CTLS */ 270 310 271 311 272 312 /** 273 * Patches the call table of VID.DLL so we can intercept and log 274 * NtDeviceIoControlFile. 275 * 276 * This is for DEBUGGING only. 277 * 313 * Patches the call table of VID.DLL so we can intercept NtDeviceIoControlFile. 314 * 315 * This is for used to figure out the I/O control codes and in logging builds 316 * for logging API calls that WinHvPlatform.dll does. 317 * 318 * @returns VBox status code. 278 319 * @param hLdrModVid The VID module handle. 279 */ 280 static void nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid) 320 * @param pErrInfo Where to return additional error information. 321 */ 322 static int nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid, PRTERRINFO pErrInfo) 281 323 { 282 324 /* … … 284 326 */ 285 327 g_pfnNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) *)RTLdrGetSystemSymbol("NTDLL.DLL", "NtDeviceIoControlFile"); 286 AssertReturnVoid(g_pfnNtDeviceIoControlFile > 0); 328 AssertReturn(g_pfnNtDeviceIoControlFile != NULL, 329 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to resolve NtDeviceIoControlFile from NTDLL.DLL")); 287 330 288 331 /* … … 291 334 uint8_t const *pbImage = (uint8_t const *)RTLdrGetNativeHandle(hLdrModVid); 292 335 IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbImage; 293 AssertReturnVoid(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE); 336 AssertReturn(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE, 337 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL mapping doesn't start with MZ signature: %#x", pMzHdr->e_magic)); 294 338 IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)&pbImage[pMzHdr->e_lfanew]; 295 AssertReturnVoid(pNtHdrs->Signature == IMAGE_NT_SIGNATURE); 339 AssertReturn(pNtHdrs->Signature == IMAGE_NT_SIGNATURE, 340 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL has invalid PE signaturre: %#x @%#x", 341 pNtHdrs->Signature, pMzHdr->e_lfanew)); 296 342 297 343 uint32_t const cbImage = pNtHdrs->OptionalHeader.SizeOfImage; … … 301 347 * Walk the import descriptor table looking for NTDLL.DLL. 302 348 */ 303 bool fSuccess = true; 304 AssertReturnVoid(ImportDir.Size > 0); 305 AssertReturnVoid(ImportDir.Size < cbImage); 306 AssertReturnVoid(ImportDir.VirtualAddress > 0); 307 AssertReturnVoid(ImportDir.VirtualAddress < cbImage); 349 AssertReturn( ImportDir.Size > 0 350 && ImportDir.Size < cbImage, 351 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory size: %#x", ImportDir.Size)); 352 AssertReturn( ImportDir.VirtualAddress > 0 353 && ImportDir.VirtualAddress <= cbImage - ImportDir.Size, 354 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory RVA: %#x", ImportDir.VirtualAddress)); 355 308 356 for (PIMAGE_IMPORT_DESCRIPTOR pImps = (PIMAGE_IMPORT_DESCRIPTOR)&pbImage[ImportDir.VirtualAddress]; 309 357 pImps->Name != 0 && pImps->FirstThunk != 0; 310 358 pImps++) 311 359 { 312 AssertReturnVoid(pImps->Name < cbImage); 360 AssertReturn(pImps->Name < cbImage, 361 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad import directory entry name: %#x", pImps->Name)); 313 362 const char *pszModName = (const char *)&pbImage[pImps->Name]; 314 363 if (RTStrICmpAscii(pszModName, "ntdll.dll")) 315 364 continue; 316 AssertReturnVoid(pImps->FirstThunk < cbImage); 317 AssertReturnVoid(pImps->OriginalFirstThunk < cbImage); 365 AssertReturn(pImps->FirstThunk < cbImage, 366 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk)); 367 AssertReturn(pImps->OriginalFirstThunk < cbImage, 368 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk)); 318 369 319 370 /* … … 328 379 if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) 329 380 { 330 AssertReturnVoid(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage); 381 AssertReturn(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage, 382 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "VID.DLL bad FirstThunk: %#x", pImps->FirstThunk)); 331 383 332 384 const char *pszSymbol = (const char *)&pbImage[(uintptr_t)pThunk->u1.AddressOfData + 2]; 333 385 if (strcmp(pszSymbol, "NtDeviceIoControlFile") == 0) 334 386 { 335 DWORD fOldProt = PAGE_ EXECUTE;387 DWORD fOldProt = PAGE_READONLY; 336 388 VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &fOldProt); 337 pFirstThunk->u1.Function = (uintptr_t)nemR3WinLogWrapper_NtDeviceIoControlFile; 338 VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), fOldProt, &fOldProt); 339 fSuccess = true; 389 g_ppfnVidNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) **)&pFirstThunk->u1.Function; 390 /* Don't restore the protection here, so we modify the NtDeviceIoControlFile pointer later. */ 340 391 } 341 392 } … … 345 396 } 346 397 } 347 Assert(fSuccess); 348 } 349 350 #endif /* NEM_WIN_INTERCEPT_NT_IO_CTLS */ 398 399 if (*g_ppfnVidNtDeviceIoControlFile) 400 { 401 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 402 *g_ppfnVidNtDeviceIoControlFile = nemR3WinLogWrapper_NtDeviceIoControlFile; 403 #endif 404 return VINF_SUCCESS; 405 } 406 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to patch NtDeviceIoControlFile import in VID.DLL!"); 407 } 351 408 352 409 … … 426 483 } 427 484 if (RT_SUCCESS(rc)) 428 { 429 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 430 nemR3WinInitVidIntercepts(ahMods[1]); 431 #endif 485 rc = nemR3WinInitVidIntercepts(ahMods[1], pErrInfo); 486 if (RT_SUCCESS(rc)) 487 { 432 488 for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++) 433 489 { … … 453 509 } 454 510 if (RT_SUCCESS(rc)) 511 { 455 512 Assert(!RTErrInfoIsSet(pErrInfo)); 513 } 456 514 } 457 515 … … 675 733 676 734 /** 735 * Used to fill in g_IoCtlGetHvPartitionId. 736 */ 737 static NTSTATUS WINAPI 738 nemR3WinIoctlDetector_GetHvPartitionId(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 739 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 740 PVOID pvOutput, ULONG cbOutput) 741 { 742 AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1); 743 RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx); 744 AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5); 745 AssertLogRelMsgReturn(cbInput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8); 746 RT_NOREF(pvInput); 747 748 AssertLogRelMsgReturn(RT_VALID_PTR(pvOutput), ("pvOutput=%p\n", pvOutput), STATUS_INVALID_PARAMETER_9); 749 AssertLogRelMsgReturn(cbOutput == sizeof(HV_PARTITION_ID), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10); 750 *(HV_PARTITION_ID *)pvOutput = NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID; 751 752 g_IoCtlGetHvPartitionId.cbInput = cbInput; 753 g_IoCtlGetHvPartitionId.cbOutput = cbOutput; 754 g_IoCtlGetHvPartitionId.uFunction = uFunction; 755 756 return STATUS_SUCCESS; 757 } 758 759 760 /** 761 * Used to fill in g_IoCtlStartVirtualProcessor. 762 */ 763 static NTSTATUS WINAPI 764 nemR3WinIoctlDetector_StartVirtualProcessor(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 765 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 766 PVOID pvOutput, ULONG cbOutput) 767 { 768 AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1); 769 RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx); 770 AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5); 771 AssertLogRelMsgReturn(cbInput == sizeof(HV_VP_INDEX), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8); 772 AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9); 773 AssertLogRelMsgReturn(*(HV_VP_INDEX *)pvInput == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, 774 ("*piCpu=%u\n", *(HV_VP_INDEX *)pvInput), STATUS_INVALID_PARAMETER_9); 775 AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10); 776 RT_NOREF(pvOutput); 777 778 g_IoCtlStartVirtualProcessor.cbInput = cbInput; 779 g_IoCtlStartVirtualProcessor.cbOutput = cbOutput; 780 g_IoCtlStartVirtualProcessor.uFunction = uFunction; 781 782 return STATUS_SUCCESS; 783 } 784 785 786 /** 787 * Used to fill in g_IoCtlStartVirtualProcessor. 788 */ 789 static NTSTATUS WINAPI 790 nemR3WinIoctlDetector_StopVirtualProcessor(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 791 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 792 PVOID pvOutput, ULONG cbOutput) 793 { 794 AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1); 795 RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx); 796 AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5); 797 AssertLogRelMsgReturn(cbInput == sizeof(HV_VP_INDEX), ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_8); 798 AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9); 799 AssertLogRelMsgReturn(*(HV_VP_INDEX *)pvInput == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, 800 ("*piCpu=%u\n", *(HV_VP_INDEX *)pvInput), STATUS_INVALID_PARAMETER_9); 801 AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10); 802 RT_NOREF(pvOutput); 803 804 g_IoCtlStopVirtualProcessor.cbInput = cbInput; 805 g_IoCtlStopVirtualProcessor.cbOutput = cbOutput; 806 g_IoCtlStopVirtualProcessor.uFunction = uFunction; 807 808 return STATUS_SUCCESS; 809 } 810 811 812 /** 813 * Used to fill in g_IoCtlMessageSlotHandleAndGetNext 814 */ 815 static NTSTATUS WINAPI 816 nemR3WinIoctlDetector_MessageSlotHandleAndGetNext(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 817 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 818 PVOID pvOutput, ULONG cbOutput) 819 { 820 AssertLogRelMsgReturn(hFile == NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, ("hFile=%p\n", hFile), STATUS_INVALID_PARAMETER_1); 821 RT_NOREF(hEvt); RT_NOREF(pfnApcCallback); RT_NOREF(pvApcCtx); 822 AssertLogRelMsgReturn(RT_VALID_PTR(pIos), ("pIos=%p\n", pIos), STATUS_INVALID_PARAMETER_5); 823 824 AssertLogRelMsgReturn(cbInput == sizeof(VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT), ("cbInput=%#x\n", cbInput), 825 STATUS_INVALID_PARAMETER_8); 826 AssertLogRelMsgReturn(RT_VALID_PTR(pvInput), ("pvInput=%p\n", pvInput), STATUS_INVALID_PARAMETER_9); 827 PCVID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT pVidIn = (PCVID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT)pvInput; 828 AssertLogRelMsgReturn( pVidIn->iCpu == NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX 829 && pVidIn->fFlags == VID_MSHAGN_F_HANDLE_MESSAGE 830 && pVidIn->cMillies == NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT, 831 ("iCpu=%u fFlags=%#x cMillies=%#x\n", pVidIn->iCpu, pVidIn->fFlags, pVidIn->cMillies), 832 STATUS_INVALID_PARAMETER_9); 833 AssertLogRelMsgReturn(cbOutput == 0, ("cbInput=%#x\n", cbInput), STATUS_INVALID_PARAMETER_10); 834 RT_NOREF(pvOutput); 835 836 g_IoCtlMessageSlotHandleAndGetNext.cbInput = cbInput; 837 g_IoCtlMessageSlotHandleAndGetNext.cbOutput = cbOutput; 838 g_IoCtlMessageSlotHandleAndGetNext.uFunction = uFunction; 839 840 return STATUS_SUCCESS; 841 } 842 843 844 #ifdef LOG_ENABLED 845 /** 846 * Used to fill in what g_pIoCtlDetectForLogging points to. 847 */ 848 static NTSTATUS WINAPI nemR3WinIoctlDetector_ForLogging(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 849 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 850 PVOID pvOutput, ULONG cbOutput) 851 { 852 RT_NOREF(hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pvInput, pvOutput); 853 854 g_pIoCtlDetectForLogging->cbInput = cbInput; 855 g_pIoCtlDetectForLogging->cbOutput = cbOutput; 856 g_pIoCtlDetectForLogging->uFunction = uFunction; 857 858 return STATUS_SUCCESS; 859 } 860 #endif 861 862 863 /** 864 * Worker for nemR3NativeInit that detect I/O control function numbers for VID. 865 * 866 * We use the function numbers directly in ring-0 and to name functions when 867 * logging NtDeviceIoControlFile calls. 868 * 869 * @note We could alternatively do this by disassembling the respective 870 * functions, but hooking NtDeviceIoControlFile and making fake calls 871 * more easily provides the desired information. 872 * 873 * @returns VBox status code. 874 * @param pVM The cross context VM structure. Will set I/O 875 * control info members. 876 * @param pErrInfo Where to always return error info. 877 */ 878 static int nemR3WinInitDiscoverIoControlProperties(PVM pVM, PRTERRINFO pErrInfo) 879 { 880 /* 881 * Probe the I/O control information for select VID APIs so we can use 882 * them directly from ring-0 and better log them. 883 * 884 */ 885 decltype(NtDeviceIoControlFile) * const pfnOrg = *g_ppfnVidNtDeviceIoControlFile; 886 887 /* VidGetHvPartitionId */ 888 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_GetHvPartitionId; 889 HV_PARTITION_ID idHvPartition = HV_PARTITION_ID_INVALID; 890 BOOL fRet = g_pfnVidGetHvPartitionId(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, &idHvPartition); 891 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 892 AssertReturn(fRet && idHvPartition == NEM_WIN_IOCTL_DETECTOR_FAKE_PARTITION_ID && g_IoCtlGetHvPartitionId.uFunction != 0, 893 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 894 "Problem figuring out VidGetHvPartitionId: fRet=%u idHvPartition=%#x dwErr=%u", 895 fRet, idHvPartition, GetLastError()) ); 896 LogRel(("NEM: VidGetHvPartitionId -> fun:%#x in:%#x out:%#x\n", 897 g_IoCtlGetHvPartitionId.uFunction, g_IoCtlGetHvPartitionId.cbInput, g_IoCtlGetHvPartitionId.cbOutput)); 898 899 /* VidStartVirtualProcessor */ 900 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_StartVirtualProcessor; 901 fRet = g_pfnVidStartVirtualProcessor(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX); 902 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 903 AssertReturn(fRet && g_IoCtlStartVirtualProcessor.uFunction != 0, 904 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 905 "Problem figuring out VidStartVirtualProcessor: fRet=%u dwErr=%u", 906 fRet, GetLastError()) ); 907 LogRel(("NEM: VidStartVirtualProcessor -> fun:%#x in:%#x out:%#x\n", g_IoCtlStartVirtualProcessor.uFunction, 908 g_IoCtlStartVirtualProcessor.cbInput, g_IoCtlStartVirtualProcessor.cbOutput)); 909 910 /* VidStopVirtualProcessor */ 911 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_StopVirtualProcessor; 912 fRet = g_pfnVidStopVirtualProcessor(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX); 913 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 914 AssertReturn(fRet && g_IoCtlStopVirtualProcessor.uFunction != 0, 915 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 916 "Problem figuring out VidStopVirtualProcessor: fRet=%u dwErr=%u", 917 fRet, GetLastError()) ); 918 LogRel(("NEM: VidStopVirtualProcessor -> fun:%#x in:%#x out:%#x\n", g_IoCtlStopVirtualProcessor.uFunction, 919 g_IoCtlStopVirtualProcessor.cbInput, g_IoCtlStopVirtualProcessor.cbOutput)); 920 921 /* VidMessageSlotHandleAndGetNext */ 922 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_MessageSlotHandleAndGetNext; 923 fRet = g_pfnVidMessageSlotHandleAndGetNext(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, 924 NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, VID_MSHAGN_F_HANDLE_MESSAGE, 925 NEM_WIN_IOCTL_DETECTOR_FAKE_TIMEOUT); 926 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 927 AssertReturn(fRet && g_IoCtlMessageSlotHandleAndGetNext.uFunction != 0, 928 RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 929 "Problem figuring out VidMessageSlotHandleAndGetNext: fRet=%u dwErr=%u", 930 fRet, GetLastError()) ); 931 LogRel(("NEM: VidMessageSlotHandleAndGetNext -> fun:%#x in:%#x out:%#x\n", 932 g_IoCtlMessageSlotHandleAndGetNext.uFunction, g_IoCtlMessageSlotHandleAndGetNext.cbInput, 933 g_IoCtlMessageSlotHandleAndGetNext.cbOutput)); 934 935 #ifdef LOG_ENABLED 936 /* The following are only for logging: */ 937 union 938 { 939 VID_MAPPED_MESSAGE_SLOT MapSlot; 940 HV_REGISTER_NAME Name; 941 HV_REGISTER_VALUE Value; 942 } uBuf; 943 944 /* VidMessageSlotMap */ 945 g_pIoCtlDetectForLogging = &g_IoCtlMessageSlotMap; 946 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging; 947 fRet = g_pfnVidMessageSlotMap(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, &uBuf.MapSlot, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX); 948 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 949 Assert(fRet); 950 LogRel(("NEM: VidMessageSlotMap -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction, 951 g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput)); 952 953 /* VidGetVirtualProcessorState */ 954 uBuf.Name = HvRegisterExplicitSuspend; 955 g_pIoCtlDetectForLogging = &g_IoCtlGetVirtualProcessorState; 956 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging; 957 fRet = g_pfnVidGetVirtualProcessorState(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, 958 &uBuf.Name, 1, &uBuf.Value); 959 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 960 Assert(fRet); 961 LogRel(("NEM: VidGetVirtualProcessorState -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction, 962 g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput)); 963 964 /* VidSetVirtualProcessorState */ 965 uBuf.Name = HvRegisterExplicitSuspend; 966 g_pIoCtlDetectForLogging = &g_IoCtlSetVirtualProcessorState; 967 *g_ppfnVidNtDeviceIoControlFile = nemR3WinIoctlDetector_ForLogging; 968 fRet = g_pfnVidSetVirtualProcessorState(NEM_WIN_IOCTL_DETECTOR_FAKE_HANDLE, NEM_WIN_IOCTL_DETECTOR_FAKE_VP_INDEX, 969 &uBuf.Name, 1, &uBuf.Value); 970 *g_ppfnVidNtDeviceIoControlFile = pfnOrg; 971 Assert(fRet); 972 LogRel(("NEM: VidSetVirtualProcessorState -> fun:%#x in:%#x out:%#x\n", g_pIoCtlDetectForLogging->uFunction, 973 g_pIoCtlDetectForLogging->cbInput, g_pIoCtlDetectForLogging->cbOutput)); 974 975 g_pIoCtlDetectForLogging = NULL; 976 #endif 977 978 /* Done. */ 979 pVM->nem.s.IoCtlGetHvPartitionId = g_IoCtlGetHvPartitionId; 980 pVM->nem.s.IoCtlStartVirtualProcessor = g_IoCtlStartVirtualProcessor; 981 pVM->nem.s.IoCtlStopVirtualProcessor = g_IoCtlStopVirtualProcessor; 982 pVM->nem.s.IoCtlMessageSlotHandleAndGetNext = g_IoCtlMessageSlotHandleAndGetNext; 983 return VINF_SUCCESS; 984 } 985 986 987 /** 677 988 * Creates and sets up a Hyper-V (exo) partition. 678 989 * … … 779 1090 { 780 1091 /* 781 * Check out our ring-0 capabilities.1092 * Discover the VID I/O control function numbers we need. 782 1093 */ 783 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_NEM_INIT_VM, 0, NULL);1094 rc = nemR3WinInitDiscoverIoControlProperties(pVM, pErrInfo); 784 1095 if (RT_SUCCESS(rc)) 785 1096 { 786 1097 /* 787 * C reate and initialize a partition.1098 * Check out our ring-0 capabilities. 788 1099 */ 789 rc = nemR3WinInitCreatePartition(pVM, pErrInfo);1100 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_NEM_INIT_VM, 0, NULL); 790 1101 if (RT_SUCCESS(rc)) 791 1102 { 792 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 793 Log(("NEM: Marked active!\n")); 1103 /* 1104 * Create and initialize a partition. 1105 */ 1106 rc = nemR3WinInitCreatePartition(pVM, pErrInfo); 1107 if (RT_SUCCESS(rc)) 1108 { 1109 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 1110 Log(("NEM: Marked active!\n")); 1111 } 794 1112 } 795 1113 } … … 1799 2117 1800 2118 case VMCPUSTATE_STARTED_EXEC_NEM_WAIT: 1801 {1802 2119 if (VMCPU_CMPXCHG_STATE(pVCpu, VMCPUSTATE_STARTED_EXEC_NEM_CANCELED, VMCPUSTATE_STARTED_EXEC_NEM_WAIT)) 1803 2120 { … … 1810 2127 } 1811 2128 break; 1812 }1813 2129 1814 2130 default: … … 1822 2138 1823 2139 1824 /** 2140 /** 1825 2141 * Fills in WHV_VP_EXIT_CONTEXT from HV_X64_INTERCEPT_MESSAGE_HEADER. 1826 2142 */ … … 3007 3323 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb) 3008 3324 { 3009 Log Rel(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb));3325 Log5(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb)); 3010 3326 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 3011 3327 return VINF_SUCCESS; … … 3015 3331 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2) 3016 3332 { 3017 Log Rel(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2));3333 Log5(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2)); 3018 3334 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2); 3019 3335 return VINF_SUCCESS; … … 3023 3339 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 3024 3340 { 3025 Log Rel(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));3341 Log5(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 3026 3342 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 3027 3343 return VINF_SUCCESS; … … 3044 3360 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 3045 3361 { 3046 Log Rel(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));3362 Log5(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 3047 3363 #if 0 /* Let's not do this after all. We'll protection change notifications for each page and if not we'll map them lazily. */ 3048 3364 RTGCPHYS const cPages = cb >> X86_PAGE_SHIFT; … … 3092 3408 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 3093 3409 { 3094 Log Rel(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags));3410 Log5(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 3095 3411 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 3096 3412 return VINF_SUCCESS; … … 3178 3494 void nemR3NativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb) 3179 3495 { 3180 Log Rel(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind));3496 Log5(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind)); 3181 3497 NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); 3182 3498 } … … 3186 3502 int fRestoreAsRAM, bool fRestoreAsRAM2) 3187 3503 { 3188 Log Rel(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n",3189 3504 Log5(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n", 3505 GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2)); 3190 3506 NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); NOREF(fRestoreAsRAM); NOREF(fRestoreAsRAM2); 3191 3507 } … … 3195 3511 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM) 3196 3512 { 3197 Log Rel(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n",3198 3513 Log5(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n", 3514 GCPhysOld, cb, GCPhysNew, enmKind, fRestoreAsRAM)); 3199 3515 NOREF(pVM); NOREF(enmKind); NOREF(GCPhysOld); NOREF(GCPhysNew); NOREF(cb); NOREF(fRestoreAsRAM); 3200 3516 } … … 3480 3796 PGMPAGETYPE enmType, uint8_t *pu2State) 3481 3797 { 3482 Log Rel(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",3483 3798 Log5(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 3799 GCPhys, HCPhys, fPageProt, enmType, *pu2State)); 3484 3800 RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType); 3485 3801 … … 3515 3831 PGMPAGETYPE enmType, uint8_t *pu2State) 3516 3832 { 3517 Log Rel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",3518 3833 Log5(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 3834 GCPhys, HCPhys, fPageProt, enmType, *pu2State)); 3519 3835 RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType); 3520 3836 … … 3546 3862 uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State) 3547 3863 { 3548 Log Rel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n",3549 3864 Log5(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 3865 GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State)); 3550 3866 RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType); 3551 3867 -
trunk/src/VBox/VMM/include/NEMInternal.h
r71129 r71131 49 49 # error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS" 50 50 # endif 51 #endif 51 52 /** 53 * Windows VID I/O control information. 54 */ 55 typedef struct NEMWINIOCTL 56 { 57 /** The I/O control function number. */ 58 uint32_t uFunction; 59 uint32_t cbInput; 60 uint32_t cbOutput; 61 } NEMWINIOCTL; 62 63 #endif 64 52 65 53 66 /** … … 104 117 /** Number of currently mapped pages. */ 105 118 uint32_t volatile cMappedPages; 106 #endif 107 119 120 /** Info about the VidGetHvPartitionId I/O control interface. */ 121 NEMWINIOCTL IoCtlGetHvPartitionId; 122 /** Info about the VidStartVirtualProcessor I/O control interface. */ 123 NEMWINIOCTL IoCtlStartVirtualProcessor; 124 /** Info about the VidStopVirtualProcessor I/O control interface. */ 125 NEMWINIOCTL IoCtlStopVirtualProcessor; 126 /** Info about the VidStopVirtualProcessor I/O control interface. */ 127 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext; 128 129 #endif /* RT_OS_WINDOWS */ 108 130 } NEM; 109 131 /** Pointer to NEM VM instance data. */ … … 115 137 #define NEM_MAGIC_DEAD UINT32_C(0xdead1111) 116 138 117 #if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API)118 /** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state.119 * @{ */120 /** The CPU has not been started. */121 # define NEM_WIN_MSG_STATE_STOPPED UINT8_C(0x00)122 /** The CPU has been started, no messages are pending. */123 # define NEM_WIN_MSG_STATE_STARTED UINT8_C(0x01)124 /** Message is pending and needs to be ACKed. */125 # define NEM_WIN_MSG_STATE_PENDING_MSG UINT8_C(0x02)126 /** Both a message and execution stopping is pending. We need to ACK the127 * current message and get the stop message, then ACK the stop message before128 * the CPU can be started again. */129 # define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03)130 /** @} */131 #endif132 139 133 140 /** … … 177 184 178 185 186 #if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_OUR_OWN_RUN_API) 187 /** @name NEM_WIN_MSG_STATE_XXX - Windows message handling state. 188 * @{ */ 189 /** The CPU has not been started. */ 190 # define NEM_WIN_MSG_STATE_STOPPED UINT8_C(0x00) 191 /** The CPU has been started, no messages are pending. */ 192 # define NEM_WIN_MSG_STATE_STARTED UINT8_C(0x01) 193 /** Message is pending and needs to be ACKed. */ 194 # define NEM_WIN_MSG_STATE_PENDING_MSG UINT8_C(0x02) 195 /** Both a message and execution stopping is pending. We need to ACK the 196 * current message and get the stop message, then ACK the stop message before 197 * the CPU can be started again. */ 198 # define NEM_WIN_MSG_STATE_PENDING_STOP_AND_MSG UINT8_C(0x03) 199 /** @} */ 200 #endif 201 202 203 179 204 #ifdef IN_RING0 180 205
Note:
See TracChangeset
for help on using the changeset viewer.