Changeset 71075 in vbox
- Timestamp:
- Feb 20, 2018 9:10:45 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120939
- Location:
- trunk
- Files:
-
- 2 added
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/err.h
r70979 r71075 2815 2815 /** NEM init failed. */ 2816 2816 #define VERR_NEM_INIT_FAILED (-6802) 2817 /** NEM init failed because of missing kernel API. */ 2818 #define VERR_NEM_MISSING_KERNEL_API (-6803) 2817 2819 /** NEM failed to create a native VM instance. */ 2818 #define VERR_NEM_VM_CREATE_FAILED (-6803) 2820 #define VERR_NEM_VM_CREATE_FAILED (-6804) 2821 /** NEM failed to map page(s) into the VM. */ 2822 #define VERR_NEM_MAP_PAGES_FAILED (-6805) 2823 /** NEM failed to unmap page(s) into the VM. */ 2824 #define VERR_NEM_UNMAP_PAGES_FAILED (-6806) 2819 2825 /** @} */ 2820 2826 -
trunk/include/VBox/vmm/gvm.h
r69475 r71075 54 54 uint8_t padding[64]; 55 55 } gvmm; 56 57 #ifdef VBOX_WITH_NEM_R0 58 /** The NEM per vcpu data. */ 59 union 60 { 61 # ifdef ___NEMInternal_h 62 struct NEMR0PERVCPU s; 63 # endif 64 uint8_t padding[64]; 65 } nem; 66 #endif 56 67 } GVMCPU; 57 68 /** Pointer to the GVMCPU data. */ … … 107 118 } gmm; 108 119 120 #ifdef VBOX_WITH_NEM_R0 121 /** The NEM per vcpu data. */ 122 union 123 { 124 # ifdef ___NEMInternal_h 125 struct NEMR0PERVM s; 126 # endif 127 uint8_t padding[64]; 128 } nem; 129 #endif 130 109 131 /** The RAWPCIVM per vm data. */ 110 132 union … … 113 135 struct RAWPCIPERVM s; 114 136 #endif 115 uint8_t padding[64];137 uint8_t padding[64]; 116 138 } rawpci; 117 118 139 119 140 /** GVMCPU array for the configured number of virtual CPUs. */ -
trunk/include/VBox/vmm/nem.h
r71041 r71075 80 80 /** @} */ 81 81 82 /** @defgroup grp_nem_hc The NEM host context API 82 83 /** @defgroup grp_nem_r0 The NEM ring-0 Context API 84 * @{ */ 85 VMMR0_INT_DECL(int) NEMR0InitVM(PGVM pGVM, PVM pVM); 86 VMMR0_INT_DECL(void) NEMR0CleanupVM(PGVM pGVM); 87 VMMR0_INT_DECL(int) NEMR0MapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu); 88 VMMR0_INT_DECL(int) NEMR0UnmapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu); 89 /** @} */ 90 91 92 /** @defgroup grp_nem_hc The NEM Host Context API 83 93 * @{ 84 94 */ -
trunk/include/VBox/vmm/vm.h
r71041 r71075 176 176 struct NEMCPU s; 177 177 #endif 178 uint8_t padding[ 128]; /* multiple of 64 */178 uint8_t padding[256]; /* multiple of 64 */ 179 179 } nem; 180 180 … … 265 265 266 266 /** Align the following members on page boundary. */ 267 uint8_t abAlignment2[1 976];267 uint8_t abAlignment2[1848]; 268 268 269 269 /** PGM part. */ -
trunk/include/VBox/vmm/vm.mac
r70948 r71075 64 64 .hm resb 5824 65 65 .em resb 1408 66 .nem resb 12866 .nem resb 256 67 67 .trpm resb 128 68 68 .tm resb 384 -
trunk/include/VBox/vmm/vmm.h
r69107 r71075 501 501 VMMR0_DO_SRV_END, 502 502 503 /** Call NEMR0InitVM() (host specific). */ 504 VMMR0_DO_NEM_INIT_VM = 576, 505 /** Call NEMR0MapPages() (host specific). */ 506 VMMR0_DO_NEM_MAP_PAGES, 507 /** Call NEMR0UnmapPages() (host specific). */ 508 VMMR0_DO_NEM_UNMAP_PAGES, 509 503 510 /** Official call we use for testing Ring-0 APIs. */ 504 VMMR0_DO_TESTS ,511 VMMR0_DO_TESTS = 640, 505 512 /** Test the 32->64 bits switcher. */ 506 513 VMMR0_DO_TEST_SWITCHER3264, -
trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
r70917 r71075 39 39 #include <iprt/asm-math.h> 40 40 #include <iprt/cpuset.h> 41 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) 41 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) 42 42 # include <iprt/dbg.h> 43 43 #endif … … 331 331 { "RTProcSelf", (void *)(uintptr_t)RTProcSelf }, 332 332 { "RTR0AssertPanicSystem", (void *)(uintptr_t)RTR0AssertPanicSystem }, 333 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) 334 { "RTR0DbgKrnlInfoOpen", (void *)(uintptr_t)RTR0DbgKrnlInfoOpen }, /* only-darwin, only-solaris */335 { "RTR0DbgKrnlInfoQueryMember", (void *)(uintptr_t)RTR0DbgKrnlInfoQueryMember }, /* only-darwin, only-solaris */333 #if defined(RT_OS_DARWIN) || defined(RT_OS_SOLARIS) || defined(RT_OS_WINDOWS) 334 { "RTR0DbgKrnlInfoOpen", (void *)(uintptr_t)RTR0DbgKrnlInfoOpen }, /* only-darwin, only-solaris, only-windows */ 335 { "RTR0DbgKrnlInfoQueryMember", (void *)(uintptr_t)RTR0DbgKrnlInfoQueryMember }, /* only-darwin, only-solaris, only-windows */ 336 336 # if defined(RT_OS_SOLARIS) 337 337 { "RTR0DbgKrnlInfoQuerySize", (void *)(uintptr_t)RTR0DbgKrnlInfoQuerySize }, /* only-solaris */ 338 338 # endif 339 { "RTR0DbgKrnlInfoQuerySymbol", (void *)(uintptr_t)RTR0DbgKrnlInfoQuerySymbol }, /* only-darwin, only-solaris */340 { "RTR0DbgKrnlInfoRelease", (void *)(uintptr_t)RTR0DbgKrnlInfoRelease }, /* only-darwin, only-solaris */341 { "RTR0DbgKrnlInfoRetain", (void *)(uintptr_t)RTR0DbgKrnlInfoRetain }, /* only-darwin, only-solaris */339 { "RTR0DbgKrnlInfoQuerySymbol", (void *)(uintptr_t)RTR0DbgKrnlInfoQuerySymbol }, /* only-darwin, only-solaris, only-windows */ 340 { "RTR0DbgKrnlInfoRelease", (void *)(uintptr_t)RTR0DbgKrnlInfoRelease }, /* only-darwin, only-solaris, only-windows */ 341 { "RTR0DbgKrnlInfoRetain", (void *)(uintptr_t)RTR0DbgKrnlInfoRetain }, /* only-darwin, only-solaris, only-windows */ 342 342 #endif 343 343 { "RTR0MemAreKrnlAndUsrDifferent", (void *)(uintptr_t)RTR0MemAreKrnlAndUsrDifferent }, -
trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
r70917 r71075 214 214 * @remarks 0x002a0000 is used by 5.1. The next version number must be 0x002b0000. 215 215 */ 216 #define SUPDRV_IOC_VERSION 0x0029000 1216 #define SUPDRV_IOC_VERSION 0x00290002 217 217 218 218 /** SUP_IOCTL_COOKIE. */ -
trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
r70918 r71075 277 277 CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION; 278 278 const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00290000 279 ? 0x0029000 1279 ? 0x00290002 280 280 : SUPDRV_IOC_VERSION & 0xffff0000; 281 281 CookieReq.u.In.u32MinVersion = uMinVersion; -
trunk/src/VBox/VMM/Makefile.kmk
r70979 r71075 829 829 VMMR0/VMMR0JmpA-x86.asm 830 830 831 if1of ($(USERNAME),bird) # experimental. 832 VMMR0_SOURCES.win.amd64 += VMMR0/NEMR0Native-win.cpp 833 VMMR0_DEFS.win.amd64 += VBOX_WITH_NATIVE_NEM VBOX_WITH_NEM_R0 834 endif 835 831 836 VMMR0_LIBS = \ 832 837 $(PATH_STAGE_LIB)/ServicesR0$(VBOX_SUFF_LIB) \ -
trunk/src/VBox/VMM/VMMAll/AllPdbTypeHack.cpp
r69111 r71075 51 51 #include "../include/EMInternal.h" 52 52 #include "../include/IEMInternal.h" 53 #include "../include/NEMInternal.h" 53 54 #include "../include/REMInternal.h" 54 55 #include "../VMMR0/GMMR0Internal.h" -
trunk/src/VBox/VMM/VMMR0/GVMMR0.cpp
r69111 r71075 58 58 #include <VBox/vmm/vmcpuset.h> 59 59 #include <VBox/vmm/vmm.h> 60 #ifdef VBOX_WITH_NEM_R0 61 # include <VBox/vmm/nem.h> 62 #endif 60 63 #include <VBox/param.h> 61 64 #include <VBox/err.h> … … 1243 1246 1244 1247 GMMR0CleanupVM(pGVM); 1248 #ifdef VBOX_WITH_NEM_R0 1249 NEMR0CleanupVM(pGVM); 1250 #endif 1245 1251 1246 1252 AssertCompile((uintptr_t)NIL_RTTHREADCTXHOOK == 0); /* Depends on zero initialized memory working for NIL at the moment. */ -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r70917 r71075 27 27 #include <VBox/vmm/pdmapi.h> 28 28 #include <VBox/vmm/pgm.h> 29 #ifdef VBOX_WITH_NEM_R0 30 # include <VBox/vmm/nem.h> 31 #endif 29 32 #include <VBox/vmm/stam.h> 30 33 #include <VBox/vmm/tm.h> … … 1959 1962 break; 1960 1963 #endif 1964 1965 /* 1966 * NEM requests. 1967 */ 1968 #ifdef VBOX_WITH_NEM_R0 1969 # if defined(RT_ARCH_AMD64) && defined(RT_OS_WINDOWS) 1970 case VMMR0_DO_NEM_INIT_VM: 1971 if (u64Arg || pReqHdr || idCpu != 0) 1972 return VERR_INVALID_PARAMETER; 1973 rc = NEMR0InitVM(pGVM, pVM); 1974 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1975 break; 1976 1977 case VMMR0_DO_NEM_MAP_PAGES: 1978 if (u64Arg || pReqHdr || idCpu == NIL_VMCPUID) 1979 return VERR_INVALID_PARAMETER; 1980 rc = NEMR0MapPages(pGVM, pVM, idCpu); 1981 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1982 break; 1983 1984 case VMMR0_DO_NEM_UNMAP_PAGES: 1985 if (u64Arg || pReqHdr || idCpu == NIL_VMCPUID) 1986 return VERR_INVALID_PARAMETER; 1987 rc = NEMR0UnmapPages(pGVM, pVM, idCpu); 1988 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING); 1989 break; 1990 # endif 1991 #endif 1992 1961 1993 /* 1962 1994 * For profiling. -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r71044 r71075 5 5 * Log group 2: Exit logging. 6 6 * Log group 3: Log context on exit. 7 * Log group 5: Ring-3 memory management 8 * Log group 6: Ring-0 memory management 7 9 * Log group 12: API intercepts. 8 10 */ … … 26 28 #define LOG_GROUP LOG_GROUP_NEM 27 29 #include <iprt/nt/nt-and-windows.h> 30 #include <iprt/nt/hyperv.h> 28 31 #include <WinHvPlatform.h> 29 32 … … 73 76 #define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \ 74 77 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) ) 78 79 80 #define NEM_WIN_USE_HYPERCALLS 75 81 76 82 … … 147 153 /** @} */ 148 154 155 /** @name APIs imported from Vid.dll 156 * @{ */ 157 static BOOL (WINAPI *g_pfnVidGetHvPartitionId)(HANDLE hPartition, HV_PARTITION_ID *pidPartition); 158 /** @} */ 159 149 160 150 161 /** … … 176 187 NEM_WIN_IMPORT(0, false, WHvGetVirtualProcessorRegisters), 177 188 NEM_WIN_IMPORT(0, false, WHvSetVirtualProcessorRegisters), 189 NEM_WIN_IMPORT(1, false, VidGetHvPartitionId), 178 190 #undef NEM_WIN_IMPORT 179 191 }; … … 752 764 { 753 765 /* 754 * C reate and initialize a partition.766 * Check out our ring-0 capabilities. 755 767 */ 756 rc = nemR3WinInitCreatePartition(pVM, pErrInfo);768 rc = SUPR3CallVMMR0Ex(pVM->pVMR0, 0 /*idCpu*/, VMMR0_DO_NEM_INIT_VM, 0, NULL); 757 769 if (RT_SUCCESS(rc)) 758 770 { 759 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 760 Log(("NEM: Marked active!\n")); 771 /* 772 * Create and initialize a partition. 773 */ 774 rc = nemR3WinInitCreatePartition(pVM, pErrInfo); 775 if (RT_SUCCESS(rc)) 776 { 777 VM_SET_MAIN_EXECUTION_ENGINE(pVM, VM_EXEC_ENGINE_NATIVE_API); 778 Log(("NEM: Marked active!\n")); 779 } 761 780 } 762 781 } … … 862 881 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 863 882 "Failed to get device handle for partition %p: %Rhrc", hPartition, hrc); 864 /** @todo Do a Vid query that uses the handle to check that we've got a 865 * working value. */ 883 884 HV_PARTITION_ID idHvPartition = HV_PARTITION_ID_INVALID; 885 if (!g_pfnVidGetHvPartitionId(hPartitionDevice, &idHvPartition)) 886 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 887 "Failed to get device handle and/or partition ID for %p (hPartitionDevice=%p, Last=%#x/%u)", 888 hPartition, hPartitionDevice, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 866 889 pVM->nem.s.hPartitionDevice = hPartitionDevice; 890 pVM->nem.s.idHvPartition = idHvPartition; 867 891 868 892 /* … … 890 914 pVM->nem.s.fCreatedEmts = true; 891 915 892 LogRel(("NEM: Successfully set up partition (device handle %p )\n", hPartitionDevice));916 LogRel(("NEM: Successfully set up partition (device handle %p, partition ID %#llx)\n", hPartitionDevice, idHvPartition)); 893 917 return VINF_SUCCESS; 894 918 } … … 1588 1612 if (pPendingInt->fInterruptionPending) 1589 1613 { 1590 Log 6(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x unk0=%u unk1=%u\n",1614 Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x unk0=%u unk1=%u\n", 1591 1615 pPendingInt->enmInterruptionType, pPendingInt->InterruptionVector, pPendingInt->fDeliverErrCd, 1592 1616 pPendingInt->uErrCd, pPendingInt->fUnknown0, pPendingInt->fUnknown1)); … … 1816 1840 } 1817 1841 1842 1818 1843 static DECLCALLBACK(int) nemR3WinUnmapOnePageCallback(PVM pVM, RTGCPHYS GCPhys, uint8_t *pu2NemState, void *pvUser) 1819 1844 { 1820 1845 RT_NOREF_PV(pvUser); 1846 #ifdef NEM_WIN_USE_HYPERCALLS 1847 PVMCPU pVCpu = VMMGetCpu(pVM); 1848 pVCpu->nem.s.Hypercall.UnmapPages.GCPhys = GCPhys; 1849 pVCpu->nem.s.Hypercall.UnmapPages.cPages = 1; 1850 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_UNMAP_PAGES, 0, NULL); 1851 AssertRC(rc); 1852 if (RT_SUCCESS(rc)) 1853 #else 1821 1854 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE); 1822 1855 if (SUCCEEDED(hrc)) 1856 #endif 1857 { 1858 Log5(("NEM GPA unmap all: %RGp (cMappedPages=%u)\n", GCPhys, pVM->nem.s.cMappedPages - 1)); 1823 1859 *pu2NemState = NEM_WIN_PAGE_STATE_UNMAPPED; 1860 } 1824 1861 else 1825 1862 { 1863 #ifdef NEM_WIN_USE_HYPERCALLS 1864 LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc)); 1865 #else 1826 1866 LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n", 1827 1867 GCPhys, g_apszPageStates[*pu2NemState], hrc, hrc, RTNtCurrentTeb()->LastStatusValue, 1828 1868 RTNtCurrentTeb()->LastErrorValue, pVM->nem.s.cMappedPages)); 1869 #endif 1829 1870 *pu2NemState = NEM_WIN_PAGE_STATE_NOT_SET; 1830 1871 } … … 1947 1988 * If this fails, which it does every so often, just unmap everything for now. 1948 1989 */ 1990 #ifdef NEM_WIN_USE_HYPERCALLS 1991 pVCpu->nem.s.Hypercall.UnmapPages.GCPhys = GCPhys; 1992 pVCpu->nem.s.Hypercall.UnmapPages.cPages = 1; 1993 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_UNMAP_PAGES, 0, NULL); 1994 AssertRC(rc); 1995 if (RT_SUCCESS(rc)) 1996 #else 1949 1997 /** @todo figure out whether we mess up the state or if it's WHv. */ 1950 1998 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE); 1951 1999 if (SUCCEEDED(hrc)) 2000 #endif 1952 2001 { 1953 2002 pState->fDidSomething = true; 1954 2003 pState->fCanResume = true; 1955 2004 pInfo->u2NemState = NEM_WIN_PAGE_STATE_UNMAPPED; 1956 Log5(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp => unmapped[%s]\n", GCPhys, g_apszPageStates[u2State])); 2005 uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2006 Log5(("NEM GPA unmapped/exit: %RGp (was %s, cMappedPages=%u)\n", GCPhys, g_apszPageStates[u2State], cMappedPages)); 1957 2007 return VINF_SUCCESS; 1958 2008 } 2009 #ifdef NEM_WIN_USE_HYPERCALLS 2010 LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhys, rc)); 2011 return rc; 2012 #else 1959 2013 LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp %s hrc=%Rhrc (%#x) Last=%#x/%u (cMappedPages=%u)\n", 1960 2014 GCPhys, g_apszPageStates[u2State], hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue, … … 1968 2022 pInfo->u2NemState = NEM_WIN_PAGE_STATE_UNMAPPED; 1969 2023 return VINF_SUCCESS; 2024 #endif 1970 2025 } 1971 2026 … … 2183 2238 const bool fSingleStepping = false; /** @todo get this from somewhere. */ 2184 2239 VBOXSTRICTRC rcStrict = VINF_SUCCESS; 2185 for ( ;;)2240 for (unsigned iLoop = 0;;iLoop++) 2186 2241 { 2187 2242 /* … … 2327 2382 } 2328 2383 2384 #ifdef NEM_WIN_USE_HYPERCALLS 2329 2385 /* Hack alert! */ 2330 2386 uint32_t const cMappedPages = pVM->nem.s.cMappedPages; … … 2336 2392 Log(("nemR3NativeRunGC: Unmapped all; cMappedPages=%u -> %u\n", cMappedPages, pVM->nem.s.cMappedPages)); 2337 2393 } 2394 #endif 2338 2395 2339 2396 /* If any FF is pending, return to the EM loops. That's okay for the … … 2504 2561 PPGMPHYSNEMPAGEINFO pInfo, void *pvUser) 2505 2562 { 2506 Assert(pVCpu == NULL);2507 2508 2563 /* We'll just unmap the memory. */ 2509 2564 if (pInfo->u2NemState > NEM_WIN_PAGE_STATE_UNMAPPED) 2510 2565 { 2566 #ifdef NEM_WIN_USE_HYPERCALLS 2567 pVCpu->nem.s.Hypercall.UnmapPages.GCPhys = GCPhys; 2568 pVCpu->nem.s.Hypercall.UnmapPages.cPages = 1; 2569 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_UNMAP_PAGES, 0, NULL); 2570 AssertRC(rc); 2571 if (RT_SUCCESS(rc)) 2572 #else 2511 2573 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE); 2512 2574 if (SUCCEEDED(hrc)) 2575 #endif 2576 { 2577 uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2578 Log5(("NEM GPA unmapped/A20: %RGp (was %s, cMappedPages=%u)\n", GCPhys, g_apszPageStates[pInfo->u2NemState], cMappedPages)); 2513 2579 pInfo->u2NemState = NEM_WIN_PAGE_STATE_UNMAPPED; 2580 } 2514 2581 else 2515 2582 { 2583 #ifdef NEM_WIN_USE_HYPERCALLS 2584 LogRel(("nemR3WinUnsetForA20CheckerCallback/unmap: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc)); 2585 return rc; 2586 #else 2516 2587 LogRel(("nemR3WinUnsetForA20CheckerCallback/unmap: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 2517 2588 GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 2518 2589 return VERR_INTERNAL_ERROR_2; 2590 #endif 2519 2591 } 2520 2592 } … … 2529 2601 * @returns The PGMPhysNemQueryPageInfo result. 2530 2602 * @param pVM The cross context VM structure. 2531 * @param pVCpu The cross context virtual CPU structure. Optional.2603 * @param pVCpu The cross context virtual CPU structure. 2532 2604 * @param GCPhys The page to unmap. 2533 2605 */ 2534 static int nemR3WinUnmapPageForA20Gate(PVM pVM, RTGCPHYS GCPhys)2606 static int nemR3WinUnmapPageForA20Gate(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys) 2535 2607 { 2536 2608 PGMPHYSNEMPAGEINFO Info; 2537 return PGMPhysNemPageInfoChecker(pVM, NULL /*pVCpu*/, GCPhys, false /*fMakeWritable*/, &Info,2609 return PGMPhysNemPageInfoChecker(pVM, pVCpu, GCPhys, false /*fMakeWritable*/, &Info, 2538 2610 nemR3WinUnsetForA20CheckerCallback, NULL); 2539 2611 } … … 2558 2630 pVM->nem.s.fA20Enabled = fEnabled; 2559 2631 for (RTGCPHYS GCPhys = _1M; GCPhys < _1M + _64K; GCPhys += X86_PAGE_SIZE) 2560 nemR3WinUnmapPageForA20Gate(pVM, GCPhys);2632 nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys); 2561 2633 } 2562 2634 } … … 2619 2691 if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED) 2620 2692 { 2693 #ifdef NEM_WIN_USE_HYPERCALLS 2694 PVMCPU pVCpu = VMMGetCpu(pVM); 2695 pVCpu->nem.s.Hypercall.UnmapPages.GCPhys = GCPhysDst; 2696 pVCpu->nem.s.Hypercall.UnmapPages.cPages = 1; 2697 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_UNMAP_PAGES, 0, NULL); 2698 AssertRC(rc); 2699 if (RT_SUCCESS(rc)) 2700 { 2701 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2702 uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2703 if (u2NewState == NEM_WIN_PAGE_STATE_UNMAPPED) 2704 { 2705 Log5(("NEM GPA unmapped/set: %RGp (was %s, cMappedPages=%u)\n", 2706 GCPhysDst, g_apszPageStates[u2OldState], cMappedPages)); 2707 return VINF_SUCCESS; 2708 } 2709 } 2710 else 2711 { 2712 LogRel(("nemR3NativeSetPhysPage/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2713 return rc; 2714 } 2715 #else 2621 2716 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst, X86_PAGE_SIZE); 2622 2717 if (SUCCEEDED(hrc)) … … 2626 2721 if (u2NewState == NEM_WIN_PAGE_STATE_UNMAPPED) 2627 2722 { 2628 Log5(("nemR3NativeSetPhysPage: %RGp => unmapped (total %u)\n", GCPhysDst, cMappedPages)); 2723 Log5(("NEM GPA unmapped/set: %RGp (was %s, cMappedPages=%u)\n", 2724 GCPhysDst, g_apszPageStates[u2OldState], cMappedPages)); 2629 2725 return VINF_SUCCESS; 2630 2726 } … … 2636 2732 return VERR_NEM_INIT_FAILED; 2637 2733 } 2734 #endif 2638 2735 } 2639 2736 } … … 2644 2741 if (fPageProt & NEM_PAGE_PROT_WRITE) 2645 2742 { 2743 #ifdef NEM_WIN_USE_HYPERCALLS 2744 RT_NOREF_PV(GCPhysSrc); 2745 PVMCPU pVCpu = VMMGetCpu(pVM); 2746 pVCpu->nem.s.Hypercall.MapPages.GCPhysSrc = GCPhysSrc; 2747 pVCpu->nem.s.Hypercall.MapPages.GCPhysDst = GCPhysDst; 2748 pVCpu->nem.s.Hypercall.MapPages.cPages = 1; 2749 pVCpu->nem.s.Hypercall.MapPages.fFlags = HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE 2750 | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN; 2751 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_MAP_PAGES, 0, NULL); 2752 AssertRC(rc); 2753 if (RT_SUCCESS(rc)) 2754 { 2755 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 2756 uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2757 Log5(("NEM GPA mapped/set: %RGp %s (was %s, cMappedPages=%u)\n", 2758 GCPhysDst, g_apszPageStates[u2NewState], g_apszPageStates[u2OldState], cMappedPages)); 2759 return VINF_SUCCESS; 2760 } 2761 LogRel(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2762 return rc; 2763 #else 2646 2764 void *pvPage; 2647 2765 int rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhysSrc, &pvPage); … … 2654 2772 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 2655 2773 uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2656 Log5(("nemR3NativeSetPhysPage: %RGp => writable (total %u)\n", GCPhysDst, cMappedPages)); 2774 Log5(("NEM GPA mapped/set: %RGp %s (was %s, cMappedPages=%u)\n", 2775 GCPhysDst, g_apszPageStates[u2NewState], g_apszPageStates[u2OldState], cMappedPages)); 2657 2776 return VINF_SUCCESS; 2658 2777 } … … 2663 2782 LogRel(("nemR3NativeSetPhysPage/writable: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc)); 2664 2783 return rc; 2784 #endif 2665 2785 } 2666 2786 2667 2787 if (fPageProt & NEM_PAGE_PROT_READ) 2668 2788 { 2789 #ifdef NEM_WIN_USE_HYPERCALLS 2790 PVMCPU pVCpu = VMMGetCpu(pVM); 2791 pVCpu->nem.s.Hypercall.MapPages.GCPhysSrc = GCPhysSrc; 2792 pVCpu->nem.s.Hypercall.MapPages.GCPhysDst = GCPhysDst; 2793 pVCpu->nem.s.Hypercall.MapPages.cPages = 1; 2794 pVCpu->nem.s.Hypercall.MapPages.fFlags = HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN; 2795 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_MAP_PAGES, 0, NULL); 2796 AssertRC(rc); 2797 if (RT_SUCCESS(rc)) 2798 { 2799 *pu2State = NEM_WIN_PAGE_STATE_READABLE; 2800 uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2801 Log5(("NEM GPA mapped/set: %RGp %s (was %s, cMappedPages=%u)\n", 2802 GCPhysDst, g_apszPageStates[u2NewState], g_apszPageStates[u2OldState], cMappedPages)); 2803 return VINF_SUCCESS; 2804 } 2805 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2806 return rc; 2807 #else 2669 2808 const void *pvPage; 2670 2809 int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhysSrc, &pvPage); … … 2677 2816 *pu2State = NEM_WIN_PAGE_STATE_READABLE; 2678 2817 uint32_t cMappedPages = ASMAtomicIncU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2679 Log5(("nemR3NativeSetPhysPage: %RGp => read+exec (total %u)\n", GCPhysDst, cMappedPages)); 2818 Log5(("NEM GPA mapped/set: %RGp %s (was %s, cMappedPages=%u)\n", 2819 GCPhysDst, g_apszPageStates[u2NewState], g_apszPageStates[u2OldState], cMappedPages)); 2680 2820 return VINF_SUCCESS; 2681 2821 } … … 2686 2826 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc)); 2687 2827 return rc; 2828 #endif 2688 2829 } 2689 2830 … … 2703 2844 } 2704 2845 2705 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst, X86_PAGE_SIZE); 2846 #ifdef NEM_WIN_USE_HYPERCALLS 2847 PVMCPU pVCpu = VMMGetCpu(pVM); 2848 pVCpu->nem.s.Hypercall.UnmapPages.GCPhys = GCPhysDst & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK; 2849 pVCpu->nem.s.Hypercall.UnmapPages.cPages = 1; 2850 int rc = SUPR3CallVMMR0Ex(pVM->pVMR0, pVCpu->idCpu, VMMR0_DO_NEM_UNMAP_PAGES, 0, NULL); 2851 AssertRC(rc); 2852 if (RT_SUCCESS(rc)) 2853 { 2854 uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2855 Log5(("NEM GPA unmapped/just: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[*pu2State], cMappedPages)); 2856 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2857 return VINF_SUCCESS; 2858 } 2859 LogRel(("nemR3NativeSetPhysPage/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2860 return rc; 2861 #else 2862 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, X86_PAGE_SIZE); 2706 2863 if (SUCCEEDED(hrc)) 2707 2864 { … … 2714 2871 GCPhysDst, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 2715 2872 return VERR_INTERNAL_ERROR_3; 2873 #endif 2716 2874 } 2717 2875 … … 2732 2890 { 2733 2891 /* To keep effort at a minimum, we unmap the HMA page alias and resync it lazily when needed. */ 2734 rc = nemR3WinUnmapPageForA20Gate(pVM, GCPhys | RT_BIT_32(20));2892 rc = nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys | RT_BIT_32(20)); 2735 2893 if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys) && RT_SUCCESS(rc)) 2736 2894 rc = nemR3NativeSetPhysPage(pVM, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); … … 2765 2923 { 2766 2924 /* To keep effort at a minimum, we unmap the HMA page alias and resync it lazily when needed. */ 2767 nemR3WinUnmapPageForA20Gate(pVM, GCPhys | RT_BIT_32(20));2925 nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys | RT_BIT_32(20)); 2768 2926 if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 2769 2927 nemR3NativeSetPhysPage(pVM, GCPhys, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/); … … 2795 2953 { 2796 2954 /* To keep effort at a minimum, we unmap the HMA page alias and resync it lazily when needed. */ 2797 nemR3WinUnmapPageForA20Gate(pVM, GCPhys | RT_BIT_32(20));2955 nemR3WinUnmapPageForA20Gate(pVM, pVCpu, GCPhys | RT_BIT_32(20)); 2798 2956 if (!NEM_WIN_IS_SUBJECT_TO_A20(GCPhys)) 2799 2957 nemR3NativeSetPhysPage(pVM, GCPhys, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); -
trunk/src/VBox/VMM/include/NEMInternal.h
r71043 r71075 25 25 #include <VBox/vmm/stam.h> 26 26 #include <VBox/vmm/vmapi.h> 27 #ifdef RT_OS_WINDOWS 28 #include <iprt/nt/hyperv.h> 29 #endif 27 30 28 31 RT_C_DECLS_BEGIN … … 83 86 * controls. */ 84 87 RTR3PTR hPartitionDevice; 88 /** The Hyper-V partition ID. */ 89 uint64_t idHvPartition; 85 90 86 91 /** Number of currently mapped pages. */ … … 105 110 /** NEMCPU_MAGIC. */ 106 111 uint32_t u32Magic; 107 112 #ifdef RT_OS_WINDOWS 113 /** Parameters for making Hyper-V hypercalls. */ 114 union 115 { 116 uint8_t ab[64]; 117 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */ 118 struct 119 { 120 RTGCPHYS GCPhysSrc; 121 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */ 122 uint32_t cPages; 123 HV_MAP_GPA_FLAGS fFlags; 124 } MapPages; 125 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */ 126 struct 127 { 128 RTGCPHYS GCPhys; 129 uint32_t cPages; 130 } UnmapPages; 131 } Hypercall; 132 #endif 108 133 } NEMCPU; 109 134 /** Pointer to NEM VMCPU instance data. */ … … 114 139 /** NEMCPU::u32Magic value after termination. */ 115 140 #define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222) 141 142 143 #ifdef IN_RING0 144 145 /** 146 * NEM GVMCPU instance data. 147 */ 148 typedef struct NEMR0PERVCPU 149 { 150 # ifdef RT_OS_WINDOWS 151 /** @name Hypercall input/ouput page. 152 * @{ */ 153 /** Host physical address of the hypercall input/output page. */ 154 RTHCPHYS HCPhysHypercallData; 155 /** Pointer to the hypercall input/output page. */ 156 uint8_t *pbHypercallData; 157 /** Handle to the memory object of the hypercall input/output page. */ 158 RTR0MEMOBJ hHypercallDataMemObj; 159 /** @} */ 160 # endif 161 } NEMR0PERVCPU; 162 163 /** 164 * NEM GVM instance data. 165 */ 166 typedef struct NEMR0PERVM 167 { 168 # ifdef RT_OS_WINDOWS 169 /** The partition ID. */ 170 uint64_t idHvPartition; 171 # endif 172 } NEMR0PERVM; 173 174 #endif /* IN_RING*/ 175 116 176 117 177 #ifdef IN_RING3 … … 148 208 149 209 210 #ifdef RT_OS_WINDOWS 211 /** Maximum number of pages we can map in a single NEMR0MapPages call. */ 212 # define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER)) 213 /** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */ 214 # define NEM_MAX_UNMAP_PAGES 4095 215 216 #endif 150 217 /** @} */ 151 218
Note:
See TracChangeset
for help on using the changeset viewer.