Changeset 70954 in vbox
- Timestamp:
- Feb 10, 2018 8:10:44 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120797
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/Makefile.kmk
r70942 r70954 243 243 VMMAll/MMAllHyper.cpp \ 244 244 VMMAll/MMAllPagePool.cpp \ 245 VMMAll/NEMAll.cpp \ 245 246 VMMAll/PDMAll.cpp \ 246 247 VMMAll/PDMAllCritSect.cpp \ … … 786 787 VMMAll/MMAllHyper.cpp \ 787 788 VMMAll/MMAllPagePool.cpp \ 789 VMMAll/NEMAll.cpp \ 788 790 VMMAll/PDMAll.cpp \ 789 791 VMMAll/PDMAllCritSect.cpp \ -
trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp
r69111 r70954 26 26 #include <VBox/vmm/mm.h> 27 27 #include <VBox/vmm/em.h> 28 #include <VBox/vmm/nem.h> 28 29 #include <VBox/vmm/stam.h> 29 30 #ifdef VBOX_WITH_REM … … 31 32 #endif 32 33 #include <VBox/vmm/dbgf.h> 33 #ifdef VBOX_WITH_REM34 # include <VBox/vmm/rem.h>35 #endif36 34 #include "PGMInternal.h" 37 35 #include <VBox/vmm/vm.h> … … 51 49 *********************************************************************************************************************************/ 52 50 static int pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(PVM pVM, PPGMPHYSHANDLER pCur, PPGMRAMRANGE pRam); 53 static void pgmHandlerPhysicalDeregisterNotifyREM (PVM pVM, PPGMPHYSHANDLER pCur);51 static void pgmHandlerPhysicalDeregisterNotifyREMAndNEM(PVM pVM, PPGMPHYSHANDLER pCur, int fRestoreRAM); 54 52 static void pgmHandlerPhysicalResetRamFlags(PVM pVM, PPGMPHYSHANDLER pCur); 55 53 … … 285 283 if (rc == VINF_PGM_SYNC_CR3) 286 284 rc = VINF_PGM_GCPHYS_ALIASED; 285 286 #if defined(IN_RING3) || defined(IN_RING0) 287 NEMHCNotifyHandlerPhysicalRegister(pVM, pType->enmKind, GCPhys, GCPhysLast - GCPhys + 1); 288 #endif 287 289 pgmUnlock(pVM); 288 290 … … 421 423 * @param pVM The cross context VM structure. 422 424 * @param pPhysHandler The handler to deregister (but not free). 423 */ 424 int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler) 425 { 426 LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s\n", 427 pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc))); 425 * @param fRestoreAsRAM How this will likely be restored, if we know (true, 426 * false, or if we don't know -1). 427 */ 428 int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, int fRestoreAsRAM) 429 { 430 LogFlow(("pgmHandlerPhysicalExDeregister: Removing Range %RGp-%RGp %s fRestoreAsRAM=%d\n", 431 pPhysHandler->Core.Key, pPhysHandler->Core.KeyLast, R3STRING(pPhysHandler->pszDesc), fRestoreAsRAM)); 428 432 AssertReturn(pPhysHandler->Core.Key != NIL_RTGCPHYS, VERR_PGM_HANDLER_NOT_FOUND); 429 433 … … 441 445 */ 442 446 pgmHandlerPhysicalResetRamFlags(pVM, pPhysHandler); 443 pgmHandlerPhysicalDeregisterNotifyREM (pVM, pPhysHandler);447 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pPhysHandler, fRestoreAsRAM); 444 448 pVM->pgm.s.pLastPhysHandlerR0 = 0; 445 449 pVM->pgm.s.pLastPhysHandlerR3 = 0; … … 520 524 */ 521 525 pgmHandlerPhysicalResetRamFlags(pVM, pRemoved); 522 pgmHandlerPhysicalDeregisterNotifyREM (pVM, pRemoved);526 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pRemoved, -1); 523 527 pVM->pgm.s.pLastPhysHandlerR0 = 0; 524 528 pVM->pgm.s.pLastPhysHandlerR3 = 0; … … 542 546 * Shared code with modify. 543 547 */ 544 static void pgmHandlerPhysicalDeregisterNotifyREM (PVM pVM, PPGMPHYSHANDLER pCur)548 static void pgmHandlerPhysicalDeregisterNotifyREMAndNEM(PVM pVM, PPGMPHYSHANDLER pCur, int fRestoreAsRAM) 545 549 { 546 550 PPGMPHYSHANDLERTYPEINT pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur); … … 555 559 * included in the REM notification or not. 556 560 */ 557 if ( (pCur->Core.Key& PAGE_OFFSET_MASK)558 || 561 if ( (pCur->Core.Key & PAGE_OFFSET_MASK) 562 || ((pCur->Core.KeyLast + 1) & PAGE_OFFSET_MASK)) 559 563 { 560 564 Assert(pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO); … … 595 599 } 596 600 601 /* 602 * Tell REM and NEM. 603 */ 597 604 #ifdef VBOX_WITH_REM 598 /* 599 * Tell REM. 600 */ 601 const bool fRestoreAsRAM = pCurType->pfnHandlerR3 602 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */ 605 const bool fRestoreAsRAM2 = pCurType->pfnHandlerR3 606 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */ 603 607 # ifndef IN_RING3 604 608 REMNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1, 605 !!pCurType->pfnHandlerR3, fRestoreAsRAM );609 !!pCurType->pfnHandlerR3, fRestoreAsRAM2); 606 610 # else 607 611 REMR3NotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1, 608 !!pCurType->pfnHandlerR3, fRestoreAsRAM );612 !!pCurType->pfnHandlerR3, fRestoreAsRAM2); 609 613 # endif 614 #endif 615 #if defined(IN_RING3) || defined(IN_RING0) 616 NEMHCNotifyHandlerPhysicalDeregister(pVM, pCurType->enmKind, GCPhysStart, GCPhysLast - GCPhysStart + 1, 617 fRestoreAsRAM, fRestoreAsRAM2); 610 618 #else 611 RT_NOREF_PV( pCurType);619 RT_NOREF_PV(fRestoreAsRAM); /** @todo this needs more work for REM! */ 612 620 #endif 613 621 } … … 816 824 */ 817 825 pgmHandlerPhysicalResetRamFlags(pVM, pCur); 818 #if def VBOX_WITH_REM819 PPGMPHYSHANDLERTYPEINT pCurType= PGMPHYSHANDLER_GET_TYPE(pVM, pCur);820 const bool fRestoreAsRAM = pCurType->pfnHandlerR3821 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; /** @todo this isn't entirely correct. */826 #if defined(VBOX_WITH_REM) || defined(IN_RING3) || defined(IN_RING0) 827 PPGMPHYSHANDLERTYPEINT const pCurType = PGMPHYSHANDLER_GET_TYPE(pVM, pCur); 828 bool const fRestoreAsRAM = pCurType->pfnHandlerR3 /** @todo this isn't entirely correct. */ 829 && pCurType->enmKind != PGMPHYSHANDLERKIND_MMIO; 822 830 #endif 823 831 … … 842 850 if (RTAvlroGCPhysInsert(&pVM->pgm.s.CTX_SUFF(pTrees)->PhysHandlers, &pCur->Core)) 843 851 { 852 #if defined(VBOX_WITH_REM) || defined(IN_RING3) || defined(IN_RING0) 853 RTGCPHYS const cb = GCPhysLast - GCPhys + 1; 854 PGMPHYSHANDLERKIND const enmKind = pCurType->enmKind; 855 #endif 844 856 #ifdef VBOX_WITH_REM 845 RTGCPHYS cb = GCPhysLast - GCPhys + 1; 846 PGMPHYSHANDLERKIND enmKind = pCurType->enmKind; 847 bool fHasHCHandler = !!pCurType->pfnHandlerR3; 857 bool const fHasHCHandler = !!pCurType->pfnHandlerR3; 848 858 #endif 849 859 … … 852 862 */ 853 863 rc = pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs(pVM, pCur, pRam); 864 865 #if defined(IN_RING3) || defined(IN_RING0) 866 NEMHCNotifyHandlerPhysicalModify(pVM, enmKind, GCPhysCurrent, GCPhys, cb, fRestoreAsRAM); 867 #endif 868 854 869 pgmUnlock(pVM); 855 870 … … 888 903 * We've only gotta notify REM and free the memory. 889 904 */ 890 pgmHandlerPhysicalDeregisterNotifyREM (pVM, pCur);905 pgmHandlerPhysicalDeregisterNotifyREMAndNEM(pVM, pCur, -1); 891 906 pVM->pgm.s.pLastPhysHandlerR0 = 0; 892 907 pVM->pgm.s.pLastPhysHandlerR3 = 0; -
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r70948 r70954 235 235 } 236 236 237 238 VMMR3_INT_DECL(int) NEMR3NotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb) 239 { 240 int rc = VINF_SUCCESS; 241 #ifdef VBOX_WITH_NATIVE_NEM 242 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 243 rc = nemR3NativeNotifyPhysRamRegister(pVM, GCPhys, cb); 244 #else 245 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 246 #endif 247 return rc; 248 } 249 250 251 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 252 { 253 int rc = VINF_SUCCESS; 254 #ifdef VBOX_WITH_NATIVE_NEM 255 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 256 rc = nemR3NativeNotifyPhysMmioExMap(pVM, GCPhys, cb, fFlags); 257 #else 258 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 259 #endif 260 return rc; 261 } 262 263 264 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 265 { 266 int rc = VINF_SUCCESS; 267 #ifdef VBOX_WITH_NATIVE_NEM 268 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 269 rc = nemR3NativeNotifyPhysMmioExUnmap(pVM, GCPhys, cb, fFlags); 270 #else 271 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 272 #endif 273 return rc; 274 } 275 276 277 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags) 278 { 279 int rc = VINF_SUCCESS; 280 #ifdef VBOX_WITH_NATIVE_NEM 281 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 282 rc = nemR3NativeNotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fFlags); 283 #else 284 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 285 #endif 286 return rc; 287 } 288 289 290 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags) 291 { 292 int rc = VINF_SUCCESS; 293 #ifdef VBOX_WITH_NATIVE_NEM 294 if (pVM->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 295 rc = nemR3NativeNotifyPhysRomRegisterLate(pVM, GCPhys, cb, fFlags); 296 #else 297 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 298 #endif 299 return rc; 300 } 301 302 303 VMMR3_INT_DECL(void) NEMR3NotifySetA20(PVMCPU pVCpu, bool fEnabled) 304 { 305 #ifdef VBOX_WITH_NATIVE_NEM 306 if (pVCpu->pVMR3->bMainExecutionEngine == VM_EXEC_ENGINE_NATIVE_API) 307 nemR3NativeNotifySetA20(pVCpu, fEnabled); 308 #else 309 NOREF(pVCpu); NOREF(fEnabled); 310 #endif 311 } 312 -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r70948 r70954 122 122 #endif 123 123 124 125 126 /** 127 * Worker for nemR3NativeInit that probes and load the native API. 128 * 129 * @returns VBox status code. 130 * @param fForced Whether the HMForced flag is set and we should 131 * fail if we cannot initialize. 132 * @param pErrInfo Where to always return error info. 133 */ 134 static int nemR3WinInitProbeAndLoad(bool fForced, PRTERRINFO pErrInfo) 135 { 136 /* 137 * Check that the DLL files we need are present, but without loading them. 138 * We'd like to avoid loading them unnecessarily. 139 */ 140 WCHAR wszPath[MAX_PATH + 64]; 141 UINT cwcPath = GetSystemDirectoryW(wszPath, MAX_PATH); 142 if (cwcPath >= MAX_PATH || cwcPath < 2) 143 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "GetSystemDirectoryW failed (%#x / %u)", cwcPath, GetLastError()); 144 145 if (wszPath[cwcPath - 1] != '\\' || wszPath[cwcPath - 1] != '/') 146 wszPath[cwcPath++] = '\\'; 147 RTUtf16CopyAscii(&wszPath[cwcPath], RT_ELEMENTS(wszPath) - cwcPath, "WinHvPlatform.dll"); 148 if (GetFileAttributesW(wszPath) == INVALID_FILE_ATTRIBUTES) 149 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "The native API dll was not found (%ls)", wszPath); 150 151 /* 152 * Check that we're in a VM and that the hypervisor identifies itself as Hyper-V. 153 */ 154 if (!ASMHasCpuId()) 155 return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID support"); 156 if (!ASMIsValidStdRange(ASMCpuId_EAX(0))) 157 return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID leaf #1"); 158 if (!(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_HVP)) 159 return RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Not in a hypervisor partition (HVP=0)"); 160 161 uint32_t cMaxHyperLeaf = 0; 162 uint32_t uEbx = 0; 163 uint32_t uEcx = 0; 164 uint32_t uEdx = 0; 165 ASMCpuIdExSlow(0x40000000, 0, 0, 0, &cMaxHyperLeaf, &uEbx, &uEcx, &uEdx); 166 if (!ASMIsValidHypervisorRange(cMaxHyperLeaf)) 167 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Invalid hypervisor CPUID range (%#x %#x %#x %#x)", 168 cMaxHyperLeaf, uEbx, uEcx, uEdx); 169 if ( uEbx != UINT32_C(0x7263694d) /* Micr */ 170 || uEcx != UINT32_C(0x666f736f) /* osof */ 171 || uEdx != UINT32_C(0x76482074) /* t Hv */) 172 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, 173 "Not Hyper-V CPUID signature: %#x %#x %#x (expected %#x %#x %#x)", 174 uEbx, uEcx, uEdx, UINT32_C(0x7263694d), UINT32_C(0x666f736f), UINT32_C(0x76482074)); 175 if (cMaxHyperLeaf < UINT32_C(0x40000005)) 176 return RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Too narrow hypervisor CPUID range (%#x)", cMaxHyperLeaf); 177 178 /** @todo would be great if we could recognize a root partition from the 179 * CPUID info, but I currently don't dare do that. */ 180 181 /* 182 * Now try load the DLLs and resolve the APIs. 183 */ 184 static const char * const s_apszDllNames[2] = { "WinHvPlatform.dll", "vid.dll" }; 185 RTLDRMOD ahMods[2] = { NIL_RTLDRMOD, NIL_RTLDRMOD }; 186 int rc = VINF_SUCCESS; 187 for (unsigned i = 0; i < RT_ELEMENTS(s_apszDllNames); i++) 188 { 189 int rc2 = RTLdrLoadSystem(s_apszDllNames[i], true /*fNoUnload*/, &ahMods[i]); 190 if (RT_FAILURE(rc2)) 191 { 192 if (!RTErrInfoIsSet(pErrInfo)) 193 RTErrInfoSetF(pErrInfo, rc2, "Failed to load API DLL: %s: %Rrc", s_apszDllNames[i], rc2); 194 else 195 RTErrInfoAddF(pErrInfo, rc2, "; %s: %Rrc", s_apszDllNames[i], rc2); 196 ahMods[i] = NIL_RTLDRMOD; 197 rc = VERR_NEM_INIT_FAILED; 198 } 199 } 200 if (RT_SUCCESS(rc)) 201 { 202 for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++) 203 { 204 int rc2 = RTLdrGetSymbol(ahMods[g_aImports[i].idxDll], g_aImports[i].pszName, (void **)g_aImports[i].ppfn); 205 if (RT_FAILURE(rc2)) 206 { 207 *g_aImports[i].ppfn = NULL; 208 209 LogRel(("NEM: %s: Failed to import %s!%s: %Rrc", 210 g_aImports[i].fOptional ? "info" : fForced ? "fatal" : "error", 211 s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName, rc2)); 212 if (!g_aImports[i].fOptional) 213 { 214 if (RTErrInfoIsSet(pErrInfo)) 215 RTErrInfoAddF(pErrInfo, rc2, ", %s!%s", 216 s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName); 217 else 218 rc = RTErrInfoSetF(pErrInfo, rc2, "Failed to import: %s!%s", 219 s_apszDllNames[g_aImports[i].idxDll], g_aImports[i].pszName); 220 Assert(RT_FAILURE(rc)); 221 } 222 } 223 } 224 if (RT_SUCCESS(rc)) 225 Assert(!RTErrInfoIsSet(pErrInfo)); 226 } 227 228 for (unsigned i = 0; i < RT_ELEMENTS(ahMods); i++) 229 RTLdrClose(ahMods[i]); 230 return rc; 231 } 124 232 125 233 … … 413 521 /* 414 522 * Error state. 415 * 416 * The error message will be non-empty on failure, 'rc' may or may not 417 * be set. Early API detection failures will not set 'rc', so we'll sort 418 * that out at the other end of the function. 523 * The error message will be non-empty on failure and 'rc' will be set too. 419 524 */ 420 525 RTERRINFOSTATIC ErrInfo; 421 int rc = VINF_SUCCESS;422 526 PRTERRINFO pErrInfo = RTErrInfoInitStatic(&ErrInfo); 423 424 /* 425 * Check that the DLL files we need are present, but without loading them. 426 * We'd like to avoid loading them unnecessarily. 427 */ 428 WCHAR wszPath[MAX_PATH + 64]; 429 UINT cwcPath = GetSystemDirectoryW(wszPath, MAX_PATH); 430 if (cwcPath >= MAX_PATH || cwcPath < 2) 431 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "GetSystemDirectoryW failed (%#x / %u)", cwcPath, GetLastError()); 432 else 433 { 434 if (wszPath[cwcPath - 1] != '\\' || wszPath[cwcPath - 1] != '/') 435 wszPath[cwcPath++] = '\\'; 436 RTUtf16CopyAscii(&wszPath[cwcPath], RT_ELEMENTS(wszPath) - cwcPath, "WinHvPlatform.dll"); 437 if (GetFileAttributesW(wszPath) == INVALID_FILE_ATTRIBUTES) 438 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "The native API dll was not found (%ls)", wszPath); 439 else 527 int rc = nemR3WinInitProbeAndLoad(fForced, pErrInfo); 528 if (RT_SUCCESS(rc)) 529 { 530 /* 531 * Check the capabilties of the hypervisor, starting with whether it's present. 532 */ 533 rc = nemR3WinInitCheckCapabilities(pVM, pErrInfo); 534 if (RT_SUCCESS(rc)) 440 535 { 441 536 /* 442 * C heck that we're in a VM and that the hypervisor identifies itself as Hyper-V.537 * Create and initialize a partition. 443 538 */ 444 if (!ASMHasCpuId()) 445 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID support"); 446 else if (!ASMIsValidStdRange(ASMCpuId_EAX(0))) 447 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "No CPUID leaf #1"); 448 else if (!(ASMCpuId_ECX(1) & X86_CPUID_FEATURE_ECX_HVP)) 449 rc = RTErrInfoSet(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Not in a hypervisor partition (HVP=0)"); 450 else 539 rc = nemR3WinInitCreatePartition(pVM, pErrInfo); 540 if (RT_SUCCESS(rc)) 451 541 { 452 uint32_t cMaxHyperLeaf = 0; 453 uint32_t uEbx = 0; 454 uint32_t uEcx = 0; 455 uint32_t uEdx = 0; 456 ASMCpuIdExSlow(0x40000000, 0, 0, 0, &cMaxHyperLeaf, &uEbx, &uEcx, &uEdx); 457 if (!ASMIsValidHypervisorRange(cMaxHyperLeaf)) 458 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Invalid hypervisor CPUID range (%#x %#x %#x %#x)", 459 cMaxHyperLeaf, uEbx, uEcx, uEdx); 460 else if ( uEbx != UINT32_C(0x7263694d) /* Micr */ 461 || uEcx != UINT32_C(0x666f736f) /* osof */ 462 || uEdx != UINT32_C(0x76482074) /* t Hv */) 463 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, 464 "Not Hyper-V CPUID signature: %#x %#x %#x (expected %#x %#x %#x)", 465 uEbx, uEcx, uEdx, UINT32_C(0x7263694d), UINT32_C(0x666f736f), UINT32_C(0x76482074)); 466 else if (cMaxHyperLeaf < UINT32_C(0x40000005)) 467 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_NOT_AVAILABLE, "Too narrow hypervisor CPUID range (%#x)", cMaxHyperLeaf); 468 else 469 { 470 /** @todo would be great if we could recognize a root partition from the 471 * CPUID info, but I currently don't dare do that. */ 472 473 /* 474 * Now try load the DLLs and resolve the APIs. 475 */ 476 static const char * const s_pszDllPrefixes[] = { "WinHvPlatform.dll!", "vid.dll!" }; 477 RTLDRMOD ahMods[2] = { NIL_RTLDRMOD, NIL_RTLDRMOD }; 478 rc = RTLdrLoadSystem("vid.dll", true /*fNoUnload*/, &ahMods[1]); 479 if (RT_SUCCESS(rc)) 480 { 481 rc = RTLdrLoadSystem("WinHvPlatform.dll", true /*fNoUnload*/, &ahMods[0]); 482 if (RT_SUCCESS(rc)) 483 { 484 for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++) 485 { 486 int rc2 = RTLdrGetSymbol(ahMods[g_aImports[i].idxDll], g_aImports[i].pszName, 487 (void **)g_aImports[i].ppfn); 488 if (RT_FAILURE(rc2)) 489 { 490 *g_aImports[i].ppfn = NULL; 491 492 LogRel(("NEM: %s: Failed to import %s%s: %Rrc", 493 g_aImports[i].fOptional ? "info" : fForced ? "fatal" : "error", 494 s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName, rc2)); 495 if (!g_aImports[i].fOptional) 496 { 497 if (RTErrInfoIsSet(pErrInfo)) 498 RTErrInfoAddF(pErrInfo, rc2, ", %s%s", 499 s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName); 500 else 501 rc = RTErrInfoSetF(pErrInfo, rc2, "Failed to import: %s%s", 502 s_pszDllPrefixes[g_aImports[i].idxDll], g_aImports[i].pszName); 503 Assert(RT_FAILURE(rc)); 504 } 505 } 506 } 507 if (RT_SUCCESS(rc)) 508 { 509 Assert(!RTErrInfoIsSet(pErrInfo)); 510 511 /* 512 * Check the capabilties of the hypervisor, starting with whether it's present. 513 */ 514 rc = nemR3WinInitCheckCapabilities(pVM, pErrInfo); 515 if (RT_SUCCESS(rc)) 516 { 517 /* 518 * Create and initialize a partition. 519 */ 520 rc = nemR3WinInitCreatePartition(pVM, pErrInfo); 521 if (RT_SUCCESS(rc)) 522 { 523 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 524 Log(("NEM: Marked active!\n")); 525 } 526 } 527 } 528 RTLdrClose(ahMods[0]); 529 } 530 else 531 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 532 "Failed to load API DLL 'WinHvPlatform.dll': %Rrc", rc); 533 RTLdrClose(ahMods[1]); 534 } 535 else 536 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "Failed to load API DLL 'vid.dll': %Rrc", rc); 537 } 542 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 543 Log(("NEM: Marked active!\n")); 538 544 } 539 545 } … … 706 712 } 707 713 714 715 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb) 716 { 717 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 718 return VINF_SUCCESS; 719 } 720 721 722 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 723 { 724 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 725 return VINF_SUCCESS; 726 } 727 728 729 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 730 { 731 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 732 return VINF_SUCCESS; 733 } 734 735 736 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags) 737 { 738 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 739 return VINF_SUCCESS; 740 } 741 742 743 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags) 744 { 745 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 746 return VINF_SUCCESS; 747 } 748 749 750 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled) 751 { 752 NOREF(pVCpu); NOREF(fEnabled); 753 } 754 -
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r70951 r70954 25 25 #include <VBox/vmm/iom.h> 26 26 #include <VBox/vmm/mm.h> 27 #include <VBox/vmm/nem.h> 27 28 #include <VBox/vmm/stam.h> 28 29 #ifdef VBOX_WITH_REM … … 1746 1747 } 1747 1748 pgmPhysInvalidatePageMapTLB(pVM); 1749 1750 /* 1751 * Notify NEM while holding the lock (experimental) and REM without (like always). 1752 */ 1753 rc = NEMR3NotifyPhysRamRegister(pVM, GCPhys, cb); 1748 1754 pgmUnlock(pVM); 1749 1750 1755 #ifdef VBOX_WITH_REM 1751 /*1752 * Notify REM.1753 */1754 1756 REMR3NotifyPhysRamRegister(pVM, GCPhys, cb, REM_NOTIFY_PHYS_RAM_FLAGS_RAM); 1755 1757 #endif 1756 1757 return VINF_SUCCESS; 1758 return rc; 1758 1759 } 1759 1760 … … 3466 3467 { 3467 3468 pCurMmio->fFlags &= ~PGMREGMMIORANGE_F_MAPPED; 3468 pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3 );3469 pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3, fRamExists); 3469 3470 } 3470 3471 … … 3510 3511 pgmPhysInvalidatePageMapTLB(pVM); 3511 3512 3513 /* 3514 * Notify NEM while holding the lock (experimental) and REM without (like always). 3515 */ 3516 uint32_t const fNemNotify = (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) 3517 | (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0); 3518 int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify); 3512 3519 pgmUnlock(pVM); 3513 3514 3520 #ifdef VBOX_WITH_REM 3515 /* 3516 * Inform REM without holding the PGM lock. 3517 */ 3518 if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)) 3521 if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)) /** @todo this doesn't look right. */ 3519 3522 REMR3NotifyPhysRamRegister(pVM, GCPhys, cbRange, REM_NOTIFY_PHYS_RAM_FLAGS_MMIO2); 3520 3523 #endif 3521 return VINF_SUCCESS;3524 return rc; 3522 3525 } 3523 3526 … … 3567 3570 int rc = pgmLock(pVM); 3568 3571 AssertRCReturn(rc, rc); 3569 AssertReturnStmt(pFirstMmio->fFlags & PGMREGMMIORANGE_F_MAPPED, pgmUnlock(pVM), VERR_WRONG_ORDER); 3572 uint16_t const fOldFlags = pFirstMmio->fFlags; 3573 AssertReturnStmt(fOldFlags & PGMREGMMIORANGE_F_MAPPED, pgmUnlock(pVM), VERR_WRONG_ORDER); 3570 3574 3571 3575 /* 3572 3576 * If plain MMIO, we must deregister the handlers first. 3573 3577 */ 3574 if (!( pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2))3578 if (!(fOldFlags & PGMREGMMIORANGE_F_MMIO2)) 3575 3579 { 3576 3580 PPGMREGMMIORANGE pCurMmio = pFirstMmio; 3577 rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3 );3581 rc = pgmHandlerPhysicalExDeregister(pVM, pFirstMmio->pPhysHandlerR3, RT_BOOL(fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING)); 3578 3582 AssertRCReturnStmt(rc, pgmUnlock(pVM), rc); 3579 3583 while (!(pCurMmio->fFlags & PGMREGMMIORANGE_F_LAST_CHUNK)) 3580 3584 { 3581 3585 pCurMmio = pCurMmio->pNextR3; 3582 rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3 );3586 rc = pgmHandlerPhysicalExDeregister(pVM, pCurMmio->pPhysHandlerR3, RT_BOOL(fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING)); 3583 3587 AssertRCReturnStmt(rc, pgmUnlock(pVM), VERR_PGM_PHYS_MMIO_EX_IPE); 3584 3588 } … … 3590 3594 * Unmap it. 3591 3595 */ 3592 #ifdef VBOX_WITH_REM 3593 RTGCPHYS GCPhysRangeREM; 3594 bool fInformREM; 3595 #endif 3596 if (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING) 3596 RTGCPHYS const GCPhysRangeNotify = pFirstMmio->RamRange.GCPhys; 3597 if (fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING) 3597 3598 { 3598 3599 /* … … 3604 3605 */ 3605 3606 /* Only one chunk allowed when overlapping! */ 3606 Assert( pFirstMmio->fFlags & PGMREGMMIORANGE_F_LAST_CHUNK);3607 Assert(fOldFlags & PGMREGMMIORANGE_F_LAST_CHUNK); 3607 3608 3608 3609 /* Restore the RAM pages we've replaced. */ … … 3612 3613 3613 3614 uint32_t cPagesLeft = pFirstMmio->RamRange.cb >> PAGE_SHIFT; 3614 if ( pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)3615 if (fOldFlags & PGMREGMMIORANGE_F_MMIO2) 3615 3616 pVM->pgm.s.cZeroPages += cPagesLeft; 3616 3617 … … 3624 3625 /* Flush physical page map TLB. */ 3625 3626 pgmPhysInvalidatePageMapTLB(pVM); 3626 #ifdef VBOX_WITH_REM3627 GCPhysRangeREM = NIL_RTGCPHYS; /* shuts up gcc */3628 fInformREM = false;3629 #endif3630 3627 3631 3628 /* Update range state. */ … … 3639 3636 * Unlink the chunks related to the MMIO/MMIO2 region. 3640 3637 */ 3641 #ifdef VBOX_WITH_REM3642 GCPhysRangeREM = pFirstMmio->RamRange.GCPhys;3643 fInformREM = RT_BOOL(pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2);3644 #endif3645 3638 for (PPGMREGMMIORANGE pCurMmio = pFirstMmio; ; pCurMmio = pCurMmio->pNextR3) 3646 3639 { … … 3665 3658 pgmPhysInvalidRamRangeTlbs(pVM); 3666 3659 3660 /* 3661 * Notify NEM while holding the lock (experimental) and REM without (like always). 3662 */ 3663 uint32_t const fNemFlags = (fOldFlags & PGMREGMMIORANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) 3664 | (fOldFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0); 3665 rc = NEMR3NotifyPhysMmioExUnmap(pVM, GCPhysRangeNotify, cbRange, fNemFlags); 3667 3666 pgmUnlock(pVM); 3668 3669 3667 #ifdef VBOX_WITH_REM 3670 /* 3671 * Inform REM without holding the PGM lock. 3672 */ 3673 if (fInformREM) 3674 REMR3NotifyPhysRamDeregister(pVM, GCPhysRangeREM, cbRange); 3668 if ((fOldFlags & (PGMREGMMIORANGE_F_OVERLAPPING | PGMREGMMIORANGE_F_MMIO2)) == PGMREGMMIORANGE_F_MMIO2) 3669 REMR3NotifyPhysRamDeregister(pVM, GCPhysRangeNotify, cbRange); 3675 3670 #endif 3676 3677 return VINF_SUCCESS; 3671 return rc; 3678 3672 } 3679 3673 … … 4091 4085 4092 4086 4087 /* Notify NEM before we register handlers. */ 4088 uint32_t const fNemNotify = (fRamExists ? NEM_NOTIFY_PHYS_ROM_F_REPLACE : 0) 4089 | (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED ? NEM_NOTIFY_PHYS_ROM_F_SHADOW : 0); 4090 rc = NEMR3NotifyPhysRomRegisterEarly(pVM, GCPhys, cb, fNemNotify); 4091 4093 4092 /* 4094 4093 * !HACK ALERT! REM + (Shadowed) ROM ==> mess. … … 4105 4104 REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, true /* fShadowed */); 4106 4105 #endif 4107 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4108 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), 4109 pszDesc); 4106 if (RT_SUCCESS(rc)) 4107 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4108 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), 4109 pszDesc); 4110 4110 } 4111 4111 else 4112 4112 { 4113 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4114 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), 4115 pszDesc); 4113 if (RT_SUCCESS(rc)) 4114 rc = PGMHandlerPhysicalRegister(pVM, GCPhys, GCPhysLast, pVM->pgm.s.hRomPhysHandlerType, 4115 pRomNew, MMHyperCCToR0(pVM, pRomNew), MMHyperCCToRC(pVM, pRomNew), 4116 pszDesc); 4116 4117 #ifdef VBOX_WITH_REM 4117 4118 REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, false /* fShadowed */); … … 4203 4204 pgmPhysInvalidatePageMapTLB(pVM); 4204 4205 GMMR3AllocatePagesCleanup(pReq); 4205 return VINF_SUCCESS; 4206 4207 /* Notify NEM again. */ 4208 return NEMR3NotifyPhysRomRegisterLate(pVM, GCPhys, cb, fNemNotify); 4206 4209 } 4207 4210 … … 4535 4538 REMR3A20Set(pVCpu->pVMR3, pVCpu, fEnable); 4536 4539 #endif 4540 NEMR3NotifySetA20(pVCpu, fEnable); 4537 4541 #ifdef PGM_WITH_A20 4538 4542 pVCpu->pgm.s.fSyncFlags |= PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL; -
trunk/src/VBox/VMM/include/NEMInternal.h
r70945 r70954 115 115 void nemR3NativeReset(PVM pVM); 116 116 void nemR3NativeResetCpu(PVMCPU pVCpu); 117 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb); 118 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags); 119 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags); 120 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags); 121 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags); 122 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled); 117 123 #endif 118 124 -
trunk/src/VBox/VMM/include/PGMInternal.h
r69474 r70954 4195 4195 int pgmHandlerPhysicalExDup(PVM pVM, PPGMPHYSHANDLER pPhysHandlerSrc, PPGMPHYSHANDLER *ppPhysHandler); 4196 4196 int pgmHandlerPhysicalExRegister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast); 4197 int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler );4197 int pgmHandlerPhysicalExDeregister(PVM pVM, PPGMPHYSHANDLER pPhysHandler, int fRestoreAsRAM); 4198 4198 int pgmHandlerPhysicalExDestroy(PVM pVM, PPGMPHYSHANDLER pHandler); 4199 4199 void pgmR3HandlerPhysicalUpdateAll(PVM pVM);
Note:
See TracChangeset
for help on using the changeset viewer.