Changeset 4413 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Aug 29, 2007 8:50:19 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
r4388 r4413 1549 1549 } 1550 1550 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 */ 1563 PGMDECL(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 */ 1624 PGMDECL(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 } 1551 1671 1552 1672 /**
Note:
See TracChangeset
for help on using the changeset viewer.