VirtualBox

Changeset 104116 in vbox


Ignore:
Timestamp:
Mar 29, 2024 3:06:39 AM (12 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
162523
Message:

VMM/IEM: Darwin fixes for IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER. The header requires more switching between writable and executable memory flags. bugref:10370

File:
1 edited

Legend:

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

    r104115 r104116  
    452452
    453453/**
    454  * Worker for iemExecMemAllocatorAlloc that returns @a pvRet after updating
    455  * the heap statistics.
    456  */
    457 static void *iemExecMemAllocatorAllocTailCode(PIEMEXECMEMALLOCATOR pExecMemAllocator, void *pvRet,
    458                                               uint32_t cbReq, uint32_t idxChunk)
    459 {
    460     pExecMemAllocator->cAllocations += 1;
    461     pExecMemAllocator->cbAllocated  += cbReq;
    462     pExecMemAllocator->cbFree       -= cbReq;
    463     pExecMemAllocator->idxChunkHint  = idxChunk;
    464 
    465 #ifdef RT_OS_DARWIN
    466     /*
    467      * Sucks, but RTMEM_PROT_EXEC and RTMEM_PROT_WRITE are mutually exclusive
    468      * on darwin.  So, we mark the pages returned as read+write after alloc and
    469      * expect the caller to call iemExecMemAllocatorReadyForUse when done
    470      * writing to the allocation.
    471      *
    472      * See also https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon
    473      * for details.
    474      */
    475     /** @todo detect if this is necessary... it wasn't required on 10.15 or
    476      *        whatever older version it was. */
    477     int rc = RTMemProtect(pvRet, cbReq, RTMEM_PROT_WRITE | RTMEM_PROT_READ);
    478     AssertRC(rc);
    479 #endif
    480 
    481     return pvRet;
    482 }
    483 
    484 
     454 * Try allocate a block of @a cReqUnits in the chunk @a idxChunk.
     455 */
    485456static void *iemExecMemAllocatorAllocInChunkInt(PIEMEXECMEMALLOCATOR pExecMemAllocator, uint64_t *pbmAlloc, uint32_t idxFirst,
    486457                                                uint32_t cToScan, uint32_t cReqUnits, uint32_t idxChunk, PIEMTB pTb)
     
    512483            pChunk->idxFreeHint = (uint32_t)iBit + cReqUnits;
    513484
     485            pExecMemAllocator->cAllocations += 1;
     486            uint32_t const cbReq = cReqUnits << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT;
     487            pExecMemAllocator->cbAllocated  += cbReq;
     488            pExecMemAllocator->cbFree       -= cbReq;
     489            pExecMemAllocator->idxChunkHint  = idxChunk;
     490
     491            void * const pvMem = (uint8_t *)pChunk->pvChunk
     492                               + ((idxFirst + (uint32_t)iBit) << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT);
     493#ifdef RT_OS_DARWIN
     494            /*
     495             * Sucks, but RTMEM_PROT_EXEC and RTMEM_PROT_WRITE are mutually exclusive
     496             * on darwin.  So, we mark the pages returned as read+write after alloc and
     497             * expect the caller to call iemExecMemAllocatorReadyForUse when done
     498             * writing to the allocation.
     499             *
     500             * See also https://developer.apple.com/documentation/apple-silicon/porting-just-in-time-compilers-to-apple-silicon
     501             * for details.
     502             */
     503            /** @todo detect if this is necessary... it wasn't required on 10.15 or
     504             *        whatever older version it was. */
     505            int rc = RTMemProtect(pvMem, cbReq, RTMEM_PROT_WRITE | RTMEM_PROT_READ);
     506            AssertRC(rc);
     507#endif
     508
     509            /*
     510             * Initialize the header and return.
     511             */
    514512# ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
    515             PIEMEXECMEMALLOCHDR pHdr = (PIEMEXECMEMALLOCHDR)((uint8_t *)pChunk->pvChunk
    516                                                              + (   (idxFirst + (uint32_t)iBit)
    517                                                                 << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT));
     513            PIEMEXECMEMALLOCHDR const pHdr = (PIEMEXECMEMALLOCHDR)pvMem;
    518514            pHdr->uMagic   = IEMEXECMEMALLOCHDR_MAGIC;
    519515            pHdr->idxChunk = idxChunk;
    520516            pHdr->pTb      = pTb;
    521             return iemExecMemAllocatorAllocTailCode(pExecMemAllocator, pHdr + 1,
    522                                                     cReqUnits << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT, idxChunk);
     517            return pHdr + 1;
    523518#else
    524519            RT_NOREF(pTb);
    525             void * const pvRet  = (uint8_t *)pChunk->pvChunk
    526                                 + ((idxFirst + (uint32_t)iBit) << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT);
    527             return iemExecMemAllocatorAllocTailCode(pExecMemAllocator, pvRet,
    528                                                     cReqUnits << IEMEXECMEM_ALT_SUB_ALLOC_UNIT_SHIFT, idxChunk);
     520            return pvMem;
    529521#endif
    530522        }
     
    657649{
    658650#ifdef RT_OS_DARWIN
    659     /* See iemExecMemAllocatorAllocTailCode for the explanation. */
     651    /* See iemExecMemAllocatorAllocInChunkInt for the explanation. */
    660652    int rc = RTMemProtect(pv, cb, RTMEM_PROT_EXEC | RTMEM_PROT_READ);
    661653    AssertRC(rc); RT_NOREF(pVCpu);
     
    720712                AssertReturnVoid(ASMBitTest(pbmAlloc, idxFirst + i));
    721713            ASMBitClearRange(pbmAlloc, idxFirst, idxFirst + cReqUnits);
     714
    722715#ifdef IEMEXECMEM_ALT_SUB_WITH_ALLOC_HEADER
     716# ifdef RT_OS_DARWIN
     717            int rc = RTMemProtect(pHdr, sizeof(*pHdr), RTMEM_PROT_WRITE | RTMEM_PROT_READ);
     718            AssertRC(rc); RT_NOREF(pVCpu);
     719# endif
    723720            pHdr->uMagic    = 0;
    724721            pHdr->idxChunk  = 0;
    725722            pHdr->pTb       = NULL;
     723# ifdef RT_OS_DARWIN
     724            rc = RTMemProtect(pHdr, sizeof(*pHdr), RTMEM_PROT_EXEC | RTMEM_PROT_READ);
     725            AssertRC(rc); RT_NOREF(pVCpu);
     726# endif
    726727#endif
    727728            pExecMemAllocator->aChunks[idxChunk].cFreeUnits  += cReqUnits;
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