VirtualBox

Ignore:
Timestamp:
Jun 13, 2024 10:31:38 AM (7 months ago)
Author:
vboxsync
Message:

VMM/PGM: bugref:10703 Add PGM API for retreiving boot zeroed RAM ranges for Hyper-V paravirt provider.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r104885 r104910  
    15011501    PGM_UNLOCK(pVM);
    15021502    return VERR_OUT_OF_RANGE;
     1503}
     1504
     1505
     1506/**
     1507 * Gets RAM ranges that are supposed to be zero'ed at boot.
     1508 *
     1509 * This function gets all RAM ranges that are not ad hoc (ROM, MMIO, MMIO2) memory.
     1510 * The RAM hole (if any) is -NOT- included because we don't return 0s when it is
     1511 * read anyway.
     1512 *
     1513 * @returns VBox status code.
     1514 * @param   pVM             The cross context VM structure.
     1515 * @param   pRanges         Where to store the physical RAM ranges.
     1516 * @param   cMaxRanges      The maximum ranges that can be stored.
     1517 */
     1518VMMR3_INT_DECL(int) PGMR3PhysGetRamBootZeroedRanges(PVM pVM, PPGMPHYSRANGES pRanges, uint32_t cMaxRanges)
     1519{
     1520    VM_ASSERT_VALID_EXT_RETURN(pVM, VERR_INVALID_VM_HANDLE);
     1521    AssertPtrReturn(pRanges, VERR_INVALID_PARAMETER);
     1522    AssertReturn(cMaxRanges > 0, VERR_INVALID_PARAMETER);
     1523
     1524    int rc = VINF_SUCCESS;
     1525    uint32_t idxRange = 0;
     1526    PGM_LOCK_VOID(pVM);
     1527
     1528    /*
     1529     * The primary purpose of this API is the GIM Hyper-V hypercall which recommends (not
     1530     * requires) that the largest ranges are reported earlier. Therefore, here we iterate
     1531     * the ranges in reverse because in PGM the largest range is generally at the end.
     1532     */
     1533    uint32_t const cLookupEntries = RT_MIN(pVM->pgm.s.RamRangeUnion.cLookupEntries, RT_ELEMENTS(pVM->pgm.s.aRamRangeLookup));
     1534    for (int32_t idxLookup = cLookupEntries - 1; idxLookup >= 0; idxLookup--)
     1535    {
     1536        uint32_t const idRamRange = PGMRAMRANGELOOKUPENTRY_GET_ID(pVM->pgm.s.aRamRangeLookup[idxLookup]);
     1537        Assert(idRamRange < RT_ELEMENTS(pVM->pgm.s.apRamRanges));
     1538        PPGMRAMRANGE const pCur = pVM->pgm.s.apRamRanges[idRamRange];
     1539        AssertContinue(pCur);
     1540
     1541        if (!PGM_RAM_RANGE_IS_AD_HOC(pCur))
     1542        {
     1543            if (idxRange < cMaxRanges)
     1544            {
     1545                /* Combine with previous range if it is contiguous, otherwise add it as a new range. */
     1546                if (   idxRange > 0
     1547                    && pRanges->aRanges[idxRange - 1].GCPhysStart == pCur->GCPhysLast + 1U)
     1548                {
     1549                    pRanges->aRanges[idxRange - 1].GCPhysStart = pCur->GCPhys;
     1550                    pRanges->aRanges[idxRange - 1].cPages     += (pCur->cb >> GUEST_PAGE_SHIFT);
     1551                }
     1552                else
     1553                {
     1554                    pRanges->aRanges[idxRange].GCPhysStart = pCur->GCPhys;
     1555                    pRanges->aRanges[idxRange].cPages      = pCur->cb >> GUEST_PAGE_SHIFT;
     1556                    ++idxRange;
     1557                }
     1558            }
     1559            else
     1560            {
     1561                rc = VERR_BUFFER_OVERFLOW;
     1562                break;
     1563            }
     1564        }
     1565    }
     1566    pRanges->cRanges = idxRange;
     1567    PGM_UNLOCK(pVM);
     1568    return rc;
    15031569}
    15041570
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette