VirtualBox

Changeset 377 in vbox for trunk


Ignore:
Timestamp:
Jan 27, 2007 3:48:18 AM (18 years ago)
Author:
vboxsync
Message:

vm_map_wire/vm_map_unwire (alternative that didn't make any difference for the deadlock).

Location:
trunk/src/VBox/Runtime/r0drv/darwin
Files:
2 edited

Legend:

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

    r218 r377  
    3434#include "internal/memobj.h"
    3535
     36/*#define USE_VM_MAP_WIRE*/
     37
    3638
    3739/*******************************************************************************
     
    6264    {
    6365        if (pMemDarwin->Core.enmType == RTR0MEMOBJTYPE_LOCK)
    64             pMemDarwin->pMemDesc->complete();
     66            pMemDarwin->pMemDesc->complete(); /* paranoia */
    6567        pMemDarwin->pMemDesc->release();
    6668        pMemDarwin->pMemDesc = NULL;
     
    9092
    9193        case RTR0MEMOBJTYPE_LOCK:
     94        {
     95#ifdef USE_VM_MAP_WIRE
     96            vm_map_t Map = pMemDarwin->Core.u.Lock.Process != NIL_RTPROCESS
     97                         ? get_task_map((task_t)pMemDarwin->Core.u.Lock.Process)
     98                         : kernel_map;
     99            kern_return_t kr = vm_map_unwire(Map,
     100                                             (vm_map_offset_t)pMemDarwin->Core.pv,
     101                                             (vm_map_offset_t)pMemDarwin->Core.pv + pMemDarwin->Core.cb,
     102                                             0 /* not user */);
     103            AssertRC(kr == KERN_SUCCESS); /** @todo don't ignore... */
     104#endif
    92105            break;
     106        }
    93107
    94108        case RTR0MEMOBJTYPE_PHYS:
     
    330344
    331345
    332 int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb)
    333 {
    334     Assert(current_task() != kernel_task);
     346/**
     347 * Internal worker for locking down pages.
     348 *
     349 * @return IPRT status code.
     350 *
     351 * @param ppMem     Where to store the memory object pointer.
     352 * @param pv        First page.
     353 * @param cb        Number of bytes.
     354 * @param Task      The task \a pv and \a cb refers to.
     355 */
     356static int rtR0MemObjNativeLock(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb, task_t Task)
     357{
     358#ifdef USE_VM_MAP_WIRE
     359    vm_map_t Map = get_task_map(Task);
     360    Assert(Map);
     361
     362    /*
     363     * First try lock the memory.
     364     */
     365    int rc = VERR_LOCK_FAILED;
     366    kern_return_t kr = vm_map_wire(get_task_map(Task),
     367                                   (vm_map_offset_t)pv,
     368                                   (vm_map_offset_t)pv + cb,
     369                                   VM_PROT_DEFAULT,
     370                                   0 /* not user */);
     371    if (kr == KERN_SUCCESS)
     372    {
     373        /*
     374         * Create the IPRT memory object.
     375         */
     376        PRTR0MEMOBJDARWIN pMemDarwin = (PRTR0MEMOBJDARWIN)rtR0MemObjNew(sizeof(*pMemDarwin), RTR0MEMOBJTYPE_LOCK, pv, cb);
     377        if (pMemDarwin)
     378        {
     379            pMemDarwin->Core.u.Lock.Process = (RTPROCESS)Task;
     380            *ppMem = &pMemDarwin->Core;
     381            return VINF_SUCCESS;
     382        }
     383        kr = vm_map_unwire(get_task_map(Task), (vm_map_offset_t)pv, (vm_map_offset_t)pv + cb, 0 /* not user */);
     384        Assert(kr == KERN_SUCCESS);
     385        rc = VERR_NO_MEMORY;
     386    }
     387
     388#else
     389
     390    /*
     391     * Create a descriptor and try lock it (prepare).
     392     */
    335393    int rc = VERR_MEMOBJ_INIT_FAILED;
    336     IOMemoryDescriptor *pMemDesc = IOMemoryDescriptor::withAddress((vm_address_t)pv, cb, kIODirectionInOut, current_task());
     394    IOMemoryDescriptor *pMemDesc = IOMemoryDescriptor::withAddress((vm_address_t)pv, cb, kIODirectionInOut, Task);
    337395    if (pMemDesc)
    338396    {
     
    346404            if (pMemDarwin)
    347405            {
    348                 pMemDarwin->Core.u.Lock.Process = (RTPROCESS)current_task();
     406                pMemDarwin->Core.u.Lock.Process = (RTPROCESS)Task;
    349407                pMemDarwin->pMemDesc = pMemDesc;
    350408                *ppMem = &pMemDarwin->Core;
     
    359417        pMemDesc->release();
    360418    }
     419#endif
    361420    return rc;
    362421}
    363422
    364423
     424int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb)
     425{
     426    return rtR0MemObjNativeLock(ppMem, pv, cb, current_task());
     427}
     428
     429
    365430int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb)
    366431{
    367     int rc = VERR_MEMOBJ_INIT_FAILED;
    368     IOMemoryDescriptor *pMemDesc = IOMemoryDescriptor::withAddress((vm_address_t)pv, cb, kIODirectionInOut, kernel_task);
    369     if (pMemDesc)
    370     {
    371         IOReturn IORet = pMemDesc->prepare(kIODirectionInOut);
    372         if (IORet == kIOReturnSuccess)
    373         {
    374             /*
    375              * Create the IPRT memory object.
    376              */
    377             PRTR0MEMOBJDARWIN pMemDarwin = (PRTR0MEMOBJDARWIN)rtR0MemObjNew(sizeof(*pMemDarwin), RTR0MEMOBJTYPE_LOCK, pv, cb);
    378             if (pMemDarwin)
    379             {
    380                 pMemDarwin->Core.u.Lock.Process = NIL_RTPROCESS;
    381                 pMemDarwin->pMemDesc = pMemDesc;
    382                 *ppMem = &pMemDarwin->Core;
    383                 return VINF_SUCCESS;
    384             }
    385 
    386             pMemDesc->complete();
    387             rc = VERR_NO_MEMORY;
    388         }
    389         else
    390             rc = VERR_LOCK_FAILED;
    391         pMemDesc->release();
    392     }
    393     return rc;
     432    return rtR0MemObjNativeLock(ppMem, pv, cb, kernel_task);
    394433}
    395434
     
    496535RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, unsigned iPage)
    497536{
    498     PRTR0MEMOBJDARWIN pMemDarwin = (PRTR0MEMOBJDARWIN)pMem;
    499 
    500     /*
    501      * Get the memory descriptor.
    502      */
    503     IOMemoryDescriptor *pMemDesc = pMemDarwin->pMemDesc;
    504     if (!pMemDesc)
    505         pMemDesc = pMemDarwin->pMemMap->getMemoryDescriptor();
    506     AssertReturn(pMemDesc, NIL_RTHCPHYS);
    507 
    508 
    509     /*
    510      * If we've got a memory descriptor, use getPhysicalSegment64().
    511      */
    512     addr64_t Addr = pMemDesc->getPhysicalSegment64(iPage * PAGE_SIZE, NULL);
    513     AssertMsgReturn(Addr, ("iPage=%u\n", iPage), NIL_RTHCPHYS);
    514     RTHCPHYS PhysAddr = Addr;
    515     AssertMsgReturn(PhysAddr == Addr, ("PhysAddr=%VHp Addr=%RX64\n", PhysAddr, (uint64_t)Addr), NIL_RTHCPHYS);
     537    RTHCPHYS            PhysAddr;
     538    PRTR0MEMOBJDARWIN   pMemDarwin = (PRTR0MEMOBJDARWIN)pMem;
     539
     540#ifdef USE_VM_MAP_WIRE
     541    /*
     542     * Locked memory doesn't have a memory descriptor and
     543     * needs to be handled differently.
     544     */
     545    if (pMemDarwin->Core.enmType == RTR0MEMOBJTYPE_LOCK)
     546    {
     547        ppnum_t PgNo;
     548        if (pMemDarwin->Core.u.Lock.Process == NIL_RTPROCESS)
     549            PgNo = pmap_find_phys(kernel_pmap, (uintptr_t)pMemDarwin->Core.pv + iPage * PAGE_SIZE);
     550        else
     551        {
     552            /*
     553             * From what I can tell, Apple seems to have locked up the all the
     554             * available interfaces that could help us obtain the pmap_t of a task
     555             * or vm_map_t.
     556
     557             * So, we'll have to figure out where in the vm_map_t  structure it is
     558             * and read it our selves. ASSUMING that kernel_pmap is pointed to by
     559             * kernel_map->pmap, we scan kernel_map to locate the structure offset.
     560             * Not nice, but it will hopefully do the job in a reliable manner...
     561             *
     562             * (get_task_pmap, get_map_pmap or vm_map_pmap is what we really need btw.)
     563             */
     564            static int s_offPmap = -1;
     565            if (RT_UNLIKELY(s_offPmap == -1))
     566            {
     567                pmap_t const *p = (pmap_t *)kernel_map;
     568                pmap_t const * const pEnd = p + 64;
     569                for (; p < pEnd; p++)
     570                    if (*p == kernel_pmap)
     571                    {
     572                        s_offPmap = (uintptr_t)p - (uintptr_t)kernel_map;
     573                        break;
     574                    }
     575                AssertReturn(s_offPmap >= 0, NIL_RTHCPHYS);
     576            }
     577            pmap_t Pmap = *(pmap_t *)((uintptr_t)get_task_map((task_t)pMemDarwin->Core.u.Lock.Process) + s_offPmap);
     578            PgNo = pmap_find_phys(Pmap, (uintptr_t)pMemDarwin->Core.pv + iPage * PAGE_SIZE);
     579        }
     580
     581        AssertReturn(PgNo, NIL_RTHCPHYS);
     582        PhysAddr = (RTHCPHYS)PgNo << PAGE_SHIFT;
     583        Assert((PhysAddr >> PAGE_SHIFT) == PgNo);
     584    }
     585    else
     586#endif /* USE_VM_MAP_WIRE */
     587    {
     588        /*
     589         * Get the memory descriptor.
     590         */
     591        IOMemoryDescriptor *pMemDesc = pMemDarwin->pMemDesc;
     592        if (!pMemDesc)
     593            pMemDesc = pMemDarwin->pMemMap->getMemoryDescriptor();
     594        AssertReturn(pMemDesc, NIL_RTHCPHYS);
     595
     596        /*
     597         * If we've got a memory descriptor, use getPhysicalSegment64().
     598         */
     599        addr64_t Addr = pMemDesc->getPhysicalSegment64(iPage * PAGE_SIZE, NULL);
     600        AssertMsgReturn(Addr, ("iPage=%u\n", iPage), NIL_RTHCPHYS);
     601        PhysAddr = Addr;
     602        AssertMsgReturn(PhysAddr == Addr, ("PhysAddr=%VHp Addr=%RX64\n", PhysAddr, (uint64_t)Addr), NIL_RTHCPHYS);
     603    }
     604
    516605    return PhysAddr;
    517606}
  • trunk/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h

    r217 r377  
    5252#include <libkern/libkern.h>
    5353#include <mach/thread_act.h>
     54#include <mach/vm_map.h>
    5455#include <pexpert/pexpert.h>
    5556#include <sys/conf.h>
     
    6566
    6667__BEGIN_DECLS
    67 kern_return_t thread_terminate(thread_t);
     68/* mach/vm_types.h */
     69typedef struct pmap *pmap_t;
     70
     71/* vm/vm_kern.h */
     72extern vm_map_t kernel_map;
     73
     74/* vm/pmap.h */
     75extern pmap_t kernel_pmap;
     76
     77/* kern/task.h */
     78extern vm_map_t get_task_map(task_t);
     79
     80/* osfmk/i386/pmap.h */
     81extern ppnum_t pmap_find_phys(pmap_t, addr64_t);
     82
     83/* vm/vm_map.h */
     84extern kern_return_t vm_map_wire(vm_map_t, vm_map_offset_t, vm_map_offset_t, vm_prot_t, boolean_t);
     85extern kern_return_t vm_map_unwire(vm_map_t, vm_map_offset_t, vm_map_offset_t, boolean_t);
     86
     87/* mach/i386/thread_act.h */
     88extern kern_return_t thread_terminate(thread_t);
    6889__END_DECLS
    6990
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