Changeset 18143 in vbox for trunk/src/VBox/VMM/PGMPhys.cpp
- Timestamp:
- Mar 23, 2009 3:10:24 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMPhys.cpp
r18101 r18143 347 347 348 348 #ifdef VBOX_WITH_NEW_PHYS_CODE 349 /** 349 /** 350 350 * VMR3ReqCall worker for PGMR3PhysGCPhys2CCPtrExternal to make pages writable. 351 * 351 * 352 352 * @returns see PGMR3PhysGCPhys2CCPtrExternal 353 353 * @param pVM The VM handle. … … 355 355 * @param ppv Where to store the mapping address. 356 356 * @param pLock Where to store the lock. 357 */ 357 */ 358 358 static DECLCALLBACK(int) pgmR3PhysGCPhys2CCPtrDelegated(PVM pVM, PRTGCPHYS pGCPhys, void **ppv, PPGMPAGEMAPLOCK pLock) 359 359 { 360 360 /* 361 * Just hand it to PGMPhysGCPhys2CCPtr and check that it's not a page with 361 * Just hand it to PGMPhysGCPhys2CCPtr and check that it's not a page with 362 362 * an access handler after it succeeds. 363 363 */ … … 392 392 * Requests the mapping of a guest page into ring-3, external threads. 393 393 * 394 * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to 395 * release it. 396 * 397 * This API will assume your intention is to write to the page, and will 398 * therefore replace shared and zero pages. If you do not intend to modify the 399 * page, use the PGMR3PhysGCPhys2CCPtrReadOnlyExternal() API. 394 * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to 395 * release it. 396 * 397 * This API will assume your intention is to write to the page, and will 398 * therefore replace shared and zero pages. If you do not intend to modify the 399 * page, use the PGMR3PhysGCPhys2CCPtrReadOnlyExternal() API. 400 400 * 401 401 * @returns VBox status code. 402 402 * @retval VINF_SUCCESS on success. 403 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 403 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 404 404 * backing or if the page has any active access handlers. The caller 405 405 * must fall back on using PGMR3PhysWriteExternal. … … 445 445 /* 446 446 * If the page is shared, the zero page, or being write monitored 447 * it must be converted to an page that's writable if possible. 447 * it must be converted to an page that's writable if possible. 448 448 * This has to be done on an EMT. 449 449 */ … … 451 451 { 452 452 pgmUnlock(pVM); 453 453 454 454 PVMREQ pReq = NULL; 455 455 rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, … … 496 496 /** 497 497 * Requests the mapping of a guest page into ring-3, external threads. 498 * 498 * 499 499 * When you're done with the page, call PGMPhysReleasePageMappingLock() ASAP to 500 500 * release it. … … 502 502 * @returns VBox status code. 503 503 * @retval VINF_SUCCESS on success. 504 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 504 * @retval VERR_PGM_PHYS_PAGE_RESERVED it it's a valid page but has no physical 505 505 * backing or if the page as an active ALL access handler. The caller 506 506 * must fall back on using PGMPhysRead. … … 538 538 rc = VERR_PGM_PHYS_PAGE_RESERVED; 539 539 #endif 540 else 540 else 541 541 { 542 542 /* … … 1696 1696 * @param pvBinary Pointer to the binary data backing the ROM image. 1697 1697 * This must be exactly \a cbRange in size. 1698 * @param fFlags Mask of flags. PGMPHYS_ROM_FLAG _SHADOWED1699 * and/or PGMPHYS_ROM_FLAG _PERMANENT_BINARY.1698 * @param fFlags Mask of flags. PGMPHYS_ROM_FLAGS_SHADOWED 1699 * and/or PGMPHYS_ROM_FLAGS_PERMANENT_BINARY. 1700 1700 * @param pszDesc Pointer to description string. This must not be freed. 1701 1701 * … … 1720 1720 AssertPtrReturn(pvBinary, VERR_INVALID_PARAMETER); 1721 1721 AssertPtrReturn(pszDesc, VERR_INVALID_POINTER); 1722 AssertReturn(!(fFlags & ~(PGMPHYS_ROM_FLAG _SHADOWED | PGMPHYS_ROM_FLAG_PERMANENT_BINARY)), VERR_INVALID_PARAMETER);1722 AssertReturn(!(fFlags & ~(PGMPHYS_ROM_FLAGS_SHADOWED | PGMPHYS_ROM_FLAGS_PERMANENT_BINARY)), VERR_INVALID_PARAMETER); 1723 1723 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE); 1724 1724 … … 1794 1794 */ 1795 1795 uint32_t cExtraBaseCost = fRamExists ? cPages : 0; 1796 if (fFlags & PGMPHYS_ROM_FLAG _SHADOWED)1796 if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 1797 1797 cExtraBaseCost += cPages; 1798 1798 if (cExtraBaseCost) … … 1899 1899 * to PGM atm). 1900 1900 */ 1901 if (fFlags & PGMPHYS_ROM_FLAG _SHADOWED)1901 if (fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 1902 1902 { 1903 1903 REMR3NotifyPhysRomRegister(pVM, GCPhys, cb, NULL, true /* fShadowed */); 1904 1904 rc = PGMR3HandlerPhysicalRegister(pVM, 1905 fFlags & PGMPHYS_ROM_FLAG _SHADOWED1905 fFlags & PGMPHYS_ROM_FLAGS_SHADOWED 1906 1906 ? PGMPHYSHANDLERTYPE_PHYSICAL_ALL 1907 1907 : PGMPHYSHANDLERTYPE_PHYSICAL_WRITE, … … 1914 1914 { 1915 1915 rc = PGMR3HandlerPhysicalRegister(pVM, 1916 fFlags & PGMPHYS_ROM_FLAG _SHADOWED1916 fFlags & PGMPHYS_ROM_FLAGS_SHADOWED 1917 1917 ? PGMPHYSHANDLERTYPE_PHYSICAL_ALL 1918 1918 : PGMPHYSHANDLERTYPE_PHYSICAL_WRITE, … … 1954 1954 pRomNew->cb = cb; 1955 1955 pRomNew->fFlags = fFlags; 1956 pRomNew->pvOriginal = fFlags & PGMPHYS_ROM_FLAG _PERMANENT_BINARY ? pvBinary : NULL;1956 pRomNew->pvOriginal = fFlags & PGMPHYS_ROM_FLAGS_PERMANENT_BINARY ? pvBinary : NULL; 1957 1957 pRomNew->pszDesc = pszDesc; 1958 1958 … … 2037 2037 Assert(iPage < (pRom->cb >> PAGE_SHIFT)); 2038 2038 PPGMROMPAGE pRomPage = &pRom->aPages[iPage]; 2039 switch (pRomPage->enmProt) 2040 { 2041 /* 2042 * Ignore. 2043 */ 2044 case PGMROMPROT_READ_ROM_WRITE_IGNORE: 2045 case PGMROMPROT_READ_RAM_WRITE_IGNORE: 2046 return VINF_SUCCESS; 2047 2048 /* 2049 * Write to the ram page. 2050 */ 2051 case PGMROMPROT_READ_ROM_WRITE_RAM: 2052 case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */ 2053 { 2054 /* This should be impossible now, pvPhys doesn't work cross page anylonger. */ 2055 Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage); 2056 2039 Log5(("pgmR3PhysRomWriteHandler: %d %c %#08RGp %#04zx\n", pRomPage->enmProt, enmAccessType == PGMACCESSTYPE_READ ? 'R' : 'W', GCPhys, cbBuf)); 2040 2041 if (enmAccessType == PGMACCESSTYPE_READ) 2042 { 2043 switch (pRomPage->enmProt) 2044 { 2057 2045 /* 2058 * Take the lock, do lazy allocation, map the page and copy the data. 2059 * 2060 * Note that we have to bypass the mapping TLB since it works on 2061 * guest physical addresses and entering the shadow page would 2062 * kind of screw things up... 2046 * Take the default action. 2063 2047 */ 2064 int rc = pgmLock(pVM); 2065 AssertRC(rc); 2066 2067 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(&pRomPage->Shadow) != PGM_PAGE_STATE_ALLOCATED)) 2048 case PGMROMPROT_READ_ROM_WRITE_IGNORE: 2049 case PGMROMPROT_READ_RAM_WRITE_IGNORE: 2050 case PGMROMPROT_READ_ROM_WRITE_RAM: 2051 case PGMROMPROT_READ_RAM_WRITE_RAM: 2052 return VINF_PGM_HANDLER_DO_DEFAULT; 2053 2054 default: 2055 AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n", 2056 pRom->aPages[iPage].enmProt, iPage, GCPhys), 2057 VERR_INTERNAL_ERROR); 2058 } 2059 } 2060 else 2061 { 2062 Assert(enmAccessType == PGMACCESSTYPE_WRITE); 2063 switch (pRomPage->enmProt) 2064 { 2065 /* 2066 * Ignore writes. 2067 */ 2068 case PGMROMPROT_READ_ROM_WRITE_IGNORE: 2069 case PGMROMPROT_READ_RAM_WRITE_IGNORE: 2070 return VINF_SUCCESS; 2071 2072 /* 2073 * Write to the ram page. 2074 */ 2075 case PGMROMPROT_READ_ROM_WRITE_RAM: 2076 case PGMROMPROT_READ_RAM_WRITE_RAM: /* yes this will get here too, it's *way* simpler that way. */ 2068 2077 { 2069 rc = pgmPhysPageMakeWritable(pVM, &pRomPage->Shadow, GCPhys); 2070 if (RT_FAILURE(rc)) 2078 /* This should be impossible now, pvPhys doesn't work cross page anylonger. */ 2079 Assert(((GCPhys - pRom->GCPhys + cbBuf - 1) >> PAGE_SHIFT) == iPage); 2080 2081 /* 2082 * Take the lock, do lazy allocation, map the page and copy the data. 2083 * 2084 * Note that we have to bypass the mapping TLB since it works on 2085 * guest physical addresses and entering the shadow page would 2086 * kind of screw things up... 2087 */ 2088 int rc = pgmLock(pVM); 2089 AssertRC(rc); 2090 PPGMPAGE pShadowPage = &pRomPage->Shadow; 2091 if (!PGMROMPROT_IS_ROM(pRomPage->enmProt)) 2071 2092 { 2072 p gmUnlock(pVM);2073 return rc;2093 pShadowPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); 2094 AssertLogRelReturn(pShadowPage, VERR_INTERNAL_ERROR); 2074 2095 } 2075 AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* returned */, ("%Rrc\n", rc)); 2096 2097 if (RT_UNLIKELY(PGM_PAGE_GET_STATE(pShadowPage) != PGM_PAGE_STATE_ALLOCATED)) 2098 { 2099 rc = pgmPhysPageMakeWritable(pVM, pShadowPage, GCPhys); 2100 if (RT_FAILURE(rc)) 2101 { 2102 pgmUnlock(pVM); 2103 return rc; 2104 } 2105 AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 /* returned */, ("%Rrc\n", rc)); 2106 } 2107 2108 void *pvDstPage; 2109 PPGMPAGEMAP pMapIgnored; 2110 int rc2 = pgmPhysPageMap(pVM, pShadowPage, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage); 2111 if (RT_SUCCESS(rc2)) 2112 memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf); 2113 else 2114 rc = rc2; 2115 2116 pgmUnlock(pVM); 2117 return rc; 2076 2118 } 2077 2119 2078 void *pvDstPage; 2079 PPGMPAGEMAP pMapIgnored; 2080 int rc2 = pgmPhysPageMap(pVM, &pRomPage->Shadow, GCPhys & X86_PTE_PG_MASK, &pMapIgnored, &pvDstPage); 2081 if (RT_SUCCESS(rc2)) 2082 memcpy((uint8_t *)pvDstPage + (GCPhys & PAGE_OFFSET_MASK), pvBuf, cbBuf); 2083 else 2084 rc = rc2; 2085 2086 pgmUnlock(pVM); 2087 return rc; 2088 } 2089 2090 default: 2091 AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n", 2092 pRom->aPages[iPage].enmProt, iPage, GCPhys), 2093 VERR_INTERNAL_ERROR); 2120 default: 2121 AssertMsgFailedReturn(("enmProt=%d iPage=%d GCPhys=%RGp\n", 2122 pRom->aPages[iPage].enmProt, iPage, GCPhys), 2123 VERR_INTERNAL_ERROR); 2124 } 2094 2125 } 2095 2126 } … … 2112 2143 const uint32_t cPages = pRom->cb >> PAGE_SHIFT; 2113 2144 2114 if (pRom->fFlags & PGMPHYS_ROM_FLAG _SHADOWED)2145 if (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED) 2115 2146 { 2116 2147 /* … … 2246 2277 if ( GCPhys <= pRom->GCPhysLast 2247 2278 && GCPhysLast >= pRom->GCPhys 2248 && (pRom->fFlags & PGMPHYS_ROM_FLAG _SHADOWED))2279 && (pRom->fFlags & PGMPHYS_ROM_FLAGS_SHADOWED)) 2249 2280 { 2250 2281 /* … … 2254 2285 uint32_t const cPages = pRom->GCPhysLast <= GCPhysLast 2255 2286 ? pRom->cb >> PAGE_SHIFT 2256 : (GCPhysLast - pRom->GCPhys ) >> PAGE_SHIFT;2287 : (GCPhysLast - pRom->GCPhys + 1) >> PAGE_SHIFT; 2257 2288 for (uint32_t iPage = (GCPhys - pRom->GCPhys) >> PAGE_SHIFT; 2258 2289 iPage < cPages; … … 2279 2310 /** @todo preserve the volatile flags (handlers) when these have been moved out of HCPhys! */ 2280 2311 } 2312 pRomPage->enmProt = enmProt; 2281 2313 } 2282 2314
Note:
See TracChangeset
for help on using the changeset viewer.