VirtualBox

Ignore:
Timestamp:
Jan 27, 2020 10:25:43 AM (5 years ago)
Author:
vboxsync
Message:

IPRT/memobj-r0drv-darwin.cpp: Added support for alignments other than PAGE_SIZE in rtR0MemObjNativeAllocPhys. This allows for large page allocations. bugref:5324

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp

    r82861 r82868  
    144144        case RTR0MEMOBJTYPE_PHYS:
    145145        case RTR0MEMOBJTYPE_PHYS_NC:
    146             return NULL; /* pretend these have no mapping atm. */
     146            if (pMem->pv)
     147                return kernel_map;
     148            return NULL;
    147149
    148150        case RTR0MEMOBJTYPE_LOCK:
     
    454456 *                          UINT64_MAX if it doesn't matter.
    455457 * @param   enmType         The object type.
     458 * @param   uAlignment      The allocation alignment (in bytes).
    456459 */
    457460static int rtR0MemObjNativeAllocWorker(PPRTR0MEMOBJINTERNAL ppMem, size_t cb,
    458461                                       bool fExecutable, bool fContiguous,
    459462                                       mach_vm_address_t PhysMask, uint64_t MaxPhysAddr,
    460                                        RTR0MEMOBJTYPE enmType)
    461 {
     463                                       RTR0MEMOBJTYPE enmType, size_t uAlignment)
     464{
     465    RT_NOREF_PV(uAlignment);
     466    int rc;
     467
    462468    /*
    463469     * Try inTaskWithPhysicalMask first, but since we don't quite trust that it
     
    469475     * The kIOMemoryMapperNone flag is required since 10.8.2 (IOMMU changes?).
    470476     */
    471     int rc;
    472477    size_t cbFudged = cb;
    473478    if (1) /** @todo Figure out why this is broken. Is it only on snow leopard? Seen allocating memory for the VM structure, last page corrupted or inaccessible. */
    474479         cbFudged += PAGE_SIZE;
    475 #if 1
     480
     481    uint64_t uAlignmentActual = uAlignment;
     482
    476483    IOOptionBits fOptions = kIOMemoryKernelUserShared | kIODirectionInOut;
    477484    if (fContiguous)
     
    479486    if (version_major >= 12 /* 12 = 10.8.x = Mountain Kitten */)
    480487        fOptions |= kIOMemoryMapperNone;
    481     IOBufferMemoryDescriptor *pMemDesc = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, fOptions,
    482                                                                                           cbFudged, PhysMask);
    483 #else /* Requires 10.7 SDK, but allows alignment to be specified: */
    484     uint64_t     uAlignment = PAGE_SIZE;
    485     IOOptionBits fOptions   = kIODirectionInOut | kIOMemoryMapperNone;
    486     if (fContiguous || MaxPhysAddr < UINT64_MAX)
    487     {
    488         fOptions  |= kIOMemoryPhysicallyContiguous;
    489         uAlignment = 1;                 /* PhysMask isn't respected if higher. */
    490     }
    491 
    492     IOBufferMemoryDescriptor *pMemDesc = new IOBufferMemoryDescriptor;
    493     if (pMemDesc && !pMemDesc->initWithPhysicalMask(kernel_task, fOptions, cbFudged, uAlignment, PhysMask))
    494     {
    495         pMemDesc->release();
    496         pMemDesc = NULL;
    497     }
     488
     489    /* The public initWithPhysicalMask virtual method appeared in 10.7.0, in
     490       versions 10.5.0 up to 10.7.0 it was private, and 10.4.8-10.5.0 it was
     491       x86 only and didn't have the alignment parameter (slot was different too). */
     492    IOBufferMemoryDescriptor *pMemDesc;
     493#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
     494    if (version_major >= 11 /* 11 = 10.7.x = Lion, could probably allow 10.5.0+ here if we really wanted to. */)
     495    {
     496        if (fContiguous || MaxPhysAddr < UINT64_MAX)
     497        {
     498            fOptions |= kIOMemoryPhysicallyContiguous;
     499            // cannot find any evidence of this: uAlignmentActual = 1; /* PhysMask isn't respected if higher. */
     500        }
     501
     502        pMemDesc = new IOBufferMemoryDescriptor;
     503        if (pMemDesc)
     504        {
     505            if (pMemDesc->initWithPhysicalMask(kernel_task, fOptions, cbFudged, uAlignmentActual, PhysMask))
     506            { /* likely */ }
     507            else
     508            {
     509                pMemDesc->release();
     510                pMemDesc = NULL;
     511            }
     512        }
     513    }
     514    else
    498515#endif
     516        pMemDesc = IOBufferMemoryDescriptor::inTaskWithPhysicalMask(kernel_task, fOptions, cbFudged, PhysMask);
    499517    if (pMemDesc)
    500518    {
     
    528546                        pMemDesc->release();
    529547                        if (PhysMask)
    530                             LogRel(("rtR0MemObjNativeAllocWorker: off=%x Addr=%llx AddrPrev=%llx MaxPhysAddr=%llx PhysMas=%llx fContiguous=%RTbool fOptions=%#x - buggy API!\n",
    531                                     off, Addr, AddrPrev, MaxPhysAddr, PhysMask, fContiguous, fOptions));
     548                        {
     549                            kprintf("rtR0MemObjNativeAllocWorker: off=%zx Addr=%llx AddrPrev=%llx MaxPhysAddr=%llx PhysMas=%llx fContiguous=%d fOptions=%#x - buggy API!\n",
     550                                    (size_t)off, Addr, AddrPrev, MaxPhysAddr, PhysMask, fContiguous, fOptions);
     551                            LogRel(("rtR0MemObjNativeAllocWorker: off=%zx Addr=%llx AddrPrev=%llx MaxPhysAddr=%llx PhysMas=%llx fContiguous=%RTbool fOptions=%#x - buggy API!\n",
     552                                    (size_t)off, Addr, AddrPrev, MaxPhysAddr, PhysMask, fContiguous, fOptions));
     553                        }
    532554                        return VERR_ADDRESS_TOO_BIG;
    533555                    }
    534556                    AddrPrev = Addr;
     557                }
     558
     559                /*
     560                 * Check that it's aligned correctly.
     561                 */
     562                if ((uintptr_t)pv & (uAlignment - 1))
     563                {
     564                    pMemDesc->complete();
     565                    pMemDesc->release();
     566                    if (PhysMask)
     567                    {
     568                        kprintf("rtR0MemObjNativeAllocWorker: pv=%p uAlignment=%#zx (MaxPhysAddr=%llx PhysMas=%llx fContiguous=%d fOptions=%#x) - buggy API!!\n",
     569                                pv, uAlignment, MaxPhysAddr, PhysMask, fContiguous, fOptions);
     570                        LogRel(("rtR0MemObjNativeAllocWorker: pv=%p uAlignment=%#zx (MaxPhysAddr=%llx PhysMas=%llx fContiguous=%RTbool fOptions=%#x) - buggy API!\n",
     571                                pv, uAlignment, MaxPhysAddr, PhysMask, fContiguous, fOptions));
     572                    }
     573                    return VERR_NOT_SUPPORTED;
    535574                }
    536575
     
    627666
    628667    int rc = rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, false /* fContiguous */,
    629                                          0 /* PhysMask */, UINT64_MAX, RTR0MEMOBJTYPE_PAGE);
     668                                         0 /* PhysMask */, UINT64_MAX, RTR0MEMOBJTYPE_PAGE, PAGE_SIZE);
    630669
    631670    IPRT_DARWIN_RESTORE_EFL_AC();
     
    646685     */
    647686    int rc = rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, false /* fContiguous */,
    648                                          ~(uint32_t)PAGE_OFFSET_MASK, _4G - PAGE_SIZE, RTR0MEMOBJTYPE_LOW);
     687                                         ~(uint32_t)PAGE_OFFSET_MASK, _4G - PAGE_SIZE, RTR0MEMOBJTYPE_LOW, PAGE_SIZE);
    649688    if (rc == VERR_ADDRESS_TOO_BIG)
    650689        rc = rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, false /* fContiguous */,
    651                                          0 /* PhysMask */, _4G - PAGE_SIZE, RTR0MEMOBJTYPE_LOW);
     690                                         0 /* PhysMask */, _4G - PAGE_SIZE, RTR0MEMOBJTYPE_LOW, PAGE_SIZE);
    652691
    653692    IPRT_DARWIN_RESTORE_EFL_AC();
     
    662701    int rc = rtR0MemObjNativeAllocWorker(ppMem, cb, fExecutable, true /* fContiguous */,
    663702                                         ~(uint32_t)PAGE_OFFSET_MASK, _4G - PAGE_SIZE,
    664                                          RTR0MEMOBJTYPE_CONT);
     703                                         RTR0MEMOBJTYPE_CONT, PAGE_SIZE);
    665704
    666705    /*
     
    671710        rc = rtR0MemObjNativeAllocWorker(ppMem, cb + PAGE_SIZE, fExecutable, true /* fContiguous */,
    672711                                         ~(uint32_t)PAGE_OFFSET_MASK, _4G - PAGE_SIZE,
    673                                          RTR0MEMOBJTYPE_CONT);
     712                                         RTR0MEMOBJTYPE_CONT, PAGE_SIZE);
    674713    IPRT_DARWIN_RESTORE_EFL_AC();
    675714    return rc;
     
    679718DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment)
    680719{
    681     /** @todo alignment */
    682720    if (uAlignment != PAGE_SIZE)
    683         return VERR_NOT_SUPPORTED;
     721    {
     722        /* See rtR0MemObjNativeAllocWorker: */
     723        if (version_major < 9 /* 9 = 10.5.x = Snow Leopard */)
     724            return VERR_NOT_SUPPORTED;
     725    }
    684726
    685727    IPRT_DARWIN_SAVE_EFL_AC();
     
    690732    int rc;
    691733    if (PhysHighest == NIL_RTHCPHYS)
    692         rc = rtR0MemObjNativeAllocWorker(ppMem, cb, true /* fExecutable */, true /* fContiguous */,
    693                                          0 /* PhysMask*/, UINT64_MAX, RTR0MEMOBJTYPE_PHYS);
     734        rc = rtR0MemObjNativeAllocWorker(ppMem, cb, false /* fExecutable */, true /* fContiguous */,
     735                                         uAlignment <= PAGE_SIZE ? 0 : ~(mach_vm_address_t)(uAlignment - 1) /* PhysMask*/,
     736                                         UINT64_MAX, RTR0MEMOBJTYPE_PHYS, uAlignment);
    694737    else
    695738    {
     
    699742            PhysMask >>= 1;
    700743        AssertReturn(PhysMask + 1 <= cb, VERR_INVALID_PARAMETER);
    701         PhysMask &= ~(mach_vm_address_t)PAGE_OFFSET_MASK;
    702 
    703         rc = rtR0MemObjNativeAllocWorker(ppMem, cb, true /* fExecutable */, true /* fContiguous */,
    704                                          PhysMask, PhysHighest, RTR0MEMOBJTYPE_PHYS);
     744        PhysMask &= ~(mach_vm_address_t)(uAlignment - 1);
     745
     746        rc = rtR0MemObjNativeAllocWorker(ppMem, cb, false /* fExecutable */, true /* fContiguous */,
     747                                         PhysMask, PhysHighest, RTR0MEMOBJTYPE_PHYS, uAlignment);
    705748    }
    706749
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