Changeset 71075 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Feb 20, 2018 9:10:45 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120939
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
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*/);
Note:
See TracChangeset
for help on using the changeset viewer.