Changeset 73073 in vbox for trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
- Timestamp:
- Jul 11, 2018 4:19:48 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/PGMAll.cpp
r72265 r73073 1431 1431 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 1432 1432 * @param GCPtr The guest virtual address to walk by. 1433 * @param pWalk Where to return the walk result. This is valid onsome1433 * @param pWalk Where to return the walk result. This is valid for some 1434 1434 * error codes as well. 1435 1435 */ … … 1471 1471 return VERR_PGM_NOT_USED_IN_MODE; 1472 1472 } 1473 } 1474 1475 1476 /** 1477 * Tries to continue the previous walk. 1478 * 1479 * @note Requires the caller to hold the PGM lock from the first 1480 * pgmGstPtWalk() call to the last pgmGstPtWalkNext() call. Otherwise 1481 * we cannot use the pointers. 1482 * 1483 * @returns VBox status code. 1484 * @retval VINF_SUCCESS on success. 1485 * @retval VERR_PAGE_TABLE_NOT_PRESENT on failure. Check pWalk for details. 1486 * @retval VERR_PGM_NOT_USED_IN_MODE if not paging isn't enabled. @a pWalk is 1487 * not valid, except enmType is PGMPTWALKGSTTYPE_INVALID. 1488 * 1489 * @param pVCpu The cross context virtual CPU structure of the calling EMT. 1490 * @param GCPtr The guest virtual address to walk by. 1491 * @param pWalk Pointer to the previous walk result and where to return 1492 * the result of this walk. This is valid for some error 1493 * codes as well. 1494 */ 1495 int pgmGstPtWalkNext(PVMCPU pVCpu, RTGCPTR GCPtr, PPGMPTWALKGST pWalk) 1496 { 1497 /* 1498 * We can only handle successfully walks. 1499 * We also limit ourselves to the next page. 1500 */ 1501 if ( pWalk->u.Core.fSucceeded 1502 && GCPtr - pWalk->u.Core.GCPtr == PAGE_SIZE) 1503 { 1504 Assert(pWalk->u.Core.uLevel == 0); 1505 if (pWalk->enmType == PGMPTWALKGSTTYPE_AMD64) 1506 { 1507 /* 1508 * AMD64 1509 */ 1510 if (!pWalk->u.Core.fGigantPage && !pWalk->u.Core.fBigPage) 1511 { 1512 /* 1513 * We fall back to full walk if the PDE table changes, if any 1514 * reserved bits are set, or if the effective page access changes. 1515 */ 1516 const uint64_t fPteSame = X86_PTE_P | X86_PTE_RW | X86_PTE_US | X86_PTE_PWT 1517 | X86_PTE_PCD | X86_PTE_A | X86_PTE_PAE_NX; 1518 const uint64_t fPdeSame = X86_PDE_P | X86_PDE_RW | X86_PDE_US | X86_PDE_PWT 1519 | X86_PDE_PCD | X86_PDE_A | X86_PDE_PAE_NX | X86_PDE_PS; 1520 1521 if ((GCPtr >> X86_PD_PAE_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PD_PAE_SHIFT)) 1522 { 1523 if (pWalk->u.Amd64.pPte) 1524 { 1525 X86PTEPAE Pte; 1526 Pte.u = pWalk->u.Amd64.pPte[1].u; 1527 if ( (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame) 1528 && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask)) 1529 { 1530 1531 pWalk->u.Core.GCPtr = GCPtr; 1532 pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK; 1533 pWalk->u.Amd64.Pte.u = Pte.u; 1534 pWalk->u.Amd64.pPte++; 1535 return VINF_SUCCESS; 1536 } 1537 } 1538 } 1539 else if ((GCPtr >> X86_PDPT_SHIFT) == (pWalk->u.Core.GCPtr >> X86_PDPT_SHIFT)) 1540 { 1541 Assert(!((GCPtr >> X86_PD_PAE_SHIFT) & X86_PD_PAE_MASK)); /* Must be first PT entry. */ 1542 if (pWalk->u.Amd64.pPde) 1543 { 1544 X86PDEPAE Pde; 1545 Pde.u = pWalk->u.Amd64.pPde[1].u; 1546 if ( (Pde.u & fPdeSame) == (Pde.u & fPdeSame) 1547 && !(Pde.u & (pVCpu)->pgm.s.fGstAmd64MbzPdeMask)) 1548 { 1549 /* Get the new PTE and check out the first entry. */ 1550 int rc = PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, PGM_A20_APPLY(pVCpu, (Pde.u & X86_PDE_PAE_PG_MASK)), 1551 &pWalk->u.Amd64.pPt); 1552 if (RT_SUCCESS(rc)) 1553 { 1554 pWalk->u.Amd64.pPte = &pWalk->u.Amd64.pPt->a[0]; 1555 X86PTEPAE Pte; 1556 Pte.u = pWalk->u.Amd64.pPte->u; 1557 if ( (Pte.u & fPteSame) == (pWalk->u.Amd64.Pte.u & fPteSame) 1558 && !(Pte.u & (pVCpu)->pgm.s.fGstAmd64MbzPteMask)) 1559 { 1560 pWalk->u.Core.GCPtr = GCPtr; 1561 pWalk->u.Core.GCPhys = Pte.u & X86_PTE_PAE_PG_MASK; 1562 pWalk->u.Amd64.Pte.u = Pte.u; 1563 pWalk->u.Amd64.Pde.u = Pde.u; 1564 pWalk->u.Amd64.pPde++; 1565 return VINF_SUCCESS; 1566 } 1567 } 1568 } 1569 } 1570 } 1571 } 1572 else if (!pWalk->u.Core.fGigantPage) 1573 { 1574 if ((GCPtr & X86_PAGE_2M_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_2M_BASE_MASK)) 1575 { 1576 pWalk->u.Core.GCPtr = GCPtr; 1577 pWalk->u.Core.GCPhys += PAGE_SIZE; 1578 return VINF_SUCCESS; 1579 } 1580 } 1581 else 1582 { 1583 if ((GCPtr & X86_PAGE_1G_BASE_MASK) == (pWalk->u.Core.GCPtr & X86_PAGE_1G_BASE_MASK)) 1584 { 1585 pWalk->u.Core.GCPtr = GCPtr; 1586 pWalk->u.Core.GCPhys += PAGE_SIZE; 1587 return VINF_SUCCESS; 1588 } 1589 } 1590 } 1591 } 1592 /* Case we don't handle. Do full walk. */ 1593 return pgmGstPtWalk(pVCpu, GCPtr, pWalk); 1473 1594 } 1474 1595
Note:
See TracChangeset
for help on using the changeset viewer.