Changeset 17032 in vbox
- Timestamp:
- Feb 23, 2009 6:47:03 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/SELM.cpp
r16506 r17032 1421 1421 { 1422 1422 Assert(enmAccessType == PGMACCESSTYPE_WRITE); 1423 Log(("selmR3GuestTSSWriteHandler: write to %RGv size %d\n", GCPtr, cbBuf)); 1423 Log(("selmR3GuestTSSWriteHandler: write %.*Rhxs to %RGv size %d\n", RT_MIN(8, cbBuf), pvBuf, GCPtr, cbBuf)); 1424 1424 1425 VM_FF_SET(pVM, VM_FF_SELM_SYNC_TSS); 1426 1425 1427 return VINF_PGM_HANDLER_DO_DEFAULT; 1426 1428 } … … 1477 1479 || pDesc->Gen.u4Type == X86_SEL_TYPE_SYS_386_TSS_BUSY; 1478 1480 1479 /* Note: We should monitor the whole TSS to catch accesses to the virtual interrupt redirection bitmap, but1480 * that causes some problems and with Windows guests some overhead as the entire TSS is rather big (3 pages).1481 * We'll assume for now that the bitmap is static.1482 * /1483 #if 1 1484 /* Don't bother with anything but the core structure. (Actually all we care for is the r0 ss.)*/1481 /* 1482 * Presently we monitor the TSS and the interrupt redirection bitmap if it's present. 1483 * We're assuming the guest is playing nice and that the bits we're monitoring won't 1484 * cross page boundraries. (The TSS core must be on a single page, while the bitmap 1485 * probably doesn't need to be.) 1486 */ 1485 1487 if (cbTss > sizeof(VBOXTSS)) 1486 1488 cbTss = sizeof(VBOXTSS); 1487 #endif 1488 /* The guest's TSS can span multiple pages now. We will monitor the whole thing. */ 1489 #ifndef DEBUG_michael 1490 AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + RT_MIN(sizeof(VBOXTSS), cbTss) - 1) >> PAGE_SHIFT), 1489 AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + cbTss - 1) >> PAGE_SHIFT), 1491 1490 ("GCPtrTss=%RGv cbTss=%#x - We assume everything is inside one page!\n", GCPtrTss, cbTss)); 1492 #endif1493 1491 1494 1492 // All system GDTs are marked not present above. That explains why this check fails. … … 1544 1542 } 1545 1543 1546 /* Update the ring 0 stack selector and base address */ 1547 /* feeling very lazy; reading too much */ 1548 VBOXTSS tss; 1549 rc = PGMPhysSimpleReadGCPtr(pVM, &tss, GCPtrTss, RT_OFFSETOF(VBOXTSS, offIoBitmap) + sizeof(tss.offIoBitmap)); 1544 /* 1545 * Update the ring 0 stack selector and base address. 1546 * (Reading up to and including offIoBitmap to save effort in the VME case.) 1547 */ 1548 VBOXTSS Tss; 1549 rc = PGMPhysSimpleReadGCPtr(pVM, &Tss, GCPtrTss, RT_OFFSETOF(VBOXTSS, offIoBitmap) + sizeof(Tss.offIoBitmap)); 1550 1550 if (RT_SUCCESS(rc)) 1551 1551 { 1552 1552 #ifdef LOG_ENABLED 1553 uint32_t ssr0, espr0; 1554 1555 SELMGetRing1Stack(pVM, &ssr0, &espr0); 1556 ssr0 &= ~1; 1557 1558 if (ssr0 != tss.ss0 || espr0 != tss.esp0) 1559 Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X\n", tss.ss0, tss.esp0)); 1560 Log(("offIoBitmap=%#x\n", tss.offIoBitmap)); 1553 if (LogIsEnabled()) 1554 { 1555 uint32_t ssr0, espr0; 1556 SELMGetRing1Stack(pVM, &ssr0, &espr0); 1557 if ((ssr0 & ~1) != Tss.ss0 || espr0 != Tss.esp0) 1558 { 1559 RTGCPHYS GCPhys = NIL_RTGCPHYS; 1560 rc = PGMGstGetPage(pVM, GCPtrTss, NULL, &GCPhys); AssertRC(rc); 1561 Log(("SELMR3SyncTSS: Updating TSS ring 0 stack to %04X:%08X from %04X:%08X; TSS Phys=%VGp)\n", 1562 Tss.ss0, Tss.esp0, (ssr0 & ~1), espr0, GCPhys)); 1563 AssertMsg(ssr0 != Tss.ss0, 1564 ("ring-1 leak into TSS.SS0! %04X:%08X from %04X:%08X; TSS Phys=%VGp)\n", 1565 Tss.ss0, Tss.esp0, (ssr0 & ~1), espr0, GCPhys)); 1566 } 1567 Log(("offIoBitmap=%#x\n", Tss.offIoBitmap)); 1568 } 1561 1569 #endif /* LOG_ENABLED */ 1570 AssertMsg(!(Tss.ss0 & 3), ("ring-1 leak into TSS.SS0? %04X:%08X\n", Tss.ss0, Tss.esp0)); 1571 1572 1562 1573 /* Update our TSS structure for the guest's ring 1 stack */ 1563 SELMSetRing1Stack(pVM, tss.ss0 | 1, tss.esp0); 1564 1565 /* Should we sync the virtual interrupt redirection bitmap as well? */ 1574 SELMSetRing1Stack(pVM, Tss.ss0 | 1, Tss.esp0); 1575 1576 /* 1577 * Should we sync the virtual interrupt redirection bitmap as well? 1578 */ 1566 1579 if (CPUMGetGuestCR4(pVM) & X86_CR4_VME) 1567 1580 { 1568 uint32_t offRedirBitmap;1569 1570 1581 /* Make sure the io bitmap offset is valid; anything less than sizeof(VBOXTSS) means there's none. */ 1571 if ( tss.offIoBitmap < RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(tss.IntRedirBitmap))1582 if (Tss.offIoBitmap < RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(Tss.IntRedirBitmap)) 1572 1583 { 1573 Log(("Invalid io bitmap offset detected (%x)!\n", tss.offIoBitmap));1574 tss.offIoBitmap = RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(tss.IntRedirBitmap);1584 Log(("Invalid io bitmap offset detected (%x)!\n", Tss.offIoBitmap)); 1585 Tss.offIoBitmap = RT_OFFSETOF(VBOXTSS, IntRedirBitmap) + sizeof(Tss.IntRedirBitmap); 1575 1586 } 1576 1587 1577 offRedirBitmap = tss.offIoBitmap - sizeof(tss.IntRedirBitmap);1588 uint32_t offRedirBitmap = Tss.offIoBitmap - sizeof(Tss.IntRedirBitmap); 1578 1589 1579 1590 /** @todo not sure how the partial case is handled; probably not allowed */ 1580 if (offRedirBitmap + sizeof( tss.IntRedirBitmap) <= pVM->selm.s.cbGuestTss)1591 if (offRedirBitmap + sizeof(Tss.IntRedirBitmap) <= pVM->selm.s.cbGuestTss) 1581 1592 { 1582 rc = PGMPhysSimpleReadGCPtr(pVM, &pVM->selm.s.Tss.IntRedirBitmap, GCPtrTss + offRedirBitmap, sizeof( tss.IntRedirBitmap));1593 rc = PGMPhysSimpleReadGCPtr(pVM, &pVM->selm.s.Tss.IntRedirBitmap, GCPtrTss + offRedirBitmap, sizeof(Tss.IntRedirBitmap)); 1583 1594 AssertRC(rc); 1584 1595 Log2(("Redirection bitmap:\n")); 1585 Log2(("%.*Rhxd\n", sizeof( tss.IntRedirBitmap), &pVM->selm.s.Tss.IntRedirBitmap));1596 Log2(("%.*Rhxd\n", sizeof(Tss.IntRedirBitmap), &pVM->selm.s.Tss.IntRedirBitmap)); 1586 1597 } 1587 1598 } … … 1753 1764 { 1754 1765 #ifdef VBOX_STRICT 1766 if (VM_FF_ISSET(pVM, VM_FF_SELM_SYNC_TSS)) 1767 return true; 1755 1768 1756 1769 RTSEL SelTss = CPUMGetGuestTR(pVM); … … 1768 1781 cbTss = (cbTss << PAGE_SHIFT) | PAGE_OFFSET_MASK; 1769 1782 cbTss++; 1770 # if 1 1771 /* Don't bother with anything but the core structure. (Actually all we care for is the r0 ss.) */ 1783 1784 /* 1785 * We only care about the Ring-0 ESP and SS values and the interrupt redirection bitmap. 1786 * See SELMR3SyncTSS for details. 1787 */ 1772 1788 if (cbTss > sizeof(VBOXTSS)) 1773 1789 cbTss = sizeof(VBOXTSS); 1774 # endif 1775 # ifndef DEBUG_michael 1776 AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + sizeof(VBOXTSS) - 1) >> PAGE_SHIFT), 1790 AssertMsg((GCPtrTss >> PAGE_SHIFT) == ((GCPtrTss + cbTss - 1) >> PAGE_SHIFT), 1777 1791 ("GCPtrTss=%RGv cbTss=%#x - We assume everything is inside one page!\n", GCPtrTss, cbTss)); 1778 # endif1779 1792 1780 1793 // All system GDTs are marked not present above. That explains why this check fails. … … 1801 1814 if (RT_SUCCESS(rc)) 1802 1815 { 1803 RTSEL SelSS0;1816 RTSEL SelSS0; 1804 1817 rc = PGMPhysSimpleReadGCPtr(pVM, &SelSS0, GCPtrGuestTSS + RT_OFFSETOF(VBOXTSS, ss0), sizeof(SelSS0)); 1805 1818 if (RT_SUCCESS(rc)) … … 1810 1823 1811 1824 RTGCPHYS GCPhys; 1812 uint64_t fFlags; 1813 1814 rc = PGMGstGetPage(pVM, GCPtrGuestTSS, &fFlags, &GCPhys); 1815 AssertRC(rc); 1825 rc = PGMGstGetPage(pVM, GCPtrGuestTSS, NULL, &GCPhys); AssertRC(rc); 1816 1826 AssertMsgFailed(("TSS out of sync!! (%04X:%08X vs %04X:%08X (guest)) Tss=%RGv Phys=%RGp\n", 1817 1827 (pVM->selm.s.Tss.ss1 & ~1), pVM->selm.s.Tss.esp1, SelSS0, ESPR0, GCPtrGuestTSS, GCPhys));
Note:
See TracChangeset
for help on using the changeset viewer.