Changeset 70977 in vbox for trunk/src/VBox/VMM/VMMR3
- Timestamp:
- Feb 12, 2018 8:45:31 PM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 120824
- Location:
- trunk/src/VBox/VMM/VMMR3
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR3/NEMR3.cpp
r70954 r70977 249 249 250 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); 251 VMMR3_INT_DECL(int) NEMR3NotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2) 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, pvMmio2); 257 #else 258 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2); 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); 257 270 #else 258 271 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); … … 262 275 263 276 264 VMMR3_INT_DECL(int) NEMR3NotifyPhys MmioExUnmap(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 = nemR3NativeNotifyPhys MmioExUnmap(pVM, GCPhys, cb, fFlags);277 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS 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); 270 283 #else 271 284 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); … … 275 288 276 289 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) 290 /** 291 * Called after the ROM range has been fully completed. 292 * 293 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a 294 * number of NEMHCNotifyPhysPageProtChanged calls. 295 * 296 * @returns VBox status code 297 * @param pVM The cross context VM structure. 298 * @param GCPhys The ROM address (page aligned). 299 * @param cb The size (page aligned). 300 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 301 */ 302 VMMR3_INT_DECL(int) NEMR3NotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 291 303 { 292 304 int rc = VINF_SUCCESS; -
trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
r70954 r70977 21 21 *********************************************************************************************************************************/ 22 22 #define LOG_GROUP LOG_GROUP_NEM 23 #include <iprt/nt/nt-and-windows.h> 23 24 #include <WinHvPlatform.h> 24 25 … … 42 43 #include <iprt/path.h> 43 44 #include <iprt/string.h> 45 46 47 /********************************************************************************************************************************* 48 * Defined Constants And Macros * 49 *********************************************************************************************************************************/ 50 #ifdef LOG_ENABLED 51 # define NEM_WIN_INTERCEPT_NT_IO_CTLS 52 #endif 53 54 55 /********************************************************************************************************************************* 56 * Structures and Typedefs * 57 *********************************************************************************************************************************/ 58 /** @name Our two-bit physical page state for PGMPAGE 59 * @{ */ 60 #define NEM_WIN_PAGE_STATE_NOT_SET 0 61 #define NEM_WIN_PAGE_STATE_UNMAPPED 1 62 #define NEM_WIN_PAGE_STATE_READABLE 2 63 #define NEM_WIN_PAGE_STATE_WRITABLE 3 64 /** @} */ 44 65 45 66 … … 123 144 124 145 146 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 147 148 /** The real NtDeviceIoControlFile API in NTDLL. */ 149 static decltype(NtDeviceIoControlFile) *g_pfnNtDeviceIoControlFile; 150 151 /** 152 * Wrapper that logs the call from VID.DLL. 153 * 154 * This is very handy for figuring out why an API call fails. 155 */ 156 static NTSTATUS WINAPI 157 nemR3WinLogWrapper_NtDeviceIoControlFile(HANDLE hFile, HANDLE hEvt, PIO_APC_ROUTINE pfnApcCallback, PVOID pvApcCtx, 158 PIO_STATUS_BLOCK pIos, ULONG uFunction, PVOID pvInput, ULONG cbInput, 159 PVOID pvOutput, ULONG cbOutput) 160 { 161 NTSTATUS rcNt = g_pfnNtDeviceIoControlFile(hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, uFunction, 162 pvInput, cbInput, pvOutput, cbOutput); 163 if (!hEvt && !pfnApcCallback && !pvApcCtx) 164 LogRel(("VID!NtDeviceIoControlFile: hFile=%#zx pIos=%p->{s:%#x, i:%#zx} uFunction=%#x Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n", 165 hFile, pIos, pIos->Status, pIos->Information, uFunction, pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress())); 166 else 167 LogRel(("VID!NtDeviceIoControlFile: hFile=%#zx hEvt=%#zx Apc=%p/%p pIos=%p->{s:%#x, i:%#zx} uFunction=%#x Input=%p LB %#x Output=%p LB %#x) -> %#x; Caller=%p\n", 168 hFile, hEvt, pfnApcCallback, pvApcCtx, pIos, pIos->Status, pIos->Information, uFunction, 169 pvInput, cbInput, pvOutput, cbOutput, rcNt, ASMReturnAddress())); 170 return rcNt; 171 } 172 173 174 /** 175 * Patches the call table of VID.DLL so we can intercept and log 176 * NtDeviceIoControlFile. 177 * 178 * This is for DEBUGGING only. 179 * 180 * @param hLdrModVid The VID module handle. 181 */ 182 static void nemR3WinInitVidIntercepts(RTLDRMOD hLdrModVid) 183 { 184 /* 185 * Locate the real API. 186 */ 187 g_pfnNtDeviceIoControlFile = (decltype(NtDeviceIoControlFile) *)RTLdrGetSystemSymbol("NTDLL.DLL", "NtDeviceIoControlFile"); 188 AssertReturnVoid(g_pfnNtDeviceIoControlFile > 0); 189 190 /* 191 * Locate the PE header and get what we need from it. 192 */ 193 uint8_t const *pbImage = (uint8_t const *)RTLdrGetNativeHandle(hLdrModVid); 194 IMAGE_DOS_HEADER const *pMzHdr = (IMAGE_DOS_HEADER const *)pbImage; 195 AssertReturnVoid(pMzHdr->e_magic == IMAGE_DOS_SIGNATURE); 196 IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)&pbImage[pMzHdr->e_lfanew]; 197 AssertReturnVoid(pNtHdrs->Signature == IMAGE_NT_SIGNATURE); 198 199 uint32_t const cbImage = pNtHdrs->OptionalHeader.SizeOfImage; 200 IMAGE_DATA_DIRECTORY const ImportDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT]; 201 202 /* 203 * Walk the import descriptor table looking for NTDLL.DLL. 204 */ 205 bool fSuccess = true; 206 AssertReturnVoid(ImportDir.Size > 0); 207 AssertReturnVoid(ImportDir.Size < cbImage); 208 AssertReturnVoid(ImportDir.VirtualAddress > 0); 209 AssertReturnVoid(ImportDir.VirtualAddress < cbImage); 210 for (PIMAGE_IMPORT_DESCRIPTOR pImps = (PIMAGE_IMPORT_DESCRIPTOR)&pbImage[ImportDir.VirtualAddress]; 211 pImps->Name != 0 && pImps->FirstThunk != 0; 212 pImps++) 213 { 214 AssertReturnVoid(pImps->Name < cbImage); 215 const char *pszModName = (const char *)&pbImage[pImps->Name]; 216 if (RTStrICmpAscii(pszModName, "ntdll.dll")) 217 continue; 218 AssertReturnVoid(pImps->FirstThunk < cbImage); 219 AssertReturnVoid(pImps->OriginalFirstThunk < cbImage); 220 221 /* 222 * Walk the thunks table(s) looking for NtDeviceIoControlFile. 223 */ 224 PIMAGE_THUNK_DATA pFirstThunk = (PIMAGE_THUNK_DATA)&pbImage[pImps->FirstThunk]; /* update this. */ 225 PIMAGE_THUNK_DATA pThunk = pImps->OriginalFirstThunk == 0 /* read from this. */ 226 ? (PIMAGE_THUNK_DATA)&pbImage[pImps->FirstThunk] 227 : (PIMAGE_THUNK_DATA)&pbImage[pImps->OriginalFirstThunk]; 228 while (pThunk->u1.Ordinal != 0) 229 { 230 if (!(pThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG32)) 231 { 232 AssertReturnVoid(pThunk->u1.Ordinal > 0 && pThunk->u1.Ordinal < cbImage); 233 234 const char *pszSymbol = (const char *)&pbImage[(uintptr_t)pThunk->u1.AddressOfData + 2]; 235 if (strcmp(pszSymbol, "NtDeviceIoControlFile") == 0) 236 { 237 DWORD fOldProt = PAGE_EXECUTE; 238 VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), PAGE_EXECUTE_READWRITE, &fOldProt); 239 pFirstThunk->u1.Function = (uintptr_t)nemR3WinLogWrapper_NtDeviceIoControlFile; 240 VirtualProtect(&pFirstThunk->u1.Function, sizeof(uintptr_t), fOldProt, &fOldProt); 241 fSuccess = true; 242 } 243 } 244 245 pThunk++; 246 pFirstThunk++; 247 } 248 } 249 Assert(fSuccess); 250 } 251 #endif 252 253 125 254 126 255 /** … … 200 329 if (RT_SUCCESS(rc)) 201 330 { 331 #ifdef NEM_WIN_INTERCEPT_NT_IO_CTLS 332 nemR3WinInitVidIntercepts(ahMods[1]); 333 #endif 202 334 for (unsigned i = 0; i < RT_ELEMENTS(g_aImports); i++) 203 335 { … … 267 399 DWORD rcWin = GetLastError(); 268 400 if (FAILED(hrc)) 269 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc", hrc); 401 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 402 "WHvGetCapability/WHvCapabilityCodeHypervisorPresent failed: %Rhrc (Last=%#x/%u)", 403 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 270 404 if (!Caps.HypervisorPresent) 271 405 { … … 284 418 hrc = WHvGetCapability(WHvCapabilityCodeExtendedVmExits, &Caps, sizeof(Caps)); 285 419 if (FAILED(hrc)) 286 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc", hrc); 420 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 421 "WHvGetCapability/WHvCapabilityCodeExtendedVmExits failed: %Rhrc (Last=%#x/%u)", 422 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 287 423 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeExtendedVmExits", "%'#018RX64", Caps.ExtendedVmExits.AsUINT64); 288 424 pVM->nem.s.fExtendedMsrExit = RT_BOOL(Caps.ExtendedVmExits.X64MsrExit); … … 302 438 hrc = WHvGetCapability(WHvCapabilityCodeFeatures, &Caps, sizeof(Caps)); 303 439 if (FAILED(hrc)) 304 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc", hrc); 440 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 441 "WHvGetCapability/WHvCapabilityCodeFeatures failed: %Rhrc (Last=%#x/%u)", 442 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 305 443 if (Caps.Features.AsUINT64 & ~(uint64_t)0) 306 444 LogRel(("NEM: Warning! Unknown feature definitions: %#RX64\n", Caps.Features.AsUINT64)); … … 313 451 hrc = WHvGetCapability(WHvCapabilityCodeProcessorVendor, &Caps, sizeof(Caps)); 314 452 if (FAILED(hrc)) 315 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc", hrc); 453 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 454 "WHvGetCapability/WHvCapabilityCodeProcessorVendor failed: %Rhrc (Last=%#x/%u)", 455 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 316 456 switch (Caps.ProcessorVendor) 317 457 { … … 336 476 hrc = WHvGetCapability(WHvCapabilityCodeProcessorFeatures, &Caps, sizeof(Caps)); 337 477 if (FAILED(hrc)) 338 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc", hrc); 478 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 479 "WHvGetCapability/WHvCapabilityCodeProcessorFeatures failed: %Rhrc (Last=%#x/%u)", 480 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 339 481 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorFeatures", "%'#018RX64", Caps.ProcessorFeatures.AsUINT64); 340 482 #define NEM_LOG_REL_CPU_FEATURE(a_Field) NEM_LOG_REL_CAP_SUB(#a_Field, Caps.ProcessorFeatures.a_Field) … … 393 535 hrc = WHvGetCapability(WHvCapabilityCodeProcessorClFlushSize, &Caps, sizeof(Caps)); 394 536 if (FAILED(hrc)) 395 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc", hrc); 537 return RTErrInfoSetF(pErrInfo, VERR_NEM_INIT_FAILED, 538 "WHvGetCapability/WHvCapabilityCodeProcessorClFlushSize failed: %Rhrc (Last=%#x/%u)", 539 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 396 540 NEM_LOG_REL_CAP_EX("WHvCapabilityCodeProcessorClFlushSize", "2^%u", Caps.ProcessorClFlushSize); 397 541 if (Caps.ProcessorClFlushSize < 8 && Caps.ProcessorClFlushSize > 9) … … 450 594 HRESULT hrc = WHvCreatePartition(&hPartition); 451 595 if (FAILED(hrc)) 452 return RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, "WHvCreatePartition failed with %Rhrc", hrc); 596 return RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, "WHvCreatePartition failed with %Rhrc (Last=%#x/%u)", 597 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 453 598 454 599 int rc; … … 495 640 else 496 641 rc = RTErrInfoSetF(pErrInfo, VERR_NEM_VM_CREATE_FAILED, 497 "Failed setting WHvPartitionPropertyCodeProcessorCount to %u: %Rhrc", pVM->cCpus, hrc); 642 "Failed setting WHvPartitionPropertyCodeProcessorCount to %u: %Rhrc (Last=%#x/%u)", 643 pVM->cCpus, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 498 644 WHvDeletePartition(hPartition); 499 645 … … 590 736 if (FAILED(hrc)) 591 737 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 592 "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc", Property.ProcessorVendor, hrc); 738 "Failed to set WHvPartitionPropertyCodeProcessorVendor to %u: %Rhrc (Last=%#x/%u)", 739 Property.ProcessorVendor, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 593 740 594 741 /* Not sure if we really need to set the cache line flush size. */ … … 599 746 if (FAILED(hrc)) 600 747 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 601 "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc ",602 pVM->nem.s.cCacheLineFlushShift, hrc );748 "Failed to set WHvPartitionPropertyCodeProcessorClFlushSize to %u: %Rhrc (Last=%#x/%u)", 749 pVM->nem.s.cCacheLineFlushShift, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 603 750 604 751 /* … … 614 761 if (FAILED(hrc)) 615 762 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 616 "Failed to set WHvPartitionPropertyCodeProcessorFeatures to %'#RX64: %Rhrc ",617 pVM->nem.s.uCpuFeatures.u64, hrc );763 "Failed to set WHvPartitionPropertyCodeProcessorFeatures to %'#RX64: %Rhrc (Last=%#x/%u)", 764 pVM->nem.s.uCpuFeatures.u64, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 618 765 619 766 /* … … 625 772 hrc = WHvSetupPartition(hPartition); 626 773 if (FAILED(hrc)) 627 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Call to WHvSetupPartition failed: %Rhrc", hrc); 774 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 775 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", 776 hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue); 628 777 629 778 /* Get the handle. */ … … 655 804 if (FAILED(hrc)) 656 805 { 806 NTSTATUS const rcNtLast = RTNtCurrentTeb()->LastStatusValue; 807 DWORD const dwErrLast = RTNtCurrentTeb()->LastErrorValue; 657 808 while (iCpu-- > 0) 658 809 { 659 810 HRESULT hrc2 = WHvDeleteVirtualProcessor(hPartition, iCpu); 660 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc\n", hPartition, iCpu, hrc2)); 811 AssertLogRelMsg(SUCCEEDED(hrc2), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 812 hPartition, iCpu, hrc2, RTNtCurrentTeb()->LastStatusValue, 813 RTNtCurrentTeb()->LastErrorValue)); 661 814 } 662 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, "Call to WHvSetupPartition failed: %Rhrc", hrc); 815 return VMSetError(pVM, VERR_NEM_VM_CREATE_FAILED, RT_SRC_POS, 816 "Call to WHvSetupPartition failed: %Rhrc (Last=%#x/%u)", hrc, rcNtLast, dwErrLast); 663 817 } 664 818 } … … 692 846 { 693 847 HRESULT hrc = WHvDeleteVirtualProcessor(hPartition, iCpu); 694 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc\n", hPartition, iCpu, hrc)); 848 AssertLogRelMsg(SUCCEEDED(hrc), ("WHvDeleteVirtualProcessor(%p, %u) -> %Rhrc (Last=%#x/%u)\n", 849 hPartition, iCpu, hrc, RTNtCurrentTeb()->LastStatusValue, 850 RTNtCurrentTeb()->LastErrorValue)); 695 851 } 696 852 WHvDeletePartition(hPartition); … … 713 869 714 870 871 872 DECLINLINE(int) nemR3NativeGCPhys2R3PtrReadOnly(PVM pVM, RTGCPHYS GCPhys, const void **ppv) 873 { 874 PGMPAGEMAPLOCK Lock; 875 int rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys, ppv, &Lock); 876 if (RT_SUCCESS(rc)) 877 PGMPhysReleasePageMappingLock(pVM, &Lock); 878 return rc; 879 } 880 881 DECLINLINE(int) nemR3NativeGCPhys2R3PtrWriteable(PVM pVM, RTGCPHYS GCPhys, void **ppv) 882 { 883 PGMPAGEMAPLOCK Lock; 884 int rc = PGMPhysGCPhys2CCPtr(pVM, GCPhys, ppv, &Lock); 885 if (RT_SUCCESS(rc)) 886 PGMPhysReleasePageMappingLock(pVM, &Lock); 887 return rc; 888 } 889 890 715 891 int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb) 716 892 { 893 LogRel(("nemR3NativeNotifyPhysRamRegister: %RGp LB %RGp\n", GCPhys, cb)); 717 894 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 718 895 return VINF_SUCCESS; … … 720 897 721 898 722 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 723 { 899 int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2) 900 { 901 LogRel(("nemR3NativeNotifyPhysMmioExMap: %RGp LB %RGp fFlags=%#x pvMmio2=%p\n", GCPhys, cb, fFlags, pvMmio2)); 902 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); NOREF(pvMmio2); 903 return VINF_SUCCESS; 904 } 905 906 907 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 908 { 909 LogRel(("nemR3NativeNotifyPhysMmioExUnmap: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 724 910 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 725 911 return VINF_SUCCESS; … … 727 913 728 914 729 int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 730 { 915 /** 916 * Called early during ROM registration, right after the pages have been 917 * allocated and the RAM range updated. 918 * 919 * This will be succeeded by a number of NEMHCNotifyPhysPageProtChanged() calls 920 * and finally a NEMR3NotifyPhysRomRegisterEarly(). 921 * 922 * @returns VBox status code 923 * @param pVM The cross context VM structure. 924 * @param GCPhys The ROM address (page aligned). 925 * @param cb The size (page aligned). 926 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 927 */ 928 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 929 { 930 LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 931 #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. */ 932 RTGCPHYS const cPages = cb >> X86_PAGE_SHIFT; 933 for (RTGCPHYS iPage = 0; iPage < cPages; iPage++, GCPhys += X86_PAGE_SIZE) 934 { 935 const void *pvPage; 936 int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage); 937 if (RT_SUCCESS(rc)) 938 { 939 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, (void *)pvPage, GCPhys, X86_PAGE_SIZE, 940 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute); 941 if (SUCCEEDED(hrc)) 942 { /* likely */ } 943 else 944 { 945 LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 946 GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 947 return VERR_NEM_INIT_FAILED; 948 } 949 } 950 else 951 { 952 LogRel(("nemR3NativeNotifyPhysRomRegisterEarly: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc)); 953 return rc; 954 } 955 } 956 #else 957 NOREF(pVM); NOREF(GCPhys); NOREF(cb); 958 #endif 959 RT_NOREF_PV(fFlags); 960 return VINF_SUCCESS; 961 } 962 963 964 /** 965 * Called after the ROM range has been fully completed. 966 * 967 * This will be preceeded by a NEMR3NotifyPhysRomRegisterEarly() call as well a 968 * number of NEMHCNotifyPhysPageProtChanged calls. 969 * 970 * @returns VBox status code 971 * @param pVM The cross context VM structure. 972 * @param GCPhys The ROM address (page aligned). 973 * @param cb The size (page aligned). 974 * @param fFlags NEM_NOTIFY_PHYS_ROM_F_XXX. 975 */ 976 int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags) 977 { 978 LogRel(("nemR3NativeNotifyPhysRomRegisterLate: %RGp LB %RGp fFlags=%#x\n", GCPhys, cb, fFlags)); 731 979 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 732 980 return VINF_SUCCESS; … … 734 982 735 983 736 int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTUINT cb, uint32_t fFlags) 737 { 738 NOREF(pVM); NOREF(GCPhys); NOREF(cb); NOREF(fFlags); 984 void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled) 985 { 986 LogRel(("nemR3NativeNotifySetA20: fEnabled=%RTbool\n", fEnabled)); 987 NOREF(pVCpu); NOREF(fEnabled); 988 } 989 990 991 void nemR3NativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb) 992 { 993 LogRel(("nemR3NativeNotifyHandlerPhysicalRegister: %RGp LB %RGp enmKind=%d\n", GCPhys, cb, enmKind)); 994 NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); 995 } 996 997 998 void nemR3NativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb, 999 int fRestoreAsRAM, bool fRestoreAsRAM2) 1000 { 1001 LogRel(("nemR3NativeNotifyHandlerPhysicalDeregister: %RGp LB %RGp enmKind=%d fRestoreAsRAM=%d fRestoreAsRAM2=%d\n", 1002 GCPhys, cb, enmKind, fRestoreAsRAM, fRestoreAsRAM2)); 1003 NOREF(pVM); NOREF(enmKind); NOREF(GCPhys); NOREF(cb); NOREF(fRestoreAsRAM); NOREF(fRestoreAsRAM2); 1004 } 1005 1006 1007 void nemR3NativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, 1008 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM) 1009 { 1010 LogRel(("nemR3NativeNotifyHandlerPhysicalModify: %RGp LB %RGp -> %RGp enmKind=%d fRestoreAsRAM=%d\n", 1011 GCPhysOld, cb, GCPhysNew, enmKind, fRestoreAsRAM)); 1012 NOREF(pVM); NOREF(enmKind); NOREF(GCPhysOld); NOREF(GCPhysNew); NOREF(cb); NOREF(fRestoreAsRAM); 1013 } 1014 1015 1016 static int nemR3NativeSetPhysPage(PVM pVM, RTGCPHYS GCPhys, uint32_t fPageProt, uint8_t *pu2State, bool fBackingChanged) 1017 { 1018 /* 1019 * Looks like we need to unmap a page before we can change the backing 1020 * or even modify the protection. This is going to be *REALLY* efficient. 1021 * PGM lends us two bits to keep track of the state here. 1022 */ 1023 uint8_t const u2OldState = *pu2State; 1024 uint8_t const u2NewState = fPageProt & NEM_PAGE_PROT_WRITE ? NEM_WIN_PAGE_STATE_WRITABLE 1025 : fPageProt & NEM_PAGE_PROT_READ ? NEM_WIN_PAGE_STATE_READABLE : NEM_WIN_PAGE_STATE_NOT_SET; 1026 if ( fBackingChanged 1027 || u2NewState != u2OldState) 1028 { 1029 if (u2OldState > NEM_WIN_PAGE_STATE_NOT_SET) 1030 { 1031 HRESULT hrc = WHvUnmapGpaRange(pVM->nem.s.hPartition, GCPhys, X86_PAGE_SIZE); 1032 if (SUCCEEDED(hrc)) 1033 { 1034 *pu2State = NEM_WIN_PAGE_STATE_NOT_SET; 1035 if (u2NewState == NEM_WIN_PAGE_STATE_NOT_SET) 1036 return VINF_SUCCESS; 1037 } 1038 else 1039 { 1040 LogRel(("nemR3NativeSetPhysPage/unmap: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 1041 GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 1042 return VERR_NEM_INIT_FAILED; 1043 } 1044 } 1045 } 1046 1047 /* 1048 * Writeable mapping? 1049 */ 1050 if (fPageProt & NEM_PAGE_PROT_WRITE) 1051 { 1052 void *pvPage; 1053 int rc = nemR3NativeGCPhys2R3PtrWriteable(pVM, GCPhys, &pvPage); 1054 if (RT_SUCCESS(rc)) 1055 { 1056 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, pvPage, GCPhys, X86_PAGE_SIZE, 1057 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute | WHvMapGpaRangeFlagWrite); 1058 if (SUCCEEDED(hrc)) 1059 { 1060 *pu2State = NEM_WIN_PAGE_STATE_WRITABLE; 1061 return VINF_SUCCESS; 1062 } 1063 LogRel(("nemR3NativeSetPhysPage/writable: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 1064 GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 1065 return VERR_NEM_INIT_FAILED; 1066 } 1067 LogRel(("nemR3NativeSetPhysPage/writable: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc)); 1068 return rc; 1069 } 1070 1071 if (fPageProt & NEM_PAGE_PROT_READ) 1072 { 1073 const void *pvPage; 1074 int rc = nemR3NativeGCPhys2R3PtrReadOnly(pVM, GCPhys, &pvPage); 1075 if (RT_SUCCESS(rc)) 1076 { 1077 HRESULT hrc = WHvMapGpaRange(pVM->nem.s.hPartition, (void *)pvPage, GCPhys, X86_PAGE_SIZE, 1078 WHvMapGpaRangeFlagRead | WHvMapGpaRangeFlagExecute); 1079 if (SUCCEEDED(hrc)) 1080 { 1081 *pu2State = NEM_WIN_PAGE_STATE_READABLE; 1082 return VINF_SUCCESS; 1083 } 1084 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhys=%RGp hrc=%Rhrc (%#x) Last=%#x/%u\n", 1085 GCPhys, hrc, hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue)); 1086 return VERR_NEM_INIT_FAILED; 1087 } 1088 LogRel(("nemR3NativeSetPhysPage/readonly: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc)); 1089 return rc; 1090 } 1091 1092 /* We already unmapped it above. */ 1093 *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED; 739 1094 return VINF_SUCCESS; 740 1095 } 741 1096 742 1097 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 1098 int nemR3NativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt, 1099 PGMPAGETYPE enmType, uint8_t *pu2State) 1100 { 1101 LogRel(("nemR3NativeNotifyPhysPageAllocated: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 1102 GCPhys, HCPhys, fPageProt, enmType, *pu2State)); 1103 RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType); 1104 1105 return nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); 1106 } 1107 1108 1109 void nemR3NativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt, 1110 PGMPAGETYPE enmType, uint8_t *pu2State) 1111 { 1112 LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 1113 GCPhys, HCPhys, fPageProt, enmType, *pu2State)); 1114 RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType); 1115 1116 nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, false /*fBackingChanged*/); 1117 } 1118 1119 1120 void nemR3NativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, 1121 uint32_t fPageProt, PGMPAGETYPE enmType, uint8_t *pu2State) 1122 { 1123 LogRel(("nemR3NativeNotifyPhysPageProtChanged: %RGp HCPhys=%RHp->%RHp fPageProt=%#x enmType=%d *pu2State=%d\n", 1124 GCPhys, HCPhysPrev, HCPhysNew, fPageProt, enmType, *pu2State)); 1125 RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType); 1126 1127 nemR3NativeSetPhysPage(pVM, GCPhys, fPageProt, pu2State, true /*fBackingChanged*/); 1128 } 1129 -
trunk/src/VBox/VMM/VMMR3/PGMHandler.cpp
r70948 r70977 268 268 int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint); 269 269 if (RT_SUCCESS(rc)) 270 { 270 271 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_NONE); 272 273 /* Tell NEM about the protection change. */ 274 if (VM_IS_NEM_ENABLED(pVM)) 275 { 276 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 277 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 278 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 279 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 280 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 281 } 282 } 271 283 else 272 284 AssertRC(rc); … … 300 312 int rc = pgmPhysGetPageWithHintEx(pVM, GCPhys, &pPage, &pRamHint); 301 313 if (RT_SUCCESS(rc)) 314 { 302 315 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState); 316 317 /* Tell NEM about the protection change. */ 318 if (VM_IS_NEM_ENABLED(pVM)) 319 { 320 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 321 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage); 322 NEMHCNotifyPhysPageProtChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pPage), 323 pgmPhysPageCalcNemProtection(pPage, enmType), enmType, &u2State); 324 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 325 } 326 } 303 327 else 304 328 AssertRC(rc); -
trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp
r70954 r70977 288 288 if ( PGM_PAGE_GET_STATE(pPage) == PGM_PAGE_STATE_WRITE_MONITORED 289 289 && !PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage)) 290 pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage );290 pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage, GCPhys); 291 291 else 292 292 { … … 474 474 #endif 475 475 ) 476 pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage );476 pgmPhysPageMakeWriteMonitoredWritable(pVM, pPage, GCPhys); 477 477 else 478 478 { … … 895 895 * @param GCPhys The address of the first page. 896 896 * @param GCPhysLast The address of the last page. 897 * @param uTypeThe page type to replace then with.898 */ 899 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, uint8_t uType)897 * @param enmType The page type to replace then with. 898 */ 899 static int pgmR3PhysFreePageRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, RTGCPHYS GCPhysLast, PGMPAGETYPE enmType) 900 900 { 901 901 PGM_LOCK_ASSERT_OWNER(pVM); … … 910 910 while (cPagesLeft-- > 0) 911 911 { 912 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys );912 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPageDst, GCPhys, enmType); 913 913 AssertLogRelRCReturn(rc, rc); /* We're done for if this goes wrong. */ 914 914 915 PGM_PAGE_SET_TYPE(pVM, pPageDst, uType);915 PGM_PAGE_SET_TYPE(pVM, pPageDst, enmType); 916 916 917 917 GCPhys += PAGE_SIZE; … … 985 985 pgmPoolFlushPageByGCPhys(pVM, paPhysPage[i]); 986 986 987 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i] );987 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, paPhysPage[i], (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage)); 988 988 if (RT_FAILURE(rc)) 989 989 { … … 1020 1020 Assert(PGM_PAGE_IS_BALLOONED(pPage)); 1021 1021 1022 /* Change back to zero page. */1022 /* Change back to zero page. (NEM does not need to be informed.) */ 1023 1023 PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ZERO); 1024 1024 } … … 1854 1854 if (PGM_PAGE_IS_SHARED(pPage)) 1855 1855 { 1856 uint32_t u32Checksum = pPage->s.u2Unused0 | ((uint32_t)pPage->s.u2Unused1 << 8);1856 uint32_t u32Checksum = pPage->s.u2Unused0/* | ((uint32_t)pPage->s.u2Unused1 << 8)*/; 1857 1857 if (!u32Checksum) 1858 1858 { … … 1864 1864 uint32_t u32Checksum2 = RTCrc32(pvPage, PAGE_SIZE); 1865 1865 # if 0 1866 AssertMsg((u32Checksum2 & UINT32_C(0x00000303)) == u32Checksum, ("GCPhysPage=%RGp\n", GCPhysPage));1866 AssertMsg((u32Checksum2 & /*UINT32_C(0x00000303)*/ 0x3) == u32Checksum, ("GCPhysPage=%RGp\n", GCPhysPage)); 1867 1867 # else 1868 if ((u32Checksum2 & UINT32_C(0x00000303)) == u32Checksum)1868 if ((u32Checksum2 & /*UINT32_C(0x00000303)*/ 0x3) == u32Checksum) 1869 1869 LogFlow(("shpg %#x @ %RGp %#x [OK]\n", PGM_PAGE_GET_PAGEID(pPage), GCPhysPage, u32Checksum2)); 1870 1870 else … … 1974 1974 else if (!PGM_PAGE_IS_ZERO(pPage)) 1975 1975 { 1976 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 1976 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), 1977 PGMPAGETYPE_RAM); 1977 1978 AssertLogRelRCReturn(rc, rc); 1978 1979 } … … 2123 2124 if (PGM_PAGE_IS_SHARED(pPage)) 2124 2125 { 2125 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT)); 2126 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), 2127 PGMPAGETYPE_RAM); 2126 2128 AssertLogRelRCReturn(rc, rc); 2127 2129 } … … 3389 3391 PGM_PAGE_SET_PTE_INDEX(pVM, pPageDst, 0); 3390 3392 PGM_PAGE_SET_TRACKING(pVM, pPageDst, 0); 3393 /* (We tell NEM at the end of the function.) */ 3391 3394 3392 3395 pVM->pgm.s.cZeroPages--; … … 3516 3519 uint32_t const fNemNotify = (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2 ? NEM_NOTIFY_PHYS_MMIO_EX_F_MMIO2 : 0) 3517 3520 | (pFirstMmio->fFlags & PGMREGMMIORANGE_F_OVERLAPPING ? NEM_NOTIFY_PHYS_MMIO_EX_F_REPLACE : 0); 3518 int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify); 3521 int rc = NEMR3NotifyPhysMmioExMap(pVM, GCPhys, cbRange, fNemNotify, pFirstMmio->pvR3); 3522 3519 3523 pgmUnlock(pVM); 3524 3520 3525 #ifdef VBOX_WITH_REM 3521 3526 if (!fRamExists && (pFirstMmio->fFlags & PGMREGMMIORANGE_F_MMIO2)) /** @todo this doesn't look right. */ … … 3899 3904 * @param pszDesc Pointer to description string. This must not be freed. 3900 3905 */ 3901 static int pgmR3PhysRomRegister (PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb,3902 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc)3906 static int pgmR3PhysRomRegisterLocked(PVM pVM, PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPHYS cb, 3907 const void *pvBinary, uint32_t cbBinary, uint32_t fFlags, const char *pszDesc) 3903 3908 { 3904 3909 /* … … 4270 4275 pDevIns, GCPhys, GCPhys + cb, cb, pvBinary, cbBinary, fFlags, pszDesc)); 4271 4276 pgmLock(pVM); 4272 int rc = pgmR3PhysRomRegister (pVM, pDevIns, GCPhys, cb, pvBinary, cbBinary, fFlags, pszDesc);4277 int rc = pgmR3PhysRomRegisterLocked(pVM, pDevIns, GCPhys, cb, pvBinary, cbBinary, fFlags, pszDesc); 4273 4278 pgmUnlock(pVM); 4274 4279 return rc; … … 4315 4320 4316 4321 for (uint32_t iPage = 0; iPage < cPages; iPage++) 4317 if ( 4318 && 4322 if ( !PGM_PAGE_IS_ZERO(&pRom->aPages[iPage].Shadow) 4323 && !PGM_PAGE_IS_BALLOONED(&pRom->aPages[iPage].Shadow)) 4319 4324 { 4320 4325 Assert(PGM_PAGE_GET_STATE(&pRom->aPages[iPage].Shadow) == PGM_PAGE_STATE_ALLOCATED); 4321 4326 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, &pRom->aPages[iPage].Shadow, 4322 pRom->GCPhys + (iPage << PAGE_SHIFT)); 4327 pRom->GCPhys + (iPage << PAGE_SHIFT), 4328 (PGMPAGETYPE)PGM_PAGE_GET_TYPE(&pRom->aPages[iPage].Shadow)); 4323 4329 AssertLogRelRCReturn(rc, rc); 4324 4330 } … … 4457 4463 for (PPGMROMRANGE pRom = pVM->pgm.s.pRomRangesR3; pRom; pRom = pRom->pNextR3) 4458 4464 { 4459 if ( 4460 && 4461 && 4465 if ( GCPhys <= pRom->GCPhysLast 4466 && GCPhysLast >= pRom->GCPhys 4467 && (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED)) 4462 4468 { 4463 4469 /* … … 4483 4489 if (rc2 != VINF_SUCCESS && (rc == VINF_SUCCESS || RT_FAILURE(rc2))) 4484 4490 rc = rc2; 4491 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pRamPage); 4485 4492 4486 4493 PPGMPAGE pOld = PGMROMPROT_IS_ROM(pRomPage->enmProt) ? &pRomPage->Virgin : &pRomPage->Shadow; … … 4490 4497 *pRamPage = *pNew; 4491 4498 /** @todo preserve the volatile flags (handlers) when these have been moved out of HCPhys! */ 4499 4500 /* Tell NEM about the backing and protection change. */ 4501 if (VM_IS_NEM_ENABLED(pVM)) 4502 { 4503 PGMPAGETYPE enmType = (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pNew); 4504 NEMHCNotifyPhysPageChanged(pVM, GCPhys, PGM_PAGE_GET_HCPHYS(pOld), PGM_PAGE_GET_HCPHYS(pNew), 4505 pgmPhysPageCalcNemProtection(pRamPage, enmType), enmType, &u2State); 4506 PGM_PAGE_SET_NEM_STATE(pRamPage, u2State); 4507 } 4492 4508 } 4493 4509 pRomPage->enmProt = enmProt; … … 5247 5263 * @param pPage Pointer to the page structure. 5248 5264 * @param GCPhys The guest physical address of the page, if applicable. 5265 * @param enmNewType New page type for NEM notification, since several 5266 * callers will change the type upon successful return. 5249 5267 * 5250 5268 * @remarks The caller must own the PGM lock. 5251 5269 */ 5252 int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys) 5270 int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys, 5271 PGMPAGETYPE enmNewType) 5253 5272 { 5254 5273 /* … … 5280 5299 return VMSetError(pVM, VERR_PGM_PHYS_INVALID_PAGE_ID, RT_SRC_POS, "GCPhys=%RGp idPage=%#x", GCPhys, pPage); 5281 5300 } 5301 const RTHCPHYS HCPhysPrev = PGM_PAGE_GET_HCPHYS(pPage); 5282 5302 5283 5303 /* update page count stats. */ … … 5307 5327 /* Flush physical page map TLB entry. */ 5308 5328 pgmPhysInvalidatePageMapTLBEntry(pVM, GCPhys); 5329 5330 /* Notify NEM. */ 5331 /** @todo consider doing batch NEM notifications. */ 5332 if (VM_IS_NEM_ENABLED(pVM)) 5333 { 5334 uint8_t u2State = PGM_PAGE_GET_NEM_STATE(pPage); 5335 NEMHCNotifyPhysPageChanged(pVM, GCPhys, HCPhysPrev, pVM->pgm.s.HCPhysZeroPg, 5336 pgmPhysPageCalcNemProtection(pPage, enmNewType), enmNewType, &u2State); 5337 PGM_PAGE_SET_NEM_STATE(pPage, u2State); 5338 } 5309 5339 5310 5340 /* -
trunk/src/VBox/VMM/VMMR3/PGMSavedState.cpp
r69111 r70977 2739 2739 && PGM_PAGE_GET_PDE_TYPE(pPage) != PGM_PAGE_PDE_TYPE_PDE_DISABLED) 2740 2740 { 2741 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys );2741 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys, (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage)); 2742 2742 AssertRCReturn(rc, rc); 2743 2743 } … … 2762 2762 ("GCPhys=%RGp %R[pgmpage]\n", GCPhys, pPage), VERR_PGM_LOAD_UNEXPECTED_PAGE_TYPE); 2763 2763 2764 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys );2764 rc = pgmPhysFreePage(pVM, pReq, &cPendingPages, pPage, GCPhys, (PGMPAGETYPE)PGM_PAGE_GET_TYPE(pPage)); 2765 2765 AssertRCReturn(rc, rc); 2766 2766 }
Note:
See TracChangeset
for help on using the changeset viewer.