VirtualBox

Changeset 4390 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Aug 27, 2007 3:51:04 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
23952
Message:

The page pool may flush a shadow page table mapping referenced by the faulting instruction before emulating it. Added fallback for this case as it happens with vista here (debug build).

File:
1 edited

Legend:

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

    r4284 r4390  
    4747*   Structures and Typedefs                                                    *
    4848*******************************************************************************/
    49 typedef EMDECL(uint32_t) PFN_EMULATE_PARAM2_UINT32(uint32_t *pu32Param1, uint32_t val2);
    50 typedef EMDECL(uint32_t) PFN_EMULATE_PARAM2(uint32_t *pu32Param1, size_t val2);
    51 typedef EMDECL(uint32_t) PFN_EMULATE_PARAM3(uint32_t *pu32Param1, uint32_t val2, size_t val3);
     49typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM2_UINT32(uint32_t *pu32Param1, uint32_t val2);
     50typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM2(uint32_t *pu32Param1, size_t val2);
     51typedef DECLCALLBACK(uint32_t) PFN_EMULATE_PARAM3(uint32_t *pu32Param1, uint32_t val2, size_t val3);
    5252
    5353
     
    108108}
    109109
    110 inline int emDisCoreOne(PVM pVM, DISCPUSTATE *pCpu, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
     110DECLINLINE(int) emDisCoreOne(PVM pVM, DISCPUSTATE *pCpu, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
    111111{
    112112    return DISCoreOneEx(InstrGC, pCpu->mode, EMReadBytes, pVM, pCpu,  pOpsize);
     
    115115#else
    116116
    117 inline int emDisCoreOne(PVM pVM, DISCPUSTATE *pCpu, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
     117DECLINLINE(int) emDisCoreOne(PVM pVM, DISCPUSTATE *pCpu, RTGCUINTPTR InstrGC, uint32_t *pOpsize)
    118118{
    119119    return DISCoreOne(pCpu, InstrGC, pOpsize);
     
    279279
    280280
    281 inline int emRamRead(PVM pVM, void *pDest, RTGCPTR GCSrc, uint32_t cb)
    282 {
    283 #ifdef IN_GC
    284     return MMGCRamRead(pVM, pDest, GCSrc, cb);
    285 #else
    286     int         rc;
     281DECLINLINE(int) emRamRead(PVM pVM, void *pDest, RTGCPTR GCSrc, uint32_t cb)
     282{
     283    int rc;
     284#ifdef IN_GC
     285    rc = MMGCRamRead(pVM, pDest, GCSrc, cb);
     286    if (RT_LIKELY(rc != VERR_ACCESS_DENIED))
     287        return rc;
     288    /*
     289     * The page pool cache may end up here in some cases because it
     290     * flushed one of the shadow mappings used by the trapping
     291     * instruction and it either flushed the TLB or the CPU reused it.
     292     */
     293#endif
    287294    RTGCPHYS    GCPhys;
    288295    RTGCUINTPTR offset;
    289296
    290     offset = GCSrc & PAGE_OFFSET_MASK;
     297    offset = (RTGCUINTPTR)GCSrc & PAGE_OFFSET_MASK;
    291298
    292299    rc = PGMPhysGCPtr2GCPhys(pVM, GCSrc, &GCPhys);
     
    294301    PGMPhysRead(pVM, GCPhys + offset, pDest, cb);
    295302    return VINF_SUCCESS;
    296 #endif
    297 }
    298 
    299 inline int emRamWrite(PVM pVM, RTGCPTR GCDest, void *pSrc, uint32_t cb)
    300 {
    301 #ifdef IN_GC
    302     return MMGCRamWrite(pVM, GCDest, pSrc, cb);
     303}
     304
     305DECLINLINE(int) emRamWrite(PVM pVM, RTGCPTR GCDest, void *pSrc, uint32_t cb)
     306{
     307#ifdef IN_GC
     308    int rc = MMGCRamWrite(pVM, GCDest, pSrc, cb);
     309    if (RT_LIKELY(rc != VERR_ACCESS_DENIED))
     310        return rc;
     311    /*
     312     * The page pool cache may end up here in some cases because it
     313     * flushed one of the shadow mappings used by the trapping
     314     * instruction and it either flushed the TLB or the CPU reused it.
     315     * We want to play safe here, verifying that we've got write
     316     * access doesn't cost us much (see PGMPhysGCPtr2GCPhys()).
     317     */
     318    uint64_t fFlags;
     319    RTGCPHYS GCPhys;
     320    rc = PGMGstGetPage(pVM, GCDest, &fFlags, &GCPhys);
     321    if (RT_FAILURE(rc))
     322        return rc;
     323    if (    !(fFlags & X86_PTE_RW)
     324        &&  (CPUMGetGuestCR0(pVM) & X86_CR0_WP))
     325        return VERR_ACCESS_DENIED;
     326
     327    PGMPhysWrite(pVM, GCPhys + ((RTGCUINTPTR)GCDest & PAGE_OFFSET_MASK), pSrc, cb);
     328    return VINF_SUCCESS;
     329
    303330#else
     331
    304332    int         rc;
    305333    RTGCPHYS    GCPhys;
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette