Changeset 71082 in vbox
- Timestamp:
- Feb 21, 2018 11:18:47 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r71081 r71082 1959 1959 1960 1960 /* 1961 * Consolidate current page state with actual page protection and access type. 1962 * We don't really consider downgrades here, as they shouldn't happen. 1963 */ 1964 #ifndef NEM_WIN_USE_HYPERCALLS 1965 /** @todo Someone at microsoft please explain: 1961 1966 * I'm not sure WTF was going on, but I ended up in a loop if I remapped a 1962 * readonly page as writable. Specifically, this was an issue with the big 1963 * VRAM mapping at 0xe0000000 when booing DSL 4.4.1. So, in a hope to work 1964 * around that we no longer pre-map anything, just unmap stuff and do it 1965 * lazily here. And here we will first unmap, restart, and then remap with 1966 * new protection or backing. 1967 */ 1967 * readonly page as writable (unmap, then map again). Specifically, this was an 1968 * issue with the big VRAM mapping at 0xe0000000 when booing DSL 4.4.1. So, in 1969 * a hope to work around that we no longer pre-map anything, just unmap stuff 1970 * and do it lazily here. And here we will first unmap, restart, and then remap 1971 * with new protection or backing. 1972 */ 1973 #endif 1974 int rc; 1968 1975 switch (u2State) 1969 1976 { 1970 1977 case NEM_WIN_PAGE_STATE_UNMAPPED: 1971 1978 case NEM_WIN_PAGE_STATE_NOT_SET: 1972 {1973 1979 if (pInfo->fNemProt == NEM_PAGE_PROT_NONE) 1974 1980 { … … 1986 1992 1987 1993 /* Map the page. */ 1988 intrc = nemR3NativeSetPhysPage(pVM,1989 1990 1991 1992 1993 1994 1994 rc = nemR3NativeSetPhysPage(pVM, 1995 pVCpu, 1996 GCPhysSrc & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, 1997 GCPhys & ~(RTGCPHYS)X86_PAGE_OFFSET_MASK, 1998 pInfo->fNemProt, 1999 &u2State, 2000 true /*fBackingState*/); 1995 2001 pInfo->u2NemState = u2State; 1996 2002 Log4(("nemR3WinHandleMemoryAccessPageCheckerCallback: %RGp - synced => %s + %Rrc\n", 1997 2003 GCPhys, g_apszPageStates[u2State], rc)); 1998 RT_NOREF(pVCpu);1999 2004 pState->fDidSomething = true; 2000 2005 pState->fCanResume = true; 2001 2006 return rc; 2002 }2003 2007 2004 2008 case NEM_WIN_PAGE_STATE_READABLE: … … 2016 2020 && pState->fWriteAccess) 2017 2021 { 2018 intrc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhys,2019 2020 2022 rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhys, 2023 HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE 2024 | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN); 2021 2025 AssertRC(rc); 2022 2026 if (RT_SUCCESS(rc)) … … 2027 2031 Log5(("NEM GPA write-upgrade/exit: %RGp (was %s, cMappedPages=%u)\n", 2028 2032 GCPhys, g_apszPageStates[u2State], pVM->nem.s.cMappedPages)); 2029 return rc;2030 2033 } 2031 2034 } 2035 else 2036 { 2037 /* Need to emulate the acces. */ 2038 AssertBreak(pInfo->fNemProt != NEM_PAGE_PROT_NONE); /* There should be no downgrades. */ 2039 rc = VINF_SUCCESS; 2040 } 2041 return rc; 2042 #else 2043 break; 2032 2044 #endif 2033 break;2034 2045 2035 2046 case NEM_WIN_PAGE_STATE_WRITABLE: … … 2039 2050 return VINF_SUCCESS; 2040 2051 } 2052 #ifdef NEM_WIN_USE_HYPERCALLS 2053 AssertFailed(); /* There should be no downgrades. */ 2054 #endif 2041 2055 break; 2042 2056 … … 2050 2064 */ 2051 2065 #ifdef NEM_WIN_USE_HYPERCALLS 2052 intrc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);2066 rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys); 2053 2067 AssertRC(rc); 2054 2068 if (RT_SUCCESS(rc)) … … 2738 2752 uint8_t *pu2State, bool fBackingChanged) 2739 2753 { 2754 #ifdef NEM_WIN_USE_HYPERCALLS 2755 /* 2756 * When using the hypercalls instead of the ring-3 APIs, we don't need to 2757 * unmap memory before modifying it. We still want to track the state though, 2758 * since unmap will fail when called an unmapped page and we don't want to redo 2759 * upgrades/downgrades. 2760 */ 2761 uint8_t const u2OldState = *pu2State; 2762 int rc; 2763 if (fPageProt == NEM_PAGE_PROT_NONE) 2764 { 2765 if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED) 2766 { 2767 rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst); 2768 if (RT_SUCCESS(rc)) 2769 { 2770 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2771 uint32_t cMappedPages = ASMAtomicDecU32(&pVM->nem.s.cMappedPages); NOREF(cMappedPages); 2772 Log5(("NEM GPA unmapped/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages)); 2773 } 2774 else 2775 AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2776 } 2777 else 2778 rc = VINF_SUCCESS; 2779 } 2780 else if (fPageProt & NEM_PAGE_PROT_WRITE) 2781 { 2782 if (u2OldState != NEM_WIN_PAGE_STATE_WRITABLE || fBackingChanged) 2783 { 2784 rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst, 2785 HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE 2786 | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN); 2787 if (RT_SUCCESS(rc)) 2788 { 2789 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 2790 uint32_t cMappedPages = u2OldState <= NEM_WIN_PAGE_STATE_UNMAPPED 2791 ? ASMAtomicIncU32(&pVM->nem.s.cMappedPages) : pVM->nem.s.cMappedPages; 2792 Log5(("NEM GPA writable/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages)); 2793 NOREF(cMappedPages); 2794 } 2795 else 2796 AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2797 } 2798 else 2799 rc = VINF_SUCCESS; 2800 } 2801 else 2802 { 2803 if (u2OldState != NEM_WIN_PAGE_STATE_READABLE || fBackingChanged) 2804 { 2805 rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst, 2806 HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN); 2807 if (RT_SUCCESS(rc)) 2808 { 2809 *pu2State = NEM_WIN_PAGE_STATE_READABLE; 2810 uint32_t cMappedPages = u2OldState <= NEM_WIN_PAGE_STATE_UNMAPPED 2811 ? ASMAtomicIncU32(&pVM->nem.s.cMappedPages) : pVM->nem.s.cMappedPages; 2812 Log5(("NEM GPA read+exec/set: %RGp (was %s, cMappedPages=%u)\n", GCPhysDst, g_apszPageStates[u2OldState], cMappedPages)); 2813 NOREF(cMappedPages); 2814 } 2815 else 2816 AssertLogRelMsgFailed(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2817 } 2818 else 2819 rc = VINF_SUCCESS; 2820 } 2821 2822 return VINF_SUCCESS; 2823 2824 #else 2740 2825 /* 2741 2826 * Looks like we need to unmap a page before we can change the backing … … 2751 2836 if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED) 2752 2837 { 2753 # ifdef NEM_WIN_USE_HYPERCALLS2838 # ifdef NEM_WIN_USE_HYPERCALLS 2754 2839 int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst); 2755 2840 AssertRC(rc); … … 2770 2855 return rc; 2771 2856 } 2772 # else2857 # else 2773 2858 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhysDst, X86_PAGE_SIZE); 2774 2859 if (SUCCEEDED(hrc)) … … 2789 2874 return VERR_NEM_INIT_FAILED; 2790 2875 } 2791 # endif2876 # endif 2792 2877 } 2793 2878 } … … 2798 2883 if (fPageProt & NEM_PAGE_PROT_WRITE) 2799 2884 { 2800 # ifdef NEM_WIN_USE_HYPERCALLS2885 # ifdef NEM_WIN_USE_HYPERCALLS 2801 2886 int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst, 2802 2887 HV_MAP_GPA_READABLE | HV_MAP_GPA_WRITABLE … … 2813 2898 LogRel(("nemR3NativeSetPhysPage/writable: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2814 2899 return rc; 2815 # else2900 # else 2816 2901 void *pvPage; 2817 2902 int rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhysSrc, &pvPage); … … 2834 2919 LogRel(("nemR3NativeSetPhysPage/writable: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc)); 2835 2920 return rc; 2836 # endif2921 # endif 2837 2922 } 2838 2923 2839 2924 if (fPageProt & NEM_PAGE_PROT_READ) 2840 2925 { 2841 # ifdef NEM_WIN_USE_HYPERCALLS2926 # ifdef NEM_WIN_USE_HYPERCALLS 2842 2927 int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst, 2843 2928 HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN); … … 2853 2938 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysDst=%RGp rc=%Rrc\n", GCPhysDst, rc)); 2854 2939 return rc; 2855 # else2940 # else 2856 2941 const void *pvPage; 2857 2942 int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhysSrc, &pvPage); … … 2874 2959 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhysSrc=%RGp rc=%Rrc\n", GCPhysSrc, rc)); 2875 2960 return rc; 2876 # endif2961 # endif 2877 2962 } 2878 2963 … … 2880 2965 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 2881 2966 return VINF_SUCCESS; 2967 #endif /* !NEM_WIN_USE_HYPERCALLS */ 2882 2968 } 2883 2969
Note:
See TracChangeset
for help on using the changeset viewer.