VirtualBox

Changeset 4413 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Aug 29, 2007 8:50:19 AM (17 years ago)
Author:
vboxsync
Message:

Added PGMPhysWriteGCPtrSafe & PGMPhysReadGCPtrSafe

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r4388 r4413  
    15491549}
    15501550
     1551/**
     1552 * Read from guest physical memory referenced by GC pointer.
     1553 *
     1554 * This function uses the current CR3/CR0/CR4 of the guest and will
     1555 * respect access handlers and set accessed bits.
     1556 *
     1557 * @returns VBox status.
     1558 * @param   pVM         VM handle.
     1559 * @param   pvDst       The destination address.
     1560 * @param   GCPtrSrc    The source address (GC pointer).
     1561 * @param   cb          The number of bytes to read.
     1562 */
     1563PGMDECL(int) PGMPhysReadGCPtrSafe(PVM pVM, void *pvDst, RTGCPTR GCPtrSrc, size_t cb)
     1564{
     1565    /*
     1566     * Anything to do?
     1567     */
     1568    if (!cb)
     1569        return VINF_SUCCESS;
     1570
     1571    LogFlow(("PGMPhysReadGCPtrSafe: %VGv %d\n", GCPtrSrc, cb));
     1572
     1573    /*
     1574     * Optimize reads within a single page.
     1575     */
     1576    if (((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK) + cb <= PAGE_SIZE)
     1577    {
     1578        /* mark the guest page as accessed. */
     1579        int rc = PGMGstModifyPage(pVM, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     1580        AssertRC(rc);
     1581
     1582        PGMPhysRead(pVM, GCPtrSrc, pvDst, cb);
     1583        return VINF_SUCCESS;
     1584    }
     1585
     1586    /*
     1587     * Page by page.
     1588     */
     1589    for (;;)
     1590    {
     1591        /* mark the guest page as accessed. */
     1592        int rc = PGMGstModifyPage(pVM, GCPtrSrc, 1, X86_PTE_A, ~(uint64_t)(X86_PTE_A));
     1593        AssertRC(rc);
     1594
     1595        /* copy */
     1596        size_t cbRead = PAGE_SIZE - ((RTGCUINTPTR)GCPtrSrc & PAGE_OFFSET_MASK);
     1597        if (cbRead >= cb)
     1598        {
     1599            PGMPhysRead(pVM, GCPtrSrc, pvDst, cb);
     1600            return VINF_SUCCESS;
     1601        }
     1602        PGMPhysRead(pVM, GCPtrSrc, pvDst, cbRead);
     1603
     1604        /* next */
     1605        cb         -= cbRead;
     1606        pvDst       = (uint8_t *)pvDst + cbRead;
     1607        GCPtrSrc   += cbRead;
     1608    }
     1609}
     1610
     1611
     1612/**
     1613 * Write to guest physical memory referenced by GC pointer.
     1614 *
     1615 * This function uses the current CR3/CR0/CR4 of the guest and will
     1616 * respect access handlers and set dirty and accessed bits.
     1617 *
     1618 * @returns VBox status.
     1619 * @param   pVM         VM handle.
     1620 * @param   GCPtrDst    The destination address (GC pointer).
     1621 * @param   pvSrc       The source address.
     1622 * @param   cb          The number of bytes to write.
     1623 */
     1624PGMDECL(int) PGMPhysWriteGCPtrSafe(PVM pVM, RTGCPTR GCPtrDst, const void *pvSrc, size_t cb)
     1625{
     1626    /*
     1627     * Anything to do?
     1628     */
     1629    if (!cb)
     1630        return VINF_SUCCESS;
     1631
     1632    LogFlow(("PGMPhysWriteGCPtrSafe: %VGv %d\n", GCPtrDst, cb));
     1633
     1634    /*
     1635     * Optimize writes within a single page.
     1636     */
     1637    if (((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK) + cb <= PAGE_SIZE)
     1638    {
     1639        /* mark the guest page as accessed and dirty. */
     1640        int rc = PGMGstModifyPage(pVM, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
     1641        AssertRC(rc);
     1642
     1643        PGMPhysWrite(pVM, GCPtrDst, pvSrc, cb);
     1644        return VINF_SUCCESS;
     1645    }
     1646
     1647    /*
     1648     * Page by page.
     1649     */
     1650    for (;;)
     1651    {
     1652        /* mark the guest page as accessed and dirty. */
     1653        int rc = PGMGstModifyPage(pVM, GCPtrDst, 1, X86_PTE_A | X86_PTE_D, ~(uint64_t)(X86_PTE_A | X86_PTE_D));
     1654        AssertRC(rc);
     1655
     1656        /* copy */
     1657        size_t cbWrite = PAGE_SIZE - ((RTGCUINTPTR)GCPtrDst & PAGE_OFFSET_MASK);
     1658        if (cbWrite >= cb)
     1659        {
     1660            PGMPhysWrite(pVM, GCPtrDst, pvSrc, cb);
     1661            return VINF_SUCCESS;
     1662        }
     1663        PGMPhysWrite(pVM, GCPtrDst, pvSrc, cbWrite);
     1664
     1665        /* next */
     1666        cb         -= cbWrite;
     1667        pvSrc       = (uint8_t *)pvSrc + cbWrite;
     1668        GCPtrDst   += cbWrite;
     1669    }
     1670}
    15511671
    15521672/**
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