VirtualBox

Changeset 1946 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 5, 2007 10:57:11 AM (18 years ago)
Author:
vboxsync
Message:

PGMReadPhys: return zeros for physical memory that hasn't been allocated yet.

File:
1 edited

Legend:

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

    r1828 r1946  
    718718            {
    719719                unsigned iPage = off >> PAGE_SHIFT;
     720                size_t   cb;
    720721
    721722                /* Physical chunk in dynamically allocated range not present? */
    722723                if (RT_UNLIKELY(!(pCur->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK)))
    723724                {
    724                     int rc;
    725 #ifdef IN_RING3
    726                     if (fGrabbedLock)
     725                    /* Treat it as reserved; return zeros */
     726                    cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
     727                    if (cb >= cbRead)
    727728                    {
    728                         pgmUnlock(pVM);
    729                         rc = pgmr3PhysGrowRange(pVM, GCPhys);
    730                         if (rc == VINF_SUCCESS)
    731                             PGMPhysRead(pVM, GCPhys, pvBuf, cbRead); /* try again; can't assume pCur is still valid (paranoia) */
    732                         return;
     729                        memset(pvBuf, 0, cbRead);
     730                        goto end;
    733731                    }
    734                     rc = pgmr3PhysGrowRange(pVM, GCPhys);
    735 #else
    736                     rc = CTXALLMID(VMM, CallHost)(pVM, VMMCALLHOST_PGM_RAM_GROW_RANGE, GCPhys);
    737 #endif
    738                     if (rc != VINF_SUCCESS)
    739                         goto end;
    740                 }
    741 
    742                 size_t   cb;
    743                 RTHCPHYS HCPhys = pCur->aHCPhys[iPage];
    744                 switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))
    745                 {
    746                     /*
    747                      * Normal memory or ROM.
    748                      */
    749                     case 0:
    750                     case MM_RAM_FLAGS_ROM:
    751                     case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED:
    752                     case MM_RAM_FLAGS_PHYSICAL_WRITE:
    753                     case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE:
    754                     case MM_RAM_FLAGS_VIRTUAL_WRITE:
     732                    memset(pvBuf, 0, cb);
     733                }
     734                else
     735                {
     736                    RTHCPHYS HCPhys = pCur->aHCPhys[iPage];
     737                    switch (HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM))
    755738                    {
    756 #ifdef IN_GC
    757                         void *pvSrc = NULL;
    758                         PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc);
    759                         pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK);
    760 #else
    761                         void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
    762 #endif
    763                         cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    764                         if (cb >= cbRead)
    765                         {
    766 #if defined(IN_RING3) && defined(PGM_PHYSMEMACCESS_CACHING)
    767                             if (cbRead <= 4)
    768                                 pgmPhysCacheAdd(pVM, &pVM->pgm.s.pgmphysreadcache, GCPhys, (uint8_t*)pvSrc);
    769 #endif /* IN_RING3 && PGM_PHYSMEMACCESS_CACHING */
    770                             memcpy(pvBuf, pvSrc, cbRead);
    771                             goto end;
    772                         }
    773                         memcpy(pvBuf, pvSrc, cb);
    774                         break;
    775                     }
    776 
    777                     /*
    778                      * All reserved, nothing there.
    779                      */
    780                     case MM_RAM_FLAGS_RESERVED:
    781                         cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    782                         if (cb >= cbRead)
    783                         {
    784                             memset(pvBuf, 0, cbRead);
    785                             goto end;
    786                         }
    787                         memset(pvBuf, 0, cb);
    788                         break;
    789 
    790                     /*
    791                      * Physical handler.
    792                      */
    793                     case MM_RAM_FLAGS_PHYSICAL_ALL:
    794                     case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_ALL: /** r=bird: MMIO2 isn't in the mask! */
    795                     {
    796                         int rc = VINF_PGM_HANDLER_DO_DEFAULT;
    797                         cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    798 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */
    799 
    800                         /* find and call the handler */
    801                         PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
    802                         if (pNode && pNode->pfnHandlerR3)
    803                         {
    804                             size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;
    805                             if (cbRange < cb)
    806                                 cb = cbRange;
    807                             if (cb > cbRead)
    808                                 cb = cbRead;
    809 
    810                             void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
    811 
    812                             /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
    813                             rc = pNode->pfnHandlerR3(pVM, GCPhys, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pNode->pvUserR3);
    814                         }
    815 #endif /* IN_RING3 */
    816                         if (rc == VINF_PGM_HANDLER_DO_DEFAULT)
     739                        /*
     740                         * Normal memory or ROM.
     741                         */
     742                        case 0:
     743                        case MM_RAM_FLAGS_ROM:
     744                        case MM_RAM_FLAGS_ROM | MM_RAM_FLAGS_RESERVED:
     745                        case MM_RAM_FLAGS_PHYSICAL_WRITE:
     746                        case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_WRITE:
     747                        case MM_RAM_FLAGS_VIRTUAL_WRITE:
    817748                        {
    818749#ifdef IN_GC
     
    823754                            void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
    824755#endif
    825 
     756                            cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    826757                            if (cb >= cbRead)
    827758                            {
     759#if defined(IN_RING3) && defined(PGM_PHYSMEMACCESS_CACHING)
     760                                if (cbRead <= 4)
     761                                    pgmPhysCacheAdd(pVM, &pVM->pgm.s.pgmphysreadcache, GCPhys, (uint8_t*)pvSrc);
     762#endif /* IN_RING3 && PGM_PHYSMEMACCESS_CACHING */
    828763                                memcpy(pvBuf, pvSrc, cbRead);
    829764                                goto end;
    830765                            }
    831766                            memcpy(pvBuf, pvSrc, cb);
     767                            break;
    832768                        }
    833                         else if (cb >= cbRead)
    834                             goto end;
    835                         break;
    836                     }
    837 
    838                     case MM_RAM_FLAGS_VIRTUAL_ALL:
    839                     {
    840                         int rc = VINF_PGM_HANDLER_DO_DEFAULT;
    841                         cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    842 #ifdef IN_RING3 /** @todo deal with this in GC and R0! */
    843                         /* Search the whole tree for matching physical addresses (rather expensive!) */
    844                         PPGMVIRTHANDLER pNode;
    845                         unsigned iPage;
    846                         int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage);
    847                         if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC)
    848                         {
    849                             size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;
    850                             if (cbRange < cb)
    851                                 cb = cbRange;
    852                             if (cb > cbRead)
    853                                 cb = cbRead;
    854                             RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK)
    855                                               + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK);
    856 
    857                             void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
    858 
    859                             /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
    860                             rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0);
    861                         }
    862 #endif /* IN_RING3 */
    863                         if (rc == VINF_PGM_HANDLER_DO_DEFAULT)
    864                         {
    865 #ifdef IN_GC
    866                             void *pvSrc = NULL;
    867                             PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc);
    868                             pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK);
    869 #else
    870                             void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
    871 #endif
     769
     770                        /*
     771                         * All reserved, nothing there.
     772                         */
     773                        case MM_RAM_FLAGS_RESERVED:
     774                            cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    872775                            if (cb >= cbRead)
    873776                            {
    874                                 memcpy(pvBuf, pvSrc, cbRead);
     777                                memset(pvBuf, 0, cbRead);
    875778                                goto end;
    876779                            }
    877                             memcpy(pvBuf, pvSrc, cb);
     780                            memset(pvBuf, 0, cb);
     781                            break;
     782
     783                        /*
     784                         * Physical handler.
     785                         */
     786                        case MM_RAM_FLAGS_PHYSICAL_ALL:
     787                        case MM_RAM_FLAGS_MMIO2 | MM_RAM_FLAGS_PHYSICAL_ALL: /** r=bird: MMIO2 isn't in the mask! */
     788                        {
     789                            int rc = VINF_PGM_HANDLER_DO_DEFAULT;
     790                            cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
     791#ifdef IN_RING3 /** @todo deal with this in GC and R0! */
     792
     793                            /* find and call the handler */
     794                            PPGMPHYSHANDLER pNode = (PPGMPHYSHANDLER)RTAvlroGCPhysRangeGet(&pVM->pgm.s.pTreesHC->PhysHandlers, GCPhys);
     795                            if (pNode && pNode->pfnHandlerR3)
     796                            {
     797                                size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;
     798                                if (cbRange < cb)
     799                                    cb = cbRange;
     800                                if (cb > cbRead)
     801                                    cb = cbRead;
     802
     803                                void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
     804
     805                                /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
     806                                rc = pNode->pfnHandlerR3(pVM, GCPhys, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, pNode->pvUserR3);
     807                            }
     808#endif /* IN_RING3 */
     809                            if (rc == VINF_PGM_HANDLER_DO_DEFAULT)
     810                            {
     811#ifdef IN_GC
     812                                void *pvSrc = NULL;
     813                                PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc);
     814                                pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK);
     815#else
     816                                void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
     817#endif
     818
     819                                if (cb >= cbRead)
     820                                {
     821                                    memcpy(pvBuf, pvSrc, cbRead);
     822                                    goto end;
     823                                }
     824                                memcpy(pvBuf, pvSrc, cb);
     825                            }
     826                            else if (cb >= cbRead)
     827                                goto end;
     828                            break;
    878829                        }
    879                         else if (cb >= cbRead)
    880                             goto end;
    881                         break;
     830
     831                        case MM_RAM_FLAGS_VIRTUAL_ALL:
     832                        {
     833                            int rc = VINF_PGM_HANDLER_DO_DEFAULT;
     834                            cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
     835#ifdef IN_RING3 /** @todo deal with this in GC and R0! */
     836                            /* Search the whole tree for matching physical addresses (rather expensive!) */
     837                            PPGMVIRTHANDLER pNode;
     838                            unsigned iPage;
     839                            int rc2 = pgmHandlerVirtualFindByPhysAddr(pVM, GCPhys, &pNode, &iPage);
     840                            if (VBOX_SUCCESS(rc2) && pNode->pfnHandlerHC)
     841                            {
     842                                size_t cbRange = pNode->Core.KeyLast - GCPhys + 1;
     843                                if (cbRange < cb)
     844                                    cb = cbRange;
     845                                if (cb > cbRead)
     846                                    cb = cbRead;
     847                                RTGCUINTPTR GCPtr = ((RTGCUINTPTR)pNode->GCPtr & PAGE_BASE_GC_MASK)
     848                                                  + (iPage << PAGE_SHIFT) + (off & PAGE_OFFSET_MASK);
     849
     850                                void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
     851
     852                                /** @note Dangerous assumption that HC handlers don't do anything that really requires an EMT lock! */
     853                                rc = pNode->pfnHandlerHC(pVM, (RTGCPTR)GCPtr, pvSrc, pvBuf, cb, PGMACCESSTYPE_READ, 0);
     854                            }
     855#endif /* IN_RING3 */
     856                            if (rc == VINF_PGM_HANDLER_DO_DEFAULT)
     857                            {
     858#ifdef IN_GC
     859                                void *pvSrc = NULL;
     860                                PGMGCDynMapHCPage(pVM, HCPhys & X86_PTE_PAE_PG_MASK, &pvSrc);
     861                                pvSrc = (char *)pvSrc + (off & PAGE_OFFSET_MASK);
     862#else
     863                                void *pvSrc = PGMRAMRANGE_GETHCPTR(pCur, off)
     864#endif
     865                                if (cb >= cbRead)
     866                                {
     867                                    memcpy(pvBuf, pvSrc, cbRead);
     868                                    goto end;
     869                                }
     870                                memcpy(pvBuf, pvSrc, cb);
     871                            }
     872                            else if (cb >= cbRead)
     873                                goto end;
     874                            break;
     875                        }
     876
     877                        /*
     878                         * The rest needs to be taken more carefully.
     879                         */
     880                        default:
     881#if 1                   /** @todo r=bird: Can you do this properly please. */
     882                            /** @todo Try MMIO; quick hack */
     883                            if (cbRead <= 4 && IOMMMIORead(pVM, GCPhys, (uint32_t *)pvBuf, cbRead) == VINF_SUCCESS)
     884                                goto end;
     885#endif
     886
     887                            /** @todo fix me later. */
     888                            AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n",
     889                                                    GCPhys, cbRead,
     890                                                    HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)));
     891                            cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
     892                            break;
    882893                    }
    883 
    884                     /*
    885                      * The rest needs to be taken more carefully.
    886                      */
    887                     default:
    888 #if 1                   /** @todo r=bird: Can you do this properly please. */
    889                         /** @todo Try MMIO; quick hack */
    890                         if (cbRead <= 4 && IOMMMIORead(pVM, GCPhys, (uint32_t *)pvBuf, cbRead) == VINF_SUCCESS)
    891                             goto end;
    892 #endif
    893 
    894                         /** @todo fix me later. */
    895                         AssertReleaseMsgFailed(("Unknown read at %VGp size %d implement the complex physical reading case %x\n",
    896                                                 GCPhys, cbRead,
    897                                                 HCPhys & (MM_RAM_FLAGS_RESERVED | MM_RAM_FLAGS_MMIO | MM_RAM_FLAGS_VIRTUAL_ALL | MM_RAM_FLAGS_PHYSICAL_ALL | MM_RAM_FLAGS_ROM)));
    898                         cb = PAGE_SIZE - (off & PAGE_OFFSET_MASK);
    899                         break;
    900                 }
    901 
     894                }
    902895                cbRead -= cb;
    903896                off    += cb;
Note: See TracChangeset for help on using the changeset viewer.

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