- Timestamp:
- Jan 27, 2007 3:48:18 AM (18 years ago)
- 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 34 34 #include "internal/memobj.h" 35 35 36 /*#define USE_VM_MAP_WIRE*/ 37 36 38 37 39 /******************************************************************************* … … 62 64 { 63 65 if (pMemDarwin->Core.enmType == RTR0MEMOBJTYPE_LOCK) 64 pMemDarwin->pMemDesc->complete(); 66 pMemDarwin->pMemDesc->complete(); /* paranoia */ 65 67 pMemDarwin->pMemDesc->release(); 66 68 pMemDarwin->pMemDesc = NULL; … … 90 92 91 93 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 92 105 break; 106 } 93 107 94 108 case RTR0MEMOBJTYPE_PHYS: … … 330 344 331 345 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 */ 356 static 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 */ 335 393 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); 337 395 if (pMemDesc) 338 396 { … … 346 404 if (pMemDarwin) 347 405 { 348 pMemDarwin->Core.u.Lock.Process = (RTPROCESS) current_task();406 pMemDarwin->Core.u.Lock.Process = (RTPROCESS)Task; 349 407 pMemDarwin->pMemDesc = pMemDesc; 350 408 *ppMem = &pMemDarwin->Core; … … 359 417 pMemDesc->release(); 360 418 } 419 #endif 361 420 return rc; 362 421 } 363 422 364 423 424 int rtR0MemObjNativeLockUser(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb) 425 { 426 return rtR0MemObjNativeLock(ppMem, pv, cb, current_task()); 427 } 428 429 365 430 int rtR0MemObjNativeLockKernel(PPRTR0MEMOBJINTERNAL ppMem, void *pv, size_t cb) 366 431 { 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); 394 433 } 395 434 … … 496 535 RTHCPHYS rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, unsigned iPage) 497 536 { 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 516 605 return PhysAddr; 517 606 } -
trunk/src/VBox/Runtime/r0drv/darwin/the-darwin-kernel.h
r217 r377 52 52 #include <libkern/libkern.h> 53 53 #include <mach/thread_act.h> 54 #include <mach/vm_map.h> 54 55 #include <pexpert/pexpert.h> 55 56 #include <sys/conf.h> … … 65 66 66 67 __BEGIN_DECLS 67 kern_return_t thread_terminate(thread_t); 68 /* mach/vm_types.h */ 69 typedef struct pmap *pmap_t; 70 71 /* vm/vm_kern.h */ 72 extern vm_map_t kernel_map; 73 74 /* vm/pmap.h */ 75 extern pmap_t kernel_pmap; 76 77 /* kern/task.h */ 78 extern vm_map_t get_task_map(task_t); 79 80 /* osfmk/i386/pmap.h */ 81 extern ppnum_t pmap_find_phys(pmap_t, addr64_t); 82 83 /* vm/vm_map.h */ 84 extern kern_return_t vm_map_wire(vm_map_t, vm_map_offset_t, vm_map_offset_t, vm_prot_t, boolean_t); 85 extern 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 */ 88 extern kern_return_t thread_terminate(thread_t); 68 89 __END_DECLS 69 90
Note:
See TracChangeset
for help on using the changeset viewer.