Changeset 23374 in vbox for trunk/src/VBox/VMM/VMMAll
- Timestamp:
- Sep 28, 2009 12:53:55 PM (16 years ago)
- svn:sync-xref-src-repo-rev:
- 52898
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r23372 r23374 2549 2549 } 2550 2550 2551 #ifdef IN_RING32552 2553 /**2554 * Rendezvous callback used by pgmR3PoolClearAll that clears all shadow pages2555 * and all modification counters.2556 *2557 * This is only called on one of the EMTs while the other ones are waiting for2558 * it to complete this function.2559 *2560 * @returns VINF_SUCCESS (VBox strict status code).2561 * @param pVM The VM handle.2562 * @param pVCpu The VMCPU for the EMT we're being called on. Unused.2563 * @param pvUser Unused parameter.2564 *2565 * @remark Should only be used when monitoring is available, thus placed in2566 * the PGMPOOL_WITH_MONITORING \#ifdef.2567 * @remark Too expensive for use in R0/RC, but it remains here because of2568 * dependencies?2569 */2570 static DECLCALLBACK(VBOXSTRICTRC) pgmR3PoolClearAllRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)2571 {2572 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);2573 STAM_PROFILE_START(&pPool->StatClearAll, c);2574 LogFlow(("pgmPoolClearAllDoIt: cUsedPages=%d\n", pPool->cUsedPages));2575 2576 pgmLock(pVM);2577 2578 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT2579 pgmPoolResetDirtyPages(pVM);2580 #endif2581 2582 /*2583 * Iterate all the pages until we've encountered all that are in use.2584 * This is simple but not quite optimal solution.2585 */2586 unsigned cModifiedPages = 0; NOREF(cModifiedPages);2587 unsigned cLeft = pPool->cUsedPages;2588 unsigned iPage = pPool->cCurPages;2589 while (--iPage >= PGMPOOL_IDX_FIRST)2590 {2591 PPGMPOOLPAGE pPage = &pPool->aPages[iPage];2592 if (pPage->GCPhys != NIL_RTGCPHYS)2593 {2594 switch (pPage->enmKind)2595 {2596 /*2597 * We only care about shadow page tables.2598 */2599 case PGMPOOLKIND_32BIT_PT_FOR_32BIT_PT:2600 case PGMPOOLKIND_32BIT_PT_FOR_32BIT_4MB:2601 case PGMPOOLKIND_PAE_PT_FOR_32BIT_PT:2602 case PGMPOOLKIND_PAE_PT_FOR_32BIT_4MB:2603 case PGMPOOLKIND_PAE_PT_FOR_PAE_PT:2604 case PGMPOOLKIND_PAE_PT_FOR_PAE_2MB:2605 case PGMPOOLKIND_32BIT_PT_FOR_PHYS:2606 case PGMPOOLKIND_PAE_PT_FOR_PHYS:2607 {2608 #ifdef PGMPOOL_WITH_USER_TRACKING2609 if (pPage->cPresent)2610 #endif2611 {2612 void *pvShw = PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);2613 STAM_PROFILE_START(&pPool->StatZeroPage, z);2614 ASMMemZeroPage(pvShw);2615 STAM_PROFILE_STOP(&pPool->StatZeroPage, z);2616 #ifdef PGMPOOL_WITH_USER_TRACKING2617 pPage->cPresent = 0;2618 pPage->iFirstPresent = NIL_PGMPOOL_PRESENT_INDEX;2619 #endif2620 }2621 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT2622 else2623 Assert(!pPage->fDirty);2624 #endif2625 }2626 /* fall thru */2627 2628 default:2629 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT2630 Assert(!pPage->fDirty);2631 #endif2632 Assert(!pPage->cModifications || ++cModifiedPages);2633 Assert(pPage->iModifiedNext == NIL_PGMPOOL_IDX || pPage->cModifications);2634 Assert(pPage->iModifiedPrev == NIL_PGMPOOL_IDX || pPage->cModifications);2635 pPage->iModifiedNext = NIL_PGMPOOL_IDX;2636 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;2637 pPage->cModifications = 0;2638 break;2639 2640 }2641 if (!--cLeft)2642 break;2643 }2644 }2645 2646 /* swipe the special pages too. */2647 for (iPage = PGMPOOL_IDX_FIRST_SPECIAL; iPage < PGMPOOL_IDX_FIRST; iPage++)2648 {2649 PPGMPOOLPAGE pPage = &pPool->aPages[iPage];2650 if (pPage->GCPhys != NIL_RTGCPHYS)2651 {2652 Assert(!pPage->cModifications || ++cModifiedPages);2653 Assert(pPage->iModifiedNext == NIL_PGMPOOL_IDX || pPage->cModifications);2654 Assert(pPage->iModifiedPrev == NIL_PGMPOOL_IDX || pPage->cModifications);2655 pPage->iModifiedNext = NIL_PGMPOOL_IDX;2656 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;2657 pPage->cModifications = 0;2658 }2659 }2660 2661 #ifndef DEBUG_michael2662 AssertMsg(cModifiedPages == pPool->cModifiedPages, ("%d != %d\n", cModifiedPages, pPool->cModifiedPages));2663 #endif2664 pPool->iModifiedHead = NIL_PGMPOOL_IDX;2665 pPool->cModifiedPages = 0;2666 2667 #ifdef PGMPOOL_WITH_GCPHYS_TRACKING2668 /*2669 * Clear all the GCPhys links and rebuild the phys ext free list.2670 */2671 for (PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRanges);2672 pRam;2673 pRam = pRam->CTX_SUFF(pNext))2674 {2675 unsigned iPage = pRam->cb >> PAGE_SHIFT;2676 while (iPage-- > 0)2677 PGM_PAGE_SET_TRACKING(&pRam->aPages[iPage], 0);2678 }2679 2680 pPool->iPhysExtFreeHead = 0;2681 PPGMPOOLPHYSEXT paPhysExts = pPool->CTX_SUFF(paPhysExts);2682 const unsigned cMaxPhysExts = pPool->cMaxPhysExts;2683 for (unsigned i = 0; i < cMaxPhysExts; i++)2684 {2685 paPhysExts[i].iNext = i + 1;2686 paPhysExts[i].aidx[0] = NIL_PGMPOOL_IDX;2687 paPhysExts[i].aidx[1] = NIL_PGMPOOL_IDX;2688 paPhysExts[i].aidx[2] = NIL_PGMPOOL_IDX;2689 }2690 paPhysExts[cMaxPhysExts - 1].iNext = NIL_PGMPOOL_PHYSEXT_INDEX;2691 #endif2692 2693 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT2694 /* Clear all dirty pages. */2695 pPool->idxFreeDirtyPage = 0;2696 pPool->cDirtyPages = 0;2697 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aIdxDirtyPages); i++)2698 pPool->aIdxDirtyPages[i] = NIL_PGMPOOL_IDX;2699 #endif2700 2701 /* Clear the PGM_SYNC_CLEAR_PGM_POOL flag on all VCPUs to prevent redundant flushes. */2702 for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)2703 {2704 PVMCPU pVCpu = &pVM->aCpus[idCpu];2705 pVCpu->pgm.s.fSyncFlags &= ~PGM_SYNC_CLEAR_PGM_POOL;2706 }2707 2708 pPool->cPresent = 0;2709 pgmUnlock(pVM);2710 PGM_INVL_ALL_VCPU_TLBS(pVM);2711 STAM_PROFILE_STOP(&pPool->StatClearAll, c);2712 return VINF_SUCCESS;2713 }2714 2715 2716 /**2717 * Clears the shadow page pool.2718 *2719 * @param pVM The VM handle.2720 */2721 void pgmR3PoolClearAll(PVM pVM)2722 {2723 int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONCE, pgmR3PoolClearAllRendezvous, NULL);2724 AssertRC(rc);2725 }2726 2727 #endif /* IN_RING3 */2728 2551 2729 2552 /**
Note:
See TracChangeset
for help on using the changeset viewer.