Changeset 18617 in vbox
- Timestamp:
- Apr 1, 2009 10:11:29 PM (15 years ago)
- Location:
- trunk
- Files:
-
- 16 edited
-
include/VBox/param.h (modified) (3 diffs)
-
include/VBox/vm.h (modified) (3 diffs)
-
src/VBox/VMM/EM.cpp (modified) (40 diffs)
-
src/VBox/VMM/PGM.cpp (modified) (4 diffs)
-
src/VBox/VMM/PGMInternal.h (modified) (2 diffs)
-
src/VBox/VMM/PGMPhys.cpp (modified) (6 diffs)
-
src/VBox/VMM/TRPM.cpp (modified) (1 diff)
-
src/VBox/VMM/VMM.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/PGMAllBth.h (modified) (7 diffs)
-
src/VBox/VMM/VMMAll/PGMAllPhys.cpp (modified) (2 diffs)
-
src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp (modified) (4 diffs)
-
src/VBox/VMM/VMMR0/GMMR0.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR0/HWSVMR0.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR0/HWVMXR0.cpp (modified) (1 diff)
-
src/VBox/VMM/VMMR0/PGMR0.cpp (modified) (2 diffs)
-
src/VBox/VMM/testcase/tstVMStructGC.cpp (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/param.h
r18263 r18617 48 48 * @{ 49 49 */ 50 51 50 /** Initial address of Hypervisor Memory Area. 52 51 * MUST BE PAGE TABLE ALIGNED! */ … … 79 78 /** The default size of the below 4GB RAM hole. */ 80 79 #define MM_RAM_HOLE_SIZE_DEFAULT (512U * _1M) 80 /** @} */ 81 81 82 83 /** @defgroup grp_vbox_param_pgm Page Manager Parameters 84 * @ingroup grp_vbox_param 85 * @{ 86 */ 87 /** The number of handy pages. 88 * This should be a power of two. */ 89 #define PGM_HANDY_PAGES 128 90 /** The threshold at which allocation of more handy pages is flagged. */ 91 #define PGM_HANDY_PAGES_SET_FF 32 92 /** The threshold at which we will allocate more when in ring-3. 93 * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and 94 * PGM_HANDY_PAGES_MIN. */ 95 #define PGM_HANDY_PAGES_R3_ALLOC 8 96 /** The threshold at which we will allocate more when in ring-0 or raw mode. 97 * The idea is that we should never go below this threshold while in ring-0 or 98 * raw mode because of PGM_HANDY_PAGES_RZ_TO_R3. However, should this happen and 99 * we are actually out of memory, we will have 8 page to get out of whatever 100 * code we're executing. 101 * 102 * This is must be smaller than both PGM_HANDY_PAGES_SET_FF and 103 * PGM_HANDY_PAGES_MIN. */ 104 #define PGM_HANDY_PAGES_RZ_ALLOC 8 105 /** The threshold at which we force return to R3 ASAP. 106 * The idea is that this should be large enough to get out of any code and up to 107 * the main EM loop when we are out of memory. 108 * This must be less or equal to PGM_HANDY_PAGES_MIN. */ 109 #define PGM_HANDY_PAGES_RZ_TO_R3 24 110 /** The minimum number of handy pages (after allocation). 111 * This must be greater or equal to PGM_HANDY_PAGES_SET_FF. 112 * Another name would be PGM_HANDY_PAGES_EXTRA_RESERVATION or _PARANOIA. :-) */ 113 #define PGM_HANDY_PAGES_MIN 32 82 114 /** @} */ 83 115 … … 87 119 * @{ 88 120 */ 89 90 121 /** VMM stack size. */ 91 122 #define VMM_STACK_SIZE 8192U 92 93 123 /** @} */ 94 124 -
trunk/include/VBox/vm.h
r17546 r18617 211 211 /** PGM needs to allocate handy pages. */ 212 212 #define VM_FF_PGM_NEED_HANDY_PAGES RT_BIT_32(18) 213 /** PGM is out of memory. 214 * Abandon all loops and code paths which can be resumed and get up to the EM 215 * loops. */ 216 #define VM_FF_PGM_NO_MEMORY RT_BIT_32(19) 213 217 /** Check the interupt and trap gates */ 214 #define VM_FF_TRPM_SYNC_IDT RT_BIT_32( 19)218 #define VM_FF_TRPM_SYNC_IDT RT_BIT_32(20) 215 219 /** Check Guest's TSS ring 0 stack */ 216 #define VM_FF_SELM_SYNC_TSS RT_BIT_32(2 0)220 #define VM_FF_SELM_SYNC_TSS RT_BIT_32(21) 217 221 /** Check Guest's GDT table */ 218 #define VM_FF_SELM_SYNC_GDT RT_BIT_32(2 1)222 #define VM_FF_SELM_SYNC_GDT RT_BIT_32(22) 219 223 /** Check Guest's LDT table */ 220 #define VM_FF_SELM_SYNC_LDT RT_BIT_32(2 2)224 #define VM_FF_SELM_SYNC_LDT RT_BIT_32(23) 221 225 /** Inhibit interrupts pending. See EMGetInhibitInterruptsPC(). */ 222 #define VM_FF_INHIBIT_INTERRUPTS RT_BIT_32(2 3)226 #define VM_FF_INHIBIT_INTERRUPTS RT_BIT_32(24) 223 227 224 228 /** CSAM needs to scan the page that's being executed */ 225 #define VM_FF_CSAM_SCAN_PAGE RT_BIT_32(2 4)229 #define VM_FF_CSAM_SCAN_PAGE RT_BIT_32(26) 226 230 /** CSAM needs to do some homework. */ 227 #define VM_FF_CSAM_PENDING_ACTION RT_BIT_32(2 5)231 #define VM_FF_CSAM_PENDING_ACTION RT_BIT_32(27) 228 232 229 233 /** Force return to Ring-3. */ … … 242 246 /** High priority pre-execution actions. */ 243 247 #define VM_FF_HIGH_PRIORITY_PRE_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_TIMER | VM_FF_DEBUG_SUSPEND \ 244 | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES )248 | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY) 245 249 /** High priority pre raw-mode execution mask. */ 246 #define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_PGM_NEED_HANDY_PAGES\247 | VM_FF_INHIBIT_INTERRUPTS)250 #define VM_FF_HIGH_PRIORITY_PRE_RAW_MASK (VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT \ 251 | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NO_MEMORY) 248 252 /** High priority post-execution actions. */ 249 #define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION )253 #define VM_FF_HIGH_PRIORITY_POST_MASK (VM_FF_PDM_CRITSECT | VM_FF_CSAM_PENDING_ACTION | VM_FF_PGM_NO_MEMORY) 250 254 /** Normal priority post-execution actions. */ 251 #define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE )255 #define VM_FF_NORMAL_PRIORITY_POST_MASK (VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE | VM_FF_PGM_NO_MEMORY) 252 256 /** Normal priority actions. */ 253 257 #define VM_FF_NORMAL_PRIORITY_MASK (VM_FF_REQUEST | VM_FF_PDM_QUEUES | VM_FF_PDM_DMA | VM_FF_REM_HANDLER_NOTIFY) 254 /** Flags to c heckbefore resuming guest execution. */258 /** Flags to clear before resuming guest execution. */ 255 259 #define VM_FF_RESUME_GUEST_MASK (VM_FF_TO_R3) 260 /** Flags that causes the HWACCM loops to go back to ring-3. */ 261 #define VM_FF_HWACCM_TO_R3_MASK (VM_FF_TO_R3 | VM_FF_TIMER | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY) 256 262 /** All the forced flags. */ 257 263 #define VM_FF_ALL_MASK (~0U) 258 264 /** All the forced flags. */ 259 #define VM_FF_ALL_BUT_RAW_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT) )265 #define VM_FF_ALL_BUT_RAW_MASK (~(VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_CSAM_PENDING_ACTION | VM_FF_PDM_CRITSECT) | VM_FF_PGM_NO_MEMORY) 260 266 261 267 /** @} */ … … 357 363 #else 358 364 # define VMCPU_FF_ISPENDING(pVM, idCpu, fFlags) VM_FF_ISPENDING(pVM, fFlags) 365 #endif 366 367 /** @def VM_FF_ISPENDING 368 * Checks if one or more force action in the specified set is pending while one 369 * or more other ones are not. 370 * 371 * @param pVM VM Handle. 372 * @param fFlags The flags to check for. 373 * @param fExcpt The flags that should not be set. 374 */ 375 #define VM_FF_IS_PENDING_EXCEPT(pVM, fFlags, fExcpt) ( ((pVM)->fForcedActions & (fFlags)) && !((pVM)->fForcedActions & (fExcpt)) ) 376 377 /** @def VMCPU_FF_IS_PENDING_EXCEPT 378 * Checks if one or more force action in the specified set is pending for given 379 * VCPU while one or more other ones are not. 380 * 381 * @param pVM VM Handle. 382 * @param idCpu Virtual CPU ID. 383 * @param fFlags The flags to check for. 384 * @param fExcpt The flags that should not be set. 385 */ 386 #ifdef VBOX_WITH_SMP_GUESTS 387 # define VMCPU_FF_IS_PENDING_EXCEPT(pVM, idCpu, fFlags, fExcpt) ( ((pVM)->aCpu[idCpu].fForcedActions & (fFlags)) && !((pVM)->aCpu[idCpu].fForcedActions & (fExcpt)) ) 388 #else 389 # define VMCPU_FF_IS_PENDING_EXCEPT(pVM, idCpu, fFlags, fExcpt) VM_FF_ISPENDING(pVM, fFlags, fExcpt) 359 390 #endif 360 391 -
trunk/src/VBox/VMM/EM.cpp
r18343 r18617 755 755 case VINF_EM_OFF: 756 756 case VINF_EM_RESET: 757 case VINF_EM_NO_MEMORY: 757 758 case VINF_EM_RAW_STALE_SELECTOR: 758 759 case VINF_EM_RAW_IRET_TRAP: … … 1016 1017 { 1017 1018 rc = emR3RawForcedActions(pVM, pCtx); 1018 if ( RT_FAILURE(rc))1019 if (rc != VINF_SUCCESS) 1019 1020 return rc; 1020 1021 } … … 1090 1091 { 1091 1092 rc = emR3RawForcedActions(pVM, pCtx); 1092 if ( RT_FAILURE(rc))1093 if (rc != VINF_SUCCESS) 1093 1094 return rc; 1094 1095 } … … 1125 1126 1126 1127 1127 voidemR3SingleStepExecRaw(PVM pVM, uint32_t cIterations)1128 int emR3SingleStepExecRaw(PVM pVM, uint32_t cIterations) 1128 1129 { 1129 EMSTATE enmOldState = pVM->em.s.enmState;1130 1131 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW;1130 int rc = VINF_SUCCESS; 1131 EMSTATE enmOldState = pVM->em.s.enmState; 1132 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_RAW; 1132 1133 1133 1134 Log(("Single step BEGIN:\n")); … … 1136 1137 DBGFR3PrgStep(pVM); 1137 1138 DBGFR3DisasInstrCurrentLog(pVM, "RSS: "); 1138 emR3RawStep(pVM); 1139 } 1140 Log(("Single step END:\n")); 1139 rc = emR3RawStep(pVM); 1140 if (rc != VINF_SUCCESS) 1141 break; 1142 } 1143 Log(("Single step END: rc=%Rrc\n", rc)); 1141 1144 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF); 1142 1145 pVM->em.s.enmState = enmOldState; 1146 return rc; 1143 1147 } 1144 1148 … … 1146 1150 static int emR3SingleStepExecHwAcc(PVM pVM, RTCPUID idCpu, uint32_t cIterations) 1147 1151 { 1148 EMSTATE enmOldState = pVM->em.s.enmState;1149 1150 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_HWACC;1152 int rc = VINF_SUCCESS; 1153 EMSTATE enmOldState = pVM->em.s.enmState; 1154 pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_HWACC; 1151 1155 1152 1156 Log(("Single step BEGIN:\n")); … … 1155 1159 DBGFR3PrgStep(pVM); 1156 1160 DBGFR3DisasInstrCurrentLog(pVM, "RSS: "); 1157 emR3HwAccStep(pVM, idCpu); 1158 if (!HWACCMR3CanExecuteGuest(pVM, pVM->em.s.pCtx)) 1159 break; 1160 } 1161 Log(("Single step END:\n")); 1161 rc = emR3HwAccStep(pVM, idCpu); 1162 if ( rc != VINF_SUCCESS 1163 || !HWACCMR3CanExecuteGuest(pVM, pVM->em.s.pCtx)) 1164 break; 1165 } 1166 Log(("Single step END: rc=%Rrc\n", rc)); 1162 1167 CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF); 1163 1168 pVM->em.s.enmState = enmOldState; 1164 return VINF_EM_RESCHEDULE_REM;1169 return rc == VINF_SUCCESS ? VINF_EM_RESCHEDULE_REM : rc; 1165 1170 } 1166 1171 … … 2426 2431 case VINF_EM_HALT: 2427 2432 case VINF_EM_RESUME: 2433 case VINF_EM_NO_MEMORY: 2428 2434 case VINF_EM_RESCHEDULE: 2429 2435 case VINF_EM_RESCHEDULE_REM: … … 2479 2485 * Check for pending raw actions 2480 2486 * 2481 * @returns VBox status code. 2487 * @returns VBox status code. May return VINF_EM_NO_MEMORY but none of the other 2488 * EM statuses. 2482 2489 * @param pVM The VM to operate on. 2483 2490 */ … … 2493 2500 * This function is called when any FFs in the VM_FF_HIGH_PRIORITY_PRE_RAW_MASK is pending. 2494 2501 * 2495 * @returns VBox status code. 2496 * Only the normal success/failure stuff, no VINF_EM_*.2502 * @returns VBox status code. May return VINF_EM_NO_MEMORY but none of the other 2503 * EM statuses. 2497 2504 * @param pVM The VM handle. 2498 2505 * @param pCtx The guest CPUM register context. … … 2519 2526 * Sync IDT. 2520 2527 */ 2521 if (VM_FF_IS SET(pVM, VM_FF_TRPM_SYNC_IDT))2528 if (VM_FF_ISPENDING(pVM, VM_FF_TRPM_SYNC_IDT)) 2522 2529 { 2523 2530 int rc = TRPMR3SyncIDT(pVM); … … 2529 2536 * Sync TSS. 2530 2537 */ 2531 if (VM_FF_IS SET(pVM, VM_FF_SELM_SYNC_TSS))2538 if (VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_TSS)) 2532 2539 { 2533 2540 int rc = SELMR3SyncTSS(pVM); … … 2555 2562 { 2556 2563 if (rc != VINF_PGM_SYNC_CR3) 2564 { 2565 AssertLogRelMsgReturn(RT_FAILURE(rc), ("%Rrc\n", rc), VERR_IPE_UNEXPECTED_INFO_STATUS); 2557 2566 return rc; 2567 } 2558 2568 rc = PGMSyncCR3(pVM, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3)); 2559 2569 if (RT_FAILURE(rc)) … … 2567 2577 * Allocate handy pages (just in case the above actions have consumed some pages). 2568 2578 */ 2569 if (VM_FF_IS SET(pVM, VM_FF_PGM_NEED_HANDY_PAGES))2579 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PGM_NEED_HANDY_PAGES, VM_FF_PGM_NO_MEMORY)) 2570 2580 { 2571 2581 int rc = PGMR3PhysAllocateHandyPages(pVM); … … 2573 2583 return rc; 2574 2584 } 2585 2586 /* 2587 * Check whether we're out of memory now. 2588 * 2589 * This may stem from some of the above actions or operations that has been executed 2590 * since we ran FFs. The allocate handy pages must for instance always be followed by 2591 * this check. 2592 */ 2593 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 2594 return VINF_EM_NO_MEMORY; 2575 2595 2576 2596 return VINF_SUCCESS; … … 2636 2656 { 2637 2657 rc = emR3RawForcedActions(pVM, pCtx); 2638 if ( RT_FAILURE(rc))2658 if (rc != VINF_SUCCESS) 2639 2659 break; 2640 2660 } … … 2665 2685 { 2666 2686 rc = emR3RawForcedActions(pVM, pCtx); 2667 if ( RT_FAILURE(rc))2687 if (rc != VINF_SUCCESS) 2668 2688 break; 2669 2689 } … … 2776 2796 #endif 2777 2797 STAM_PROFILE_ADV_STOP(&pVM->em.s.StatRAWTail, d); 2778 if (VM_FF_ISPENDING(pVM, ~VM_FF_HIGH_PRIORITY_PRE_RAW_MASK ))2798 if (VM_FF_ISPENDING(pVM, ~VM_FF_HIGH_PRIORITY_PRE_RAW_MASK | VM_FF_PGM_NO_MEMORY)) 2779 2799 { 2780 2800 Assert(pCtx->eflags.Bits.u1VM || (pCtx->ss & X86_SEL_RPL) != 1); … … 2843 2863 2844 2864 /* 2845 * Check various preconditions.2846 */2847 VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));2848 2849 /*2850 2865 * Process high priority pre-execution raw-mode FFs. 2851 2866 */ 2867 VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS)); /* not relevant in HWACCM mode; shouldn't be set really. */ 2852 2868 if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK)) 2853 2869 { 2854 2870 rc = emR3RawForcedActions(pVM, pCtx); 2855 if ( RT_FAILURE(rc))2871 if (rc != VINF_SUCCESS) 2856 2872 break; 2857 2873 } … … 3085 3101 static int emR3HighPriorityPostForcedActions(PVM pVM, int rc) 3086 3102 { 3087 if (VM_FF_IS SET(pVM, VM_FF_PDM_CRITSECT))3103 if (VM_FF_ISPENDING(pVM, VM_FF_PDM_CRITSECT)) 3088 3104 PDMR3CritSectFF(pVM); 3089 3105 3090 if (VM_FF_IS SET(pVM, VM_FF_CSAM_PENDING_ACTION))3106 if (VM_FF_ISPENDING(pVM, VM_FF_CSAM_PENDING_ACTION)) 3091 3107 CSAMR3DoPendingAction(pVM); 3108 3109 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 3110 { 3111 if ( rc > VINF_EM_NO_MEMORY 3112 && rc <= VINF_EM_LAST) 3113 rc = VINF_EM_NO_MEMORY; 3114 } 3092 3115 3093 3116 return rc; … … 3137 3160 * Termination request. 3138 3161 */ 3139 if (VM_FF_IS SET(pVM, VM_FF_TERMINATE))3162 if (VM_FF_ISPENDING(pVM, VM_FF_TERMINATE)) 3140 3163 { 3141 3164 Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n")); … … 3147 3170 * Debugger Facility polling. 3148 3171 */ 3149 if (VM_FF_IS SET(pVM, VM_FF_DBGF))3172 if (VM_FF_ISPENDING(pVM, VM_FF_DBGF)) 3150 3173 { 3151 3174 rc2 = DBGFR3VMMForcedAction(pVM); … … 3156 3179 * Postponed reset request. 3157 3180 */ 3158 if (VM_FF_IS SET(pVM, VM_FF_RESET))3181 if (VM_FF_ISPENDING(pVM, VM_FF_RESET)) 3159 3182 { 3160 3183 rc2 = VMR3Reset(pVM); … … 3166 3189 * CSAM page scanning. 3167 3190 */ 3168 if (VM_FF_IS SET(pVM, VM_FF_CSAM_SCAN_PAGE))3191 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_CSAM_SCAN_PAGE, VM_FF_PGM_NO_MEMORY)) 3169 3192 { 3170 3193 PCPUMCTX pCtx = pVM->em.s.pCtx; … … 3177 3200 } 3178 3201 3202 /* 3203 * Out of memory? Putting this after CSAM as it may in theory cause us to run out of memory. 3204 */ 3205 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 3206 { 3207 rc2 = VINF_EM_NO_MEMORY; 3208 UPDATE_RC(); 3209 if (rc == VINF_EM_NO_MEMORY) 3210 return rc; 3211 } 3212 3179 3213 /* check that we got them all */ 3180 Assert(!(VM_FF_NORMAL_PRIORITY_POST_MASK & ~(VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE )));3214 Assert(!(VM_FF_NORMAL_PRIORITY_POST_MASK & ~(VM_FF_TERMINATE | VM_FF_DBGF | VM_FF_RESET | VM_FF_CSAM_SCAN_PAGE | VM_FF_PGM_NO_MEMORY))); 3181 3215 } 3182 3216 … … 3185 3219 * (Executed in no particular order.) 3186 3220 */ 3187 if (VM_FF_IS PENDING(pVM, VM_FF_NORMAL_PRIORITY_MASK))3221 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_NORMAL_PRIORITY_MASK, VM_FF_PGM_NO_MEMORY)) 3188 3222 { 3189 3223 /* 3190 3224 * PDM Queues are pending. 3191 3225 */ 3192 if (VM_FF_IS SET(pVM, VM_FF_PDM_QUEUES))3226 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PDM_QUEUES, VM_FF_PGM_NO_MEMORY)) 3193 3227 PDMR3QueueFlushAll(pVM); 3194 3228 … … 3196 3230 * PDM DMA transfers are pending. 3197 3231 */ 3198 if (VM_FF_IS SET(pVM, VM_FF_PDM_DMA))3232 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PDM_DMA, VM_FF_PGM_NO_MEMORY)) 3199 3233 PDMR3DmaRun(pVM); 3200 3234 … … 3202 3236 * Requests from other threads. 3203 3237 */ 3204 if (VM_FF_IS SET(pVM, VM_FF_REQUEST))3238 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_REQUEST, VM_FF_PGM_NO_MEMORY)) 3205 3239 { 3206 3240 rc2 = VMR3ReqProcessU(pVM->pUVM, VMREQDEST_ANY); … … 3215 3249 3216 3250 /* Replay the handler notification changes. */ 3217 if (VM_FF_IS SET(pVM, VM_FF_REM_HANDLER_NOTIFY))3251 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_REM_HANDLER_NOTIFY, VM_FF_PGM_NO_MEMORY)) 3218 3252 REMR3ReplayHandlerNotifications(pVM); 3219 3253 … … 3222 3256 } 3223 3257 3258 #if 1 /** @todo this is all dead now, remove after the no-memory changes has been committed. */ 3224 3259 /* 3225 3260 * Execute polling function ever so often. … … 3229 3264 if (!((++cLast) % 4)) 3230 3265 PDMR3Poll(pVM); 3266 #endif 3231 3267 3232 3268 /* … … 3239 3275 * Timers before interrupts. 3240 3276 */ 3241 if (VM_FF_IS SET(pVM, VM_FF_TIMER))3277 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_TIMER, VM_FF_PGM_NO_MEMORY)) 3242 3278 TMR3TimerQueuesDo(pVM); 3243 3279 … … 3245 3281 * The instruction following an emulated STI should *always* be executed! 3246 3282 */ 3247 if (VM_FF_IS SET(pVM, VM_FF_INHIBIT_INTERRUPTS))3283 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_INHIBIT_INTERRUPTS, VM_FF_PGM_NO_MEMORY)) 3248 3284 { 3249 3285 Log(("VM_FF_EMULATED_STI at %RGv successor %RGv\n", (RTGCPTR)CPUMGetGuestRIP(pVM), EMGetInhibitInterruptsPC(pVM))); … … 3268 3304 * Interrupts. 3269 3305 */ 3270 if ( !VM_FF_IS SET(pVM, VM_FF_INHIBIT_INTERRUPTS)3306 if ( !VM_FF_ISPENDING(pVM, VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NO_MEMORY) 3271 3307 && (!rc || rc >= VINF_EM_RESCHEDULE_HWACC) 3272 3308 && !TRPMHasTrap(pVM) /* an interrupt could already be scheduled for dispatching in the recompiler. */ … … 3295 3331 * Allocate handy pages. 3296 3332 */ 3297 if (VM_FF_IS SET(pVM, VM_FF_PGM_NEED_HANDY_PAGES))3333 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_PGM_NEED_HANDY_PAGES, VM_FF_PGM_NO_MEMORY)) 3298 3334 { 3299 3335 rc2 = PGMR3PhysAllocateHandyPages(pVM); … … 3304 3340 * Debugger Facility request. 3305 3341 */ 3306 if (VM_FF_IS SET(pVM, VM_FF_DBGF))3342 if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_DBGF, VM_FF_PGM_NO_MEMORY)) 3307 3343 { 3308 3344 rc2 = DBGFR3VMMForcedAction(pVM); … … 3313 3349 * Termination request. 3314 3350 */ 3315 if (VM_FF_IS SET(pVM, VM_FF_TERMINATE))3351 if (VM_FF_ISPENDING(pVM, VM_FF_TERMINATE)) 3316 3352 { 3317 3353 Log2(("emR3ForcedActions: returns VINF_EM_TERMINATE\n")); … … 3320 3356 } 3321 3357 3358 /* 3359 * Out of memory? Since most of our fellow high priority actions may cause us 3360 * to run out of memory, we're employing VM_FF_IS_PENDING_EXCEPT and putting this 3361 * at the end rather than the start. Also, VM_FF_TERMINATE has higher priority 3362 * than us since we can terminate without allocating more memory. 3363 */ 3364 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 3365 { 3366 rc2 = VINF_EM_NO_MEMORY; 3367 UPDATE_RC(); 3368 if (rc == VINF_EM_NO_MEMORY) 3369 return rc; 3370 } 3371 3322 3372 #ifdef DEBUG 3323 3373 /* 3324 3374 * Debug, pause the VM. 3325 3375 */ 3326 if (VM_FF_IS SET(pVM, VM_FF_DEBUG_SUSPEND))3376 if (VM_FF_ISPENDING(pVM, VM_FF_DEBUG_SUSPEND)) 3327 3377 { 3328 3378 VM_FF_CLEAR(pVM, VM_FF_DEBUG_SUSPEND); … … 3333 3383 #endif 3334 3384 /* check that we got them all */ 3335 Assert(!(VM_FF_HIGH_PRIORITY_PRE_MASK & ~(VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_DBGF | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NEED_HANDY_PAGES )));3385 Assert(!(VM_FF_HIGH_PRIORITY_PRE_MASK & ~(VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_DBGF | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_SELM_SYNC_TSS | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TERMINATE | VM_FF_DEBUG_SUSPEND | VM_FF_INHIBIT_INTERRUPTS | VM_FF_PGM_NEED_HANDY_PAGES | VM_FF_PGM_NO_MEMORY))); 3336 3386 } 3337 3387 … … 3531 3581 return rc; 3532 3582 3583 3584 /* 3585 * Out of memory, suspend the VM and stuff. 3586 */ 3587 case VINF_EM_NO_MEMORY: 3588 /** @todo Take the out of memory fun from here and up. May have to add another 3589 * VM state, but hope not for 2.2 ... */ 3590 Log2(("EMR3ExecuteVM: VINF_EM_NO_MEMORY: %d -> %d\n", pVM->em.s.enmState, EMSTATE_SUSPENDED)); 3591 pVM->em.s.enmState = EMSTATE_SUSPENDED; 3592 break; 3593 3533 3594 /* 3534 3595 * Guest debug events. -
trunk/src/VBox/VMM/PGM.cpp
r18353 r18617 640 640 641 641 #ifdef VBOX_WITH_DEBUGGER 642 /** @todo all but the two last commands must be converted to 'info'. */642 /** @todo Convert the first two commands to 'info' items. */ 643 643 static DECLCALLBACK(int) pgmR3CmdRam(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 644 644 static DECLCALLBACK(int) pgmR3CmdMap(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 645 static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 645 646 static DECLCALLBACK(int) pgmR3CmdSync(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); 646 647 static DECLCALLBACK(int) pgmR3CmdSyncAlways(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult); … … 655 656 *******************************************************************************/ 656 657 #ifdef VBOX_WITH_DEBUGGER 658 /** Argument descriptors for '.pgmerror' and '.pgmerroroff'. */ 659 static const DBGCVARDESC g_aPgmErrorArgs[] = 660 { 661 /* cTimesMin, cTimesMax, enmCategory, fFlags, pszName, pszDescription */ 662 { 0, 1, DBGCVAR_CAT_STRING, 0, "where", "Error injection location." }, 663 }; 664 657 665 /** Command descriptors. */ 658 666 static const DBGCCMD g_aCmds[] = 659 667 { 660 /* pszCmd, cArgsMin, cArgsMax, paArgDesc, cArgDescs, pResultDesc, fFlags, pfnHandler pszSyntax, ....pszDescription */ 661 { "pgmram", 0, 0, NULL, 0, NULL, 0, pgmR3CmdRam, "", "Display the ram ranges." }, 662 { "pgmmap", 0, 0, NULL, 0, NULL, 0, pgmR3CmdMap, "", "Display the mapping ranges." }, 663 { "pgmsync", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSync, "", "Sync the CR3 page." }, 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." }, 664 674 #ifdef VBOX_STRICT 665 { "pgmassertcr3", 0, 0, NULL, 0, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." },675 { "pgmassertcr3", 0, 0, NULL, 0, NULL, 0, pgmR3CmdAssertCR3, "", "Check the shadow CR3 mapping." }, 666 676 #endif 667 { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." },677 { "pgmsyncalways", 0, 0, NULL, 0, NULL, 0, pgmR3CmdSyncAlways, "", "Toggle permanent CR3 syncing." }, 668 678 }; 669 679 #endif … … 1283 1293 if (RT_SUCCESS(rc)) 1284 1294 { 1285 pVM->pgm.s.pvZeroPg GC = MMHyperR3ToRC(pVM, pVM->pgm.s.pvZeroPgR3);1295 pVM->pgm.s.pvZeroPgRC = MMHyperR3ToRC(pVM, pVM->pgm.s.pvZeroPgR3); 1286 1296 pVM->pgm.s.pvZeroPgR0 = MMHyperR3ToR0(pVM, pVM->pgm.s.pvZeroPgR3); 1287 1297 pVM->pgm.s.HCPhysZeroPg = MMR3HyperHCVirt2HCPhys(pVM, pVM->pgm.s.pvZeroPgR3); … … 4692 4702 4693 4703 /** 4704 * The '.pgmerror' and '.pgmerroroff' commands. 4705 * 4706 * @returns VBox status. 4707 * @param pCmd Pointer to the command descriptor (as registered). 4708 * @param pCmdHlp Pointer to command helper functions. 4709 * @param pVM Pointer to the current VM (if any). 4710 * @param paArgs Pointer to (readonly) array of arguments. 4711 * @param cArgs Number of arguments in the array. 4712 */ 4713 static DECLCALLBACK(int) pgmR3CmdError(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult) 4714 { 4715 /* 4716 * Validate input. 4717 */ 4718 if (!pVM) 4719 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: The command requires a VM to be selected.\n"); 4720 AssertReturn(cArgs == 0 || (cArgs == 1 && paArgs[0].enmType == DBGCVAR_TYPE_STRING), 4721 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Hit bug in the parser.\n")); 4722 4723 if (!cArgs) 4724 { 4725 /* 4726 * Print the list of error injection locations with status. 4727 */ 4728 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "PGM error inject locations:\n"); 4729 pCmdHlp->pfnPrintf(pCmdHlp, NULL, " handy - %RTbool\n", pVM->pgm.s.fErrInjHandyPages); 4730 } 4731 else 4732 { 4733 4734 /* 4735 * String switch on where to inject the error. 4736 */ 4737 bool const fNewState = !strcmp(pCmd->pszCmd, "pgmerror"); 4738 const char *pszWhere = paArgs[0].u.pszString; 4739 if (!strcmp(pszWhere, "handy")) 4740 ASMAtomicWriteBool(&pVM->pgm.s.fErrInjHandyPages, fNewState); 4741 else 4742 return pCmdHlp->pfnPrintf(pCmdHlp, NULL, "error: Invalid 'where' value: %s.\n", pszWhere); 4743 pCmdHlp->pfnPrintf(pCmdHlp, NULL, "done\n"); 4744 } 4745 return VINF_SUCCESS; 4746 } 4747 4748 4749 /** 4694 4750 * The '.pgmsync' command. 4695 4751 * -
trunk/src/VBox/VMM/PGMInternal.h
r18604 r18617 2566 2566 RTR0PTR pvZeroPgR0; 2567 2567 /** The GC mapping of the zero page. */ 2568 RTGCPTR pvZeroPg GC;2568 RTGCPTR pvZeroPgRC; 2569 2569 #if GC_ARCH_BITS != 32 2570 2570 uint32_t u32ZeroAlignment; /**< Alignment padding. */ … … 2584 2584 * (The current size of 32 pages, means 128 KB of handy memory.) 2585 2585 */ 2586 GMMPAGEDESC aHandyPages[32]; 2586 GMMPAGEDESC aHandyPages[PGM_HANDY_PAGES]; 2587 2588 /** @name Error injection. 2589 * @{ */ 2590 /** Inject handy page allocation errors pretending we're completely out of 2591 * memory. */ 2592 bool volatile fErrInjHandyPages; 2593 /** Padding. */ 2594 bool afReserved[7]; 2595 /** @} */ 2587 2596 2588 2597 /** @name Release Statistics -
trunk/src/VBox/VMM/PGMPhys.cpp
r18433 r18617 3367 3367 * Response to VM_FF_PGM_NEED_HANDY_PAGES and VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES. 3368 3368 * 3369 * This function will also work the VM_FF_PGM_NO_MEMORY force action flag, to 3370 * signal and clear the out of memory condition. When contracted, this API is 3371 * used to try clear the condition when the user wants to resume. 3372 * 3369 3373 * @returns The following VBox status codes. 3370 * @retval VINF_SUCCESS on success. FF cleared. 3371 * @retval VINF_EM_NO_MEMORY if we're out of memory. The FF is not cleared in this case. 3374 * @retval VINF_SUCCESS on success. FFs cleared. 3375 * @retval VINF_EM_NO_MEMORY if we're out of memory. The FF is not cleared in 3376 * this case and it gets accompanied by VM_FF_PGM_NO_MEMORY. 3372 3377 * 3373 3378 * @param pVM The VM handle. 3379 * 3380 * @remarks The VINF_EM_NO_MEMORY status is for the benefit of the FF processing 3381 * in EM.cpp and shouldn't be propagated outside TRPM, HWACCM, EM and 3382 * pgmPhysEnsureHandyPage. 3374 3383 */ 3375 3384 VMMR3DECL(int) PGMR3PhysAllocateHandyPages(PVM pVM) … … 3400 3409 } 3401 3410 3402 /*3403 * Clear the pages.3404 */3405 3411 if (RT_SUCCESS(rc)) 3406 3412 { 3413 AssertMsg(rc == VINF_SUCCESS, ("%Rrc\n", rc)); 3414 Assert(pVM->pgm.s.cHandyPages > 0); 3415 VM_FF_CLEAR(pVM, VM_FF_PGM_NEED_HANDY_PAGES); 3416 VM_FF_CLEAR(pVM, VM_FF_PGM_NO_MEMORY); 3417 3418 /* 3419 * Clear the pages. 3420 */ 3407 3421 while (iClear < pVM->pgm.s.cHandyPages) 3408 3422 { … … 3415 3429 Log3(("PGMR3PhysAllocateHandyPages: idPage=%#x HCPhys=%RGp\n", pPage->idPage, pPage->HCPhysGCPhys)); 3416 3430 } 3417 3418 VM_FF_CLEAR(pVM, VM_FF_PGM_NEED_HANDY_PAGES);3419 3431 } 3420 3432 else 3421 3433 { 3434 /* 3435 * We should never get here unless there is a genuine shortage of 3436 * memory (or some internal error). Flag the error so the VM can be 3437 * suspended ASAP and the user informed. If we're totally out of 3438 * handy pages we will return failure. 3439 */ 3440 /* Report the failure. */ 3422 3441 LogRel(("PGM: Failed to procure handy pages; rc=%Rrc rcAlloc=%Rrc rcSeed=%Rrc cHandyPages=%#x\n" 3423 3442 " cAllPages=%#x cPrivatePages=%#x cSharedPages=%#x cZeroPages=%#x\n", … … 3428 3447 pVM->pgm.s.cSharedPages, 3429 3448 pVM->pgm.s.cZeroPages)); 3430 #if 1 3431 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) 3432 { 3433 LogRel(("PGM: aHandyPages[#%#04x] = {.HCPhysGCPhys=%RHp, .idPage=%#08x, .idSharedPage=%#08x}\n", 3434 i, pVM->pgm.s.aHandyPages[i].HCPhysGCPhys, pVM->pgm.s.aHandyPages[i].idPage, 3435 pVM->pgm.s.aHandyPages[i].idSharedPage)); 3436 uint32_t const idPage = pVM->pgm.s.aHandyPages[i].idPage; 3437 if (idPage != NIL_GMM_PAGEID) 3449 if ( rc != VERR_NO_MEMORY 3450 && rc != VERR_LOCK_FAILED) 3451 { 3452 for (uint32_t i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) 3438 3453 { 3439 for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; 3440 pRam; 3441 pRam = pRam->pNextR3) 3454 LogRel(("PGM: aHandyPages[#%#04x] = {.HCPhysGCPhys=%RHp, .idPage=%#08x, .idSharedPage=%#08x}\n", 3455 i, pVM->pgm.s.aHandyPages[i].HCPhysGCPhys, pVM->pgm.s.aHandyPages[i].idPage, 3456 pVM->pgm.s.aHandyPages[i].idSharedPage)); 3457 uint32_t const idPage = pVM->pgm.s.aHandyPages[i].idPage; 3458 if (idPage != NIL_GMM_PAGEID) 3442 3459 { 3443 uint32_t const cPages = pRam->cb >> PAGE_SHIFT; 3444 for (uint32_t iPage = 0; iPage < cPages; iPage++) 3445 if (PGM_PAGE_GET_PAGEID(&pRam->aPages[iPage]) == idPage) 3446 LogRel(("PGM: Used by %RGp %R[pgmpage] (%s)\n", 3447 pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), &pRam->aPages[iPage], pRam->pszDesc)); 3460 for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; 3461 pRam; 3462 pRam = pRam->pNextR3) 3463 { 3464 uint32_t const cPages = pRam->cb >> PAGE_SHIFT; 3465 for (uint32_t iPage = 0; iPage < cPages; iPage++) 3466 if (PGM_PAGE_GET_PAGEID(&pRam->aPages[iPage]) == idPage) 3467 LogRel(("PGM: Used by %RGp %R[pgmpage] (%s)\n", 3468 pRam->GCPhys + ((RTGCPHYS)iPage << PAGE_SHIFT), &pRam->aPages[iPage], pRam->pszDesc)); 3469 } 3448 3470 } 3449 3471 } 3450 3472 } 3451 #endif 3452 rc = VERR_EM_NO_MEMORY; 3453 //rc = VINF_EM_NO_MEMORY; 3454 //VM_FF_SET(pVM, VM_FF_PGM_WE_ARE_SCREWED?); 3455 } 3456 3457 /** @todo Do proper VERR_EM_NO_MEMORY reporting. */ 3458 AssertMsg( pVM->pgm.s.cHandyPages == RT_ELEMENTS(pVM->pgm.s.aHandyPages) 3459 || rc != VINF_SUCCESS, ("%d rc=%Rrc\n", pVM->pgm.s.cHandyPages, rc)); 3473 3474 /* Set the FFs and adjust rc. */ 3475 VM_FF_SET(pVM, VM_FF_PGM_NEED_HANDY_PAGES); 3476 VM_FF_SET(pVM, VM_FF_PGM_NO_MEMORY); 3477 if ( rc == VERR_NO_MEMORY 3478 || rc == VERR_LOCK_FAILED) 3479 rc = VINF_EM_NO_MEMORY; 3480 } 3460 3481 3461 3482 pgmUnlock(pVM); 3462 Assert(rc == VINF_SUCCESS || rc == VINF_EM_NO_MEMORY || rc == VERR_EM_NO_MEMORY);3463 3483 return rc; 3464 3484 } … … 3520 3540 * Make sure it's not in the handy page array. 3521 3541 */ 3522 uint32_t i = pVM->pgm.s.cHandyPages; 3523 while (i < RT_ELEMENTS(pVM->pgm.s.aHandyPages)) 3542 for (uint32_t i = pVM->pgm.s.cHandyPages; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) 3524 3543 { 3525 3544 if (pVM->pgm.s.aHandyPages[i].idPage == idPage) … … 3533 3552 break; 3534 3553 } 3535 i++;3536 3554 } 3537 3555 -
trunk/src/VBox/VMM/TRPM.cpp
r17428 r18617 1416 1416 { 1417 1417 /* Must check pending forced actions as our IDT or GDT might be out of sync */ 1418 EMR3CheckRawForcedActions(pVM); 1419 1420 /* There's a handler -> let's execute it in raw mode */ 1421 rc = TRPMForwardTrap(pVM, CPUMCTX2CORE(pCtx), u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, enmEvent, -1); 1422 if (rc == VINF_SUCCESS /* Don't use RT_SUCCESS */) 1418 rc = EMR3CheckRawForcedActions(pVM); 1419 if (rc == VINF_SUCCESS) 1423 1420 { 1424 Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS)); 1425 1426 STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]); 1427 return VINF_EM_RESCHEDULE_RAW; 1421 /* There's a handler -> let's execute it in raw mode */ 1422 rc = TRPMForwardTrap(pVM, CPUMCTX2CORE(pCtx), u8Interrupt, 0, TRPM_TRAP_NO_ERRORCODE, enmEvent, -1); 1423 if (rc == VINF_SUCCESS /* Don't use RT_SUCCESS */) 1424 { 1425 Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS)); 1426 1427 STAM_COUNTER_INC(&pVM->trpm.s.paStatForwardedIRQR3[u8Interrupt]); 1428 return VINF_EM_RESCHEDULE_RAW; 1429 } 1428 1430 } 1429 1431 } -
trunk/src/VBox/VMM/VMM.cpp
r17367 r18617 1535 1535 PRINT_FLAG(VM_FF_PGM_SYNC_CR3); 1536 1536 PRINT_FLAG(VM_FF_PGM_SYNC_CR3_NON_GLOBAL); 1537 PRINT_FLAG(VM_FF_PGM_NEED_HANDY_PAGES); 1538 PRINT_FLAG(VM_FF_PGM_NO_MEMORY); 1537 1539 PRINT_FLAG(VM_FF_TRPM_SYNC_IDT); 1538 1540 PRINT_FLAG(VM_FF_SELM_SYNC_TSS); … … 1543 1545 PRINT_FLAG(VM_FF_CSAM_PENDING_ACTION); 1544 1546 PRINT_FLAG(VM_FF_TO_R3); 1547 PRINT_FLAG(VM_FF_REM_HANDLER_NOTIFY); 1545 1548 PRINT_FLAG(VM_FF_DEBUG_SUSPEND); 1546 1549 if (f) -
trunk/src/VBox/VMM/VMMAll/PGMAllBth.h
r18330 r18617 75 75 * 76 76 * @returns VBox status code (appropriate for trap handling and GC return). 77 * 77 78 * @param pVM VM Handle. 78 79 * @param uErr The trap error code. … … 764 765 return rc; 765 766 } 767 if (RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))) 768 return VINF_EM_NO_MEMORY; 766 769 } 767 770 /// @todo count the above case; else … … 1715 1718 # ifdef PGM_SYNC_N_PAGES 1716 1719 Assert(cPages == 1 || !(uErr & X86_TRAP_PF_P)); 1717 if (cPages > 1 && !(uErr & X86_TRAP_PF_P)) 1720 if ( cPages > 1 1721 && !(uErr & X86_TRAP_PF_P) 1722 && !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 1718 1723 { 1719 1724 /* … … 1953 1958 1954 1959 Assert(cPages == 1 || !(uErr & X86_TRAP_PF_P)); 1955 if (cPages > 1 && !(uErr & X86_TRAP_PF_P)) 1960 if ( cPages > 1 1961 && !(uErr & X86_TRAP_PF_P) 1962 && !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 1956 1963 { 1957 1964 /* … … 1993 2000 (uint64_t)pPTDst->a[iPTDst].u, 1994 2001 pPTDst->a[iPTDst].u & PGM_PTFLAGS_TRACK_DIRTY ? " Track-Dirty" : "")); 2002 2003 if (RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))) 2004 break; 1995 2005 } 1996 2006 else … … 2677 2687 PPGMRAMRANGE pRam = pVM->pgm.s.CTX_SUFF(pRamRanges); 2678 2688 unsigned iPTDst = 0; 2679 while (iPTDst < RT_ELEMENTS(pPTDst->a)) 2689 while ( iPTDst < RT_ELEMENTS(pPTDst->a) 2690 && !VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 2680 2691 { 2681 2692 /* Advance ram range list. */ … … 2700 2711 rc = pgmPhysPageMakeWritableUnlocked(pVM, pPage, GCPhys); 2701 2712 AssertRCReturn(rc, rc); 2713 if (VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) 2714 break; 2702 2715 } 2703 2716 # endif -
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r18345 r18617 262 262 * This will also take the appropriate actions when reaching water-marks. 263 263 * 264 * @returns The following VBox status codes.264 * @returns VBox status code. 265 265 * @retval VINF_SUCCESS on success. 266 266 * @retval VERR_EM_NO_MEMORY if we're really out of memory. … … 273 273 static int pgmPhysEnsureHandyPage(PVM pVM) 274 274 { 275 /** @remarks276 * low-water mark logic for R0 & GC:277 * - 75%: Set FF.278 * - 50%: Force return to ring-3 ASAP.279 *280 * For ring-3 there is a little problem wrt to the recompiler, so:281 * - 75%: Set FF.282 * - 50%: Try allocate pages; on failure we'll force REM to quite ASAP.283 *284 * The basic idea is that we should be able to get out of any situation with285 * only 50% of handy pages remaining.286 *287 * At the moment we'll not adjust the number of handy pages relative to the288 * actual VM RAM committment, that's too much work for now.289 */290 Assert(PDMCritSectIsOwner(&pVM->pgm.s.CritSect));291 275 AssertMsg(pVM->pgm.s.cHandyPages <= RT_ELEMENTS(pVM->pgm.s.aHandyPages), ("%d\n", pVM->pgm.s.cHandyPages)); 292 if ( !pVM->pgm.s.cHandyPages 276 277 /* 278 * Do we need to do anything special? 279 */ 293 280 #ifdef IN_RING3 294 || pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 2 /* 50% */ 295 #endif 296 ) 297 { 298 Log(("PGM: cHandyPages=%u out of %u -> allocate more\n", pVM->pgm.s.cHandyPages, RT_ELEMENTS(pVM->pgm.s.aHandyPages))); 281 if (pVM->pgm.s.cHandyPages <= RT_MAX(PGM_HANDY_PAGES_SET_FF, PGM_HANDY_PAGES_R3_ALLOC)) 282 #else 283 if (pVM->pgm.s.cHandyPages <= RT_MAX(PGM_HANDY_PAGES_SET_FF, PGM_HANDY_PAGES_RZ_TO_R3)) 284 #endif 285 { 286 /* 287 * Allocate pages only if we're out of them, or in ring-3, almost out. 288 */ 299 289 #ifdef IN_RING3 300 int rc = PGMR3PhysAllocateHandyPages(pVM); 290 if (pVM->pgm.s.cHandyPages <= PGM_HANDY_PAGES_R3_ALLOC) 291 #else 292 if (pVM->pgm.s.cHandyPages <= PGM_HANDY_PAGES_RZ_ALLOC) 293 #endif 294 { 295 Log(("PGM: cHandyPages=%u out of %u -> allocate more; VM_FF_PGM_NO_MEMORY=%RTbool\n", 296 pVM->pgm.s.cHandyPages, RT_ELEMENTS(pVM->pgm.s.aHandyPages), VM_FF_ISSET(pVM, VM_FF_PGM_NO_MEMORY) )); 297 #ifdef IN_RING3 298 int rc = PGMR3PhysAllocateHandyPages(pVM); 301 299 #elif defined(IN_RING0) 302 int rc = VMMR0CallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0);300 int rc = VMMR0CallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0); 303 301 #else 304 int rc = VMMGCCallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0); 305 #endif 306 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 307 { 308 AssertMsg(rc == VINF_EM_NO_MEMORY || rc == VERR_EM_NO_MEMORY, ("%Rrc\n", rc)); 309 if (!pVM->pgm.s.cHandyPages) 302 int rc = VMMGCCallHost(pVM, VMMCALLHOST_PGM_ALLOCATE_HANDY_PAGES, 0); 303 #endif 304 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 310 305 { 311 LogRel(("PGM: no more handy pages!\n")); 312 return VERR_EM_NO_MEMORY; 306 if (RT_FAILURE(rc)) 307 return rc; 308 AssertMsgReturn(rc == VINF_EM_NO_MEMORY, ("%Rrc\n", rc), VERR_IPE_UNEXPECTED_INFO_STATUS); 309 if (!pVM->pgm.s.cHandyPages) 310 { 311 LogRel(("PGM: no more handy pages!\n")); 312 return VERR_EM_NO_MEMORY; 313 } 314 Assert(VM_FF_ISSET(pVM, VM_FF_PGM_NEED_HANDY_PAGES)); 315 Assert(VM_FF_ISSET(pVM, VM_FF_PGM_NO_MEMORY)); 316 #ifdef IN_RING3 317 REMR3NotifyFF(pVM); 318 #else 319 VM_FF_SET(pVM, VM_FF_TO_R3); /* paranoia */ 320 #endif 313 321 } 314 Assert(VM_FF_ISSET(pVM, VM_FF_PGM_NEED_HANDY_PAGES)); 315 #ifdef IN_RING3 316 REMR3NotifyFF(pVM); 317 #else 318 VM_FF_SET(pVM, VM_FF_TO_R3); 319 #endif 320 } 321 AssertMsgReturn( pVM->pgm.s.cHandyPages > 0 322 && pVM->pgm.s.cHandyPages <= RT_ELEMENTS(pVM->pgm.s.aHandyPages), 323 ("%u\n", pVM->pgm.s.cHandyPages), 324 VERR_INTERNAL_ERROR); 325 } 326 else if (pVM->pgm.s.cHandyPages - 1 <= (RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 4) * 3) /* 75% */ 327 { 328 VM_FF_SET(pVM, VM_FF_PGM_NEED_HANDY_PAGES); 322 AssertMsgReturn( pVM->pgm.s.cHandyPages > 0 323 && pVM->pgm.s.cHandyPages <= RT_ELEMENTS(pVM->pgm.s.aHandyPages), 324 ("%u\n", pVM->pgm.s.cHandyPages), 325 VERR_INTERNAL_ERROR); 326 } 327 else 328 { 329 if (pVM->pgm.s.cHandyPages <= PGM_HANDY_PAGES_SET_FF) 330 VM_FF_SET(pVM, VM_FF_PGM_NEED_HANDY_PAGES); 329 331 #ifndef IN_RING3 330 if (pVM->pgm.s.cHandyPages - 1 <= RT_ELEMENTS(pVM->pgm.s.aHandyPages) / 2) 331 { 332 Log(("PGM: VM_FF_TO_R3 - cHandyPages=%u out of %u\n", pVM->pgm.s.cHandyPages - 1, RT_ELEMENTS(pVM->pgm.s.aHandyPages))); 333 VM_FF_SET(pVM, VM_FF_TO_R3); 334 } 335 #endif 332 if (pVM->pgm.s.cHandyPages <= PGM_HANDY_PAGES_RZ_TO_R3) 333 { 334 Log(("PGM: VM_FF_TO_R3 - cHandyPages=%u out of %u\n", pVM->pgm.s.cHandyPages, RT_ELEMENTS(pVM->pgm.s.aHandyPages))); 335 VM_FF_SET(pVM, VM_FF_TO_R3); 336 } 337 #endif 338 } 336 339 } 337 340 -
trunk/src/VBox/VMM/VMMGC/TRPMGCHandlers.cpp
r17506 r18617 126 126 * is already handled. Will process resume guest FFs. 127 127 * 128 * @returns rc. 128 * @returns rc, can be adjusted if its VINF_SUCCESS or something really bad 129 * happened. 129 130 * @param pVM VM handle. 130 131 * @param rc The VBox status code to return. … … 182 183 */ 183 184 if ( rc == VINF_SUCCESS 184 && VM_FF_ISPENDING(pVM, VM_FF_TO_R3 | VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_REQUEST)) 185 { 185 && VM_FF_ISPENDING(pVM, VM_FF_TO_R3 | VM_FF_TIMER | VM_FF_INTERRUPT_APIC | VM_FF_INTERRUPT_PIC | VM_FF_REQUEST 186 | VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_PGM_NO_MEMORY)) 187 { 188 /* The out of memory condition naturally outrang the others. */ 189 if (RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY))) 190 rc = VINF_EM_NO_MEMORY; 186 191 /* Pending Ring-3 action. */ 187 if (VM_FF_ISPENDING(pVM, VM_FF_TO_R3))192 else if (VM_FF_ISPENDING(pVM, VM_FF_TO_R3)) 188 193 { 189 194 VM_FF_CLEAR(pVM, VM_FF_TO_R3); … … 903 908 case VINF_IOM_HC_MMIO_READ_WRITE: 904 909 case VINF_PATM_PATCH_INT3: 910 case VINF_EM_NO_MEMORY: 905 911 case VINF_EM_RAW_TO_R3: 906 912 case VINF_EM_RAW_TIMER_PENDING: … … 944 950 switch (rc) 945 951 { 946 case VINF_EM_RAW_EMULATE_INSTR: 947 case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT: 948 case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT: 949 case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT: 950 case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT: 951 case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT: 952 if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip)) 953 rc = VINF_PATCH_EMULATE_INSTR; 954 break; 955 956 case VINF_EM_RAW_GUEST_TRAP: 957 if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip)) 958 return VINF_PATM_PATCH_TRAP_PF; 959 960 rc = TRPMForwardTrap(pVM, pRegFrame, 0xE, 0, TRPM_TRAP_HAS_ERRORCODE, TRPM_TRAP, 0xe); 961 Assert(rc == VINF_EM_RAW_GUEST_TRAP); 962 break; 963 964 case VINF_EM_RAW_INTERRUPT_PENDING: 965 Assert(TRPMHasTrap(pVM)); 966 /* no break; */ 967 case VINF_IOM_HC_MMIO_READ: 968 case VINF_IOM_HC_MMIO_WRITE: 969 case VINF_IOM_HC_MMIO_READ_WRITE: 970 case VINF_PATM_HC_MMIO_PATCH_READ: 971 case VINF_PATM_HC_MMIO_PATCH_WRITE: 972 case VINF_SUCCESS: 973 case VINF_EM_RAW_TO_R3: 974 case VINF_EM_PENDING_REQUEST: 975 case VINF_EM_RAW_TIMER_PENDING: 976 case VINF_CSAM_PENDING_ACTION: 977 case VINF_PGM_SYNC_CR3: /** @todo Check this with Sander. */ 978 break; 979 980 default: 981 AssertMsg(PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip) == false, ("Patch address for return code %d. eip=%08x\n", rc, pRegFrame->eip)); 982 break; 952 case VINF_EM_RAW_EMULATE_INSTR: 953 case VINF_EM_RAW_EMULATE_INSTR_PD_FAULT: 954 case VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT: 955 case VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT: 956 case VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT: 957 case VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT: 958 if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip)) 959 rc = VINF_PATCH_EMULATE_INSTR; 960 break; 961 962 case VINF_EM_RAW_GUEST_TRAP: 963 if (PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip)) 964 return VINF_PATM_PATCH_TRAP_PF; 965 966 rc = TRPMForwardTrap(pVM, pRegFrame, 0xE, 0, TRPM_TRAP_HAS_ERRORCODE, TRPM_TRAP, 0xe); 967 Assert(rc == VINF_EM_RAW_GUEST_TRAP); 968 break; 969 970 case VINF_EM_RAW_INTERRUPT_PENDING: 971 Assert(TRPMHasTrap(pVM)); 972 /* no break; */ 973 case VINF_IOM_HC_MMIO_READ: 974 case VINF_IOM_HC_MMIO_WRITE: 975 case VINF_IOM_HC_MMIO_READ_WRITE: 976 case VINF_PATM_HC_MMIO_PATCH_READ: 977 case VINF_PATM_HC_MMIO_PATCH_WRITE: 978 case VINF_SUCCESS: 979 case VINF_EM_RAW_TO_R3: 980 case VINF_EM_PENDING_REQUEST: 981 case VINF_EM_RAW_TIMER_PENDING: 982 case VINF_EM_NO_MEMORY: 983 case VINF_CSAM_PENDING_ACTION: 984 case VINF_PGM_SYNC_CR3: /** @todo Check this with Sander. */ 985 break; 986 987 default: 988 AssertMsg(PATMIsPatchGCAddr(pVM, (RTRCPTR)pRegFrame->eip) == false, ("Patch address for return code %d. eip=%08x\n", rc, pRegFrame->eip)); 989 break; 983 990 } 984 991 return trpmGCExitTrap(pVM, rc, pRegFrame); -
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r18369 r18617 1466 1466 RTR0MemObjFree(MemObj, false /* fFreeMappings */); 1467 1467 } 1468 /** @todo Check that RTR0MemObjAllocPhysNC always returns VERR_NO_MEMORY on 1469 * allocation failure. */ 1468 1470 return rc; 1469 1471 } -
trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
r17926 r18617 894 894 #endif 895 895 { 896 if (VM_FF_ISPENDING(pVM, VM_FF_ TO_R3 | VM_FF_TIMER | VM_FF_PGM_NEED_HANDY_PAGES))896 if (VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)) 897 897 { 898 898 VM_FF_CLEAR(pVM, VM_FF_TO_R3); 899 899 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3); 900 900 STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatEntry, x); 901 rc = VINF_EM_RAW_TO_R3;901 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3; 902 902 goto end; 903 903 } -
trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
r17924 r18617 2075 2075 2076 2076 /* Check for pending actions that force us to go back to ring 3. */ 2077 if (VM_FF_ISPENDING(pVM, VM_FF_ TO_R3 | VM_FF_TIMER | VM_FF_PGM_NEED_HANDY_PAGES))2077 if (VM_FF_ISPENDING(pVM, VM_FF_HWACCM_TO_R3_MASK)) 2078 2078 { 2079 2079 VM_FF_CLEAR(pVM, VM_FF_TO_R3); 2080 2080 STAM_COUNTER_INC(&pVCpu->hwaccm.s.StatSwitchToR3); 2081 rc = VINF_EM_RAW_TO_R3;2081 rc = RT_UNLIKELY(VM_FF_ISPENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3; 2082 2082 goto end; 2083 2083 } -
trunk/src/VBox/VMM/VMMR0/PGMR0.cpp
r17526 r18617 67 67 Assert(PDMCritSectIsOwner(&pVM->pgm.s.CritSect)); 68 68 69 /* 70 * Check for error injection. 71 */ 72 if (RT_UNLIKELY(pVM->pgm.s.fErrInjHandyPages)) 73 return VERR_NO_MEMORY; 74 75 /* 76 * Try allocate a full set of handy pages. 77 */ 69 78 uint32_t iFirst = pVM->pgm.s.cHandyPages; 70 if (iFirst > RT_ELEMENTS(pVM->pgm.s.aHandyPages)) 71 { 72 LogRel(("%d", iFirst)); 73 return VERR_INTERNAL_ERROR; 74 } 75 79 AssertReturn(iFirst <= RT_ELEMENTS(pVM->pgm.s.aHandyPages), VERR_INTERNAL_ERROR); 76 80 uint32_t cPages = RT_ELEMENTS(pVM->pgm.s.aHandyPages) - iFirst; 77 81 if (!cPages) 78 82 return VINF_SUCCESS; 79 80 83 int rc = GMMR0AllocateHandyPages(pVM, cPages, cPages, &pVM->pgm.s.aHandyPages[iFirst]); 81 84 if (RT_SUCCESS(rc)) … … 93 96 } 94 97 else if (rc != VERR_GMM_SEED_ME) 95 LogRel(("PGMR0PhysAllocateHandyPages: rc=%Rrc iFirst=%d cPages=%d\n", rc, iFirst, cPages)); 98 { 99 if ( ( rc == VERR_GMM_HIT_GLOBAL_LIMIT 100 || rc == VERR_GMM_HIT_VM_ACCOUNT_LIMIT) 101 && iFirst < PGM_HANDY_PAGES_MIN) 102 { 103 104 #ifdef VBOX_STRICT 105 /* We're ASSUMING that GMM has updated all the entires before failing us. */ 106 uint32_t i; 107 for (i = iFirst; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) 108 { 109 Assert(pVM->pgm.s.aHandyPages[i].idPage == NIL_GMM_PAGEID); 110 Assert(pVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID); 111 Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_RTHCPHYS); 112 } 113 #endif 114 115 /* 116 * Reduce the number of pages until we hit the minimum limit. 117 */ 118 do 119 { 120 cPages >>= 2; 121 if (cPages + iFirst < PGM_HANDY_PAGES_MIN) 122 cPages = PGM_HANDY_PAGES_MIN - iFirst; 123 rc = GMMR0AllocateHandyPages(pVM, cPages, cPages, &pVM->pgm.s.aHandyPages[iFirst]); 124 } while ( ( rc == VERR_GMM_HIT_GLOBAL_LIMIT 125 || rc == VERR_GMM_HIT_VM_ACCOUNT_LIMIT) 126 && cPages + iFirst > PGM_HANDY_PAGES_MIN); 127 if (RT_SUCCESS(rc)) 128 { 129 #ifdef VBOX_STRICT 130 i = iFirst + cPages; 131 while (i-- > 0) 132 { 133 Assert(pVM->pgm.s.aHandyPages[i].idPage != NIL_GMM_PAGEID); 134 Assert(pVM->pgm.s.aHandyPages[i].idPage <= GMM_PAGEID_LAST); 135 Assert(pVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID); 136 Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS); 137 Assert(!(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK)); 138 } 139 140 for (i = cPages + iFirst; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++) 141 { 142 Assert(pVM->pgm.s.aHandyPages[i].idPage == NIL_GMM_PAGEID); 143 Assert(pVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID); 144 Assert(pVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_RTHCPHYS); 145 } 146 #endif 147 148 pVM->pgm.s.cHandyPages = iFirst + cPages; 149 } 150 } 151 152 if (RT_FAILURE(rc) && rc != VERR_GMM_SEED_ME) 153 { 154 LogRel(("PGMR0PhysAllocateHandyPages: rc=%Rrc iFirst=%d cPages=%d\n", rc, iFirst, cPages)); 155 VM_FF_SET(pVM, VM_FF_PGM_NO_MEMORY); 156 } 157 } 158 159 96 160 LogFlow(("PGMR0PhysAllocateHandyPages: cPages=%d rc=%Rrc\n", cPages, rc)); 97 161 return rc; -
trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp
r18615 r18617 521 521 GEN_CHECK_OFF(PGM, pvZeroPgR3); 522 522 GEN_CHECK_OFF(PGM, pvZeroPgR0); 523 GEN_CHECK_OFF(PGM, pvZeroPg GC);523 GEN_CHECK_OFF(PGM, pvZeroPgRC); 524 524 GEN_CHECK_OFF(PGM, cHandyPages); 525 525 GEN_CHECK_OFF(PGM, aHandyPages);
Note:
See TracChangeset
for help on using the changeset viewer.

