Changeset 21994 in vbox for trunk/src/VBox/VMM/PGM.cpp
- Timestamp:
- Aug 5, 2009 12:44:59 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGM.cpp
r21928 r21994 589 589 #include <VBox/selm.h> 590 590 #include <VBox/ssm.h> 591 #include <VBox/hwaccm.h> 591 592 #include "PGMInternal.h" 592 593 #include <VBox/vm.h> 594 593 595 #include <VBox/dbg.h> 594 #include <VBox/hwaccm.h>595 596 #include <iprt/assert.h>597 #include <iprt/alloc.h>598 #include <iprt/asm.h>599 #include <iprt/thread.h>600 #include <iprt/string.h>601 #ifdef DEBUG_bird602 # include <iprt/env.h>603 #endif604 596 #include <VBox/param.h> 605 597 #include <VBox/err.h> 598 599 #include <iprt/asm.h> 600 #include <iprt/assert.h> 601 #include <iprt/env.h> 602 #include <iprt/mem.h> 603 #include <iprt/file.h> 604 #include <iprt/string.h> 605 #include <iprt/thread.h> 606 606 607 607 … … 649 649 static DECLCALLBACK(int) pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 650 650 # endif 651 static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 651 652 #endif 652 653 … … 663 664 }; 664 665 666 static const DBGCVARDESC g_aPgmPhysToFileArgs[] = 667 { 668 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 669 { 1, 1, DBGCVAR_CAT_STRING, 0, "file", "The file name." }, 670 { 0, 1, DBGCVAR_CAT_STRING, 0, "nozero", "If present, zero pages are skipped." }, 671 }; 672 665 673 /** Command descriptors. */ 666 674 static const DBGCCMD g_aCmds[] = 667 675 { 668 /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */ 669 { "pgmram", 0, 0, NULL, 0, NULL, 0, pgmR3CmdRam, "", "Display the ram ranges." }, 670 { "pgmmap", 0, 0, NULL, 0, NULL, 0, pgmR3CmdMap, "", "Display the mapping ranges." }, 671 { "pgmsync", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSync, "", "Sync the CR3 page." }, 672 { "pgmerror", 0, 1, &g_aPgmErrorArgs[0],1, NULL, 0, pgmR3CmdError, "", "Enables inject runtime of errors into parts of PGM." }, 673 { "pgmerroroff", 0, 1, &g_aPgmErrorArgs[0],1, NULL, 0, pgmR3CmdError, "", "Disables inject runtime errors into parts of PGM." }, 674 #ifdef VBOX_STRICT 675 { "pgmassertcr3", 0, 0, NULL, 0, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." }, 676 #endif 677 { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." }, 676 /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */ 677 { "pgmram", 0, 0, NULL, 0, NULL, 0, pgmR3CmdRam, "", "Display the ram ranges." }, 678 { "pgmmap", 0, 0, NULL, 0, NULL, 0, pgmR3CmdMap, "", "Display the mapping ranges." }, 679 { "pgmsync", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSync, "", "Sync the CR3 page." }, 680 { "pgmerror", 0, 1, &g_aPgmErrorArgs[0], 1, NULL, 0, pgmR3CmdError, "", "Enables inject runtime of errors into parts of PGM." }, 681 { "pgmerroroff", 0, 1, &g_aPgmErrorArgs[0], 1, NULL, 0, pgmR3CmdError, "", "Disables inject runtime errors into parts of PGM." }, 682 #ifdef VBOX_STRICT 683 { "pgmassertcr3", 0, 0, NULL, 0, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." }, 684 #endif 685 { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." }, 686 { "pgmphystofile", 1, 2, &g_aPgmPhysToFileArgs[0], 2, NULL, 0, pgmR3CmdPhysToFile, "", "Save the physical memory to file." }, 678 687 }; 679 688 #endif … … 4960 4969 } 4961 4970 4971 4972 /** 4973 * The '.pgmsyncalways' command. 4974 * 4975 * @returns VBox status. 4976 * @param pCmd Pointer to the command descriptor (as registered). 4977 * @param pCmdHlp Pointer to command helper functions. 4978 * @param pVM Pointer to the current VM (if any). 4979 * @param paArgs Pointer to (readonly) array of arguments. 4980 * @param cArgs Number of arguments in the array. 4981 */ 4982 static DECLCALLBACK(int) pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult) 4983 { 4984 /* 4985 * Validate input. 4986 */ 4987 if (!pVM) 4988 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires a VM to be selected.\n"); 4989 if ( cArgs < 1 4990 || cArgs > 2 4991 || paArgs[0].enmType != DBGCVAR_TYPE_STRING 4992 || ( cArgs > 1 4993 && paArgs[1].enmType != DBGCVAR_TYPE_STRING)) 4994 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: parser error, invalid arguments.\n"); 4995 if ( cArgs >= 2 4996 && strcmp(paArgs[1].u.pszString, "nozero")) 4997 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid 2nd argument '%s', must be 'nozero'.\n", paArgs[1].u.pszString); 4998 bool fIncZeroPgs = cArgs < 2; 4999 5000 /* 5001 * Open the output file and get the ram parameters. 5002 */ 5003 RTFILE hFile; 5004 int rc = RTFileOpen(&hFile, paArgs[0].u.pszString, RTFILE_O_WRITE | RTFILE_O_CREATE_REPLACE | RTFILE_O_DENY_WRITE); 5005 if (RT_FAILURE(rc)) 5006 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: RTFileOpen(,'%s',) -> %Rrc.\n", paArgs[0].u.pszString, rc); 5007 5008 uint32_t cbRamHole = 0; 5009 CFGMR3QueryU32Def(CFGMR3GetRoot(pVM), "RamHoleSize", &cbRamHole, MM_RAM_HOLE_SIZE_DEFAULT); 5010 uint64_t cbRam = 0; 5011 CFGMR3QueryU64Def(CFGMR3GetRoot(pVM), "RamSize", &cbRam, 0); 5012 RTGCPHYS GCPhysEnd = cbRam + cbRamHole; 5013 5014 /* 5015 * Dump the physical memory, page by page. 5016 */ 5017 RTGCPHYS GCPhys = 0; 5018 char abZeroPg[PAGE_SIZE]; 5019 RT_ZERO(abZeroPg); 5020 5021 pgmLock(pVM); 5022 for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; 5023 pRam && pRam->GCPhys < GCPhysEnd && RT_SUCCESS(rc); 5024 pRam = pRam->pNextR3) 5025 { 5026 /* fill the gap */ 5027 if (pRam->GCPhys > GCPhys && fIncZeroPgs) 5028 { 5029 while (pRam->GCPhys > GCPhys && RT_SUCCESS(rc)) 5030 { 5031 rc = RTFileWrite(hFile, abZeroPg, PAGE_SIZE, NULL); 5032 GCPhys += PAGE_SIZE; 5033 } 5034 } 5035 5036 PCPGMPAGE pPage = &pRam->aPages[0]; 5037 while (GCPhys < pRam->GCPhysLast && RT_SUCCESS(rc)) 5038 { 5039 if (PGM_PAGE_IS_ZERO(pPage)) 5040 { 5041 if (fIncZeroPgs) 5042 { 5043 rc = RTFileWrite(hFile, abZeroPg, PAGE_SIZE, NULL); 5044 if (RT_FAILURE(rc)) 5045 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: RTFileWrite -> %Rrc at GCPhys=%RGp.\n", rc, GCPhys); 5046 } 5047 } 5048 else 5049 { 5050 switch (PGM_PAGE_GET_TYPE(pPage)) 5051 { 5052 case PGMPAGETYPE_RAM: 5053 case PGMPAGETYPE_ROM_SHADOW: /* trouble?? */ 5054 case PGMPAGETYPE_ROM: 5055 case PGMPAGETYPE_MMIO2: 5056 { 5057 void const *pvPage; 5058 PGMPAGEMAPLOCK Lock; 5059 rc = PGMPhysGCPhys2CCPtrReadOnly(pVM, GCPhys, &pvPage, &Lock); 5060 if (RT_SUCCESS(rc)) 5061 { 5062 rc = RTFileWrite(hFile, pvPage, PAGE_SIZE, NULL); 5063 PGMPhysReleasePageMappingLock(pVM, &Lock); 5064 if (RT_FAILURE(rc)) 5065 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: RTFileWrite -> %Rrc at GCPhys=%RGp.\n", rc, GCPhys); 5066 } 5067 else 5068 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: PGMPhysGCPhys2CCPtrReadOnly -> %Rrc at GCPhys=%RGp.\n", rc, GCPhys); 5069 break; 5070 } 5071 5072 default: 5073 AssertFailed(); 5074 case PGMPAGETYPE_MMIO2_ALIAS_MMIO: 5075 case PGMPAGETYPE_MMIO: 5076 if (fIncZeroPgs) 5077 { 5078 rc = RTFileWrite(hFile, abZeroPg, PAGE_SIZE, NULL); 5079 if (RT_FAILURE(rc)) 5080 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: RTFileWrite -> %Rrc at GCPhys=%RGp.\n", rc, GCPhys); 5081 } 5082 break; 5083 } 5084 } 5085 5086 5087 /* advance */ 5088 GCPhys += PAGE_SIZE; 5089 pPage++; 5090 } 5091 } 5092 pgmUnlock(pVM); 5093 5094 RTFileClose(hFile); 5095 if (RT_SUCCESS(rc)) 5096 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Successfully saved physical memory to '%s'.\n", paArgs[0].u.pszString); 5097 return VINF_SUCCESS; 5098 } 5099 4962 5100 #endif /* VBOX_WITH_DEBUGGER */ 4963 5101
Note:
See TracChangeset
for help on using the changeset viewer.