Changeset 39657 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Dec 19, 2011 6:34:13 PM (13 years ago)
- svn:sync-xref-src-repo-rev:
- 75471
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
r39521 r39657 6 6 /* 7 7 * Copyright (c) 2007 knut st. osmundsen <[email protected]> 8 * Copyright (c) 2011 Andriy Gapon <[email protected]> 8 9 * 9 10 * Permission is hereby granted, free of charge, to any person … … 54 55 /** The core structure. */ 55 56 RTR0MEMOBJINTERNAL Core; 56 /** Type dependent data */ 57 union 58 { 59 /** Non physical memory allocations */ 60 struct 61 { 62 /** The VM object associated with the allocation. */ 63 vm_object_t pObject; 64 } NonPhys; 65 /** Physical memory allocations */ 66 struct 67 { 68 /** Number of pages */ 69 uint32_t cPages; 70 /** Array of pages - variable */ 71 vm_page_t apPages[1]; 72 } Phys; 73 } u; 57 /** The VM object associated with the allocation. */ 58 vm_object_t pObject; 74 59 } RTR0MEMOBJFREEBSD, *PRTR0MEMOBJFREEBSD; 75 60 76 61 77 62 MALLOC_DEFINE(M_IPRTMOBJ, "iprtmobj", "IPRT - R0MemObj"); 78 79 80 63 81 64 /** … … 126 109 switch (pMemFreeBSD->Core.enmType) 127 110 { 111 case RTR0MEMOBJTYPE_PAGE: 112 case RTR0MEMOBJTYPE_LOW: 128 113 case RTR0MEMOBJTYPE_CONT: 129 contigfree(pMemFreeBSD->Core.pv, pMemFreeBSD->Core.cb, M_IPRTMOBJ);130 break;131 132 case RTR0MEMOBJTYPE_PAGE:133 114 { 134 115 rc = vm_map_remove(kernel_map, … … 136 117 (vm_offset_t)pMemFreeBSD->Core.pv + pMemFreeBSD->Core.cb); 137 118 AssertMsg(rc == KERN_SUCCESS, ("%#x", rc)); 138 139 vm_page_lock_queues();140 for (uint32_t iPage = 0; iPage < pMemFreeBSD->u.Phys.cPages; iPage++)141 {142 vm_page_t pPage = pMemFreeBSD->u.Phys.apPages[iPage];143 vm_page_unwire(pPage, 0);144 vm_page_free(pPage);145 }146 vm_page_unlock_queues();147 119 break; 148 120 } … … 166 138 { 167 139 vm_map_t pMap = kernel_map; 168 if (pMemFreeBSD->Core.u. Lock.R0Process != NIL_RTR0PROCESS)169 pMap = &((struct proc *)pMemFreeBSD->Core.u. Lock.R0Process)->p_vmspace->vm_map;140 if (pMemFreeBSD->Core.u.ResVirt.R0Process != NIL_RTR0PROCESS) 141 pMap = &((struct proc *)pMemFreeBSD->Core.u.ResVirt.R0Process)->p_vmspace->vm_map; 170 142 rc = vm_map_remove(pMap, 171 143 (vm_offset_t)pMemFreeBSD->Core.pv, … … 181 153 if (pMemFreeBSD->Core.u.Mapping.R0Process != NIL_RTR0PROCESS) 182 154 pMap = &((struct proc *)pMemFreeBSD->Core.u.Mapping.R0Process)->p_vmspace->vm_map; 183 184 155 rc = vm_map_remove(pMap, 185 156 (vm_offset_t)pMemFreeBSD->Core.pv, … … 192 163 case RTR0MEMOBJTYPE_PHYS_NC: 193 164 { 165 VM_OBJECT_LOCK(pMemFreeBSD->pObject); 166 vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0); 194 167 vm_page_lock_queues(); 195 for (uint32_t iPage = 0; iPage < pMemFreeBSD->u.Phys.cPages; iPage++) 168 for (vm_page_t pPage = vm_page_find_least(pMemFreeBSD->pObject, 0); 169 pPage != NULL; 170 pPage = vm_page_next(pPage)) 196 171 { 197 vm_page_t pPage = pMemFreeBSD->u.Phys.apPages[iPage];198 172 vm_page_unwire(pPage, 0); 199 vm_page_free(pPage);200 173 } 201 174 vm_page_unlock_queues(); 175 VM_OBJECT_UNLOCK(pMemFreeBSD->pObject); 176 vm_object_deallocate(pMemFreeBSD->pObject); 202 177 break; 203 178 } 204 179 205 #ifdef USE_KMEM_ALLOC_ATTR206 case RTR0MEMOBJTYPE_LOW:207 {208 kmem_free(kernel_map, (vm_offset_t)pMemFreeBSD->Core.pv, pMemFreeBSD->Core.cb);209 break;210 }211 #else212 case RTR0MEMOBJTYPE_LOW: /* unused */213 #endif214 180 default: 215 181 AssertMsgFailed(("enmType=%d\n", pMemFreeBSD->Core.enmType)); … … 221 187 222 188 189 static vm_page_t rtR0MemObjFreeBSDContigPhysAllocHelper(vm_object_t pObject, vm_pindex_t iPIndex, 190 u_long cPages, vm_paddr_t VmPhysAddrHigh, 191 u_long uAlignment, bool fWire) 192 { 193 vm_page_t pPages; 194 #if __FreeBSD_version > 1000000 195 int fFlags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOBUSY; 196 if (fWire) 197 fFlags |= VM_ALLOC_WIRED; 198 VM_OBJECT_LOCK(pObject); 199 pPages = vm_page_alloc_contig(pObject, iPIndex, fFlags, cPages, 0, VmPhysAddrHigh, uAlignment, 0, VM_MEMATTR_DEFAULT); 200 VM_OBJECT_UNLOCK(pObject); 201 return pPages; 202 #else 203 pPages = vm_phys_alloc_contig(cPages, 0, VmPhysAddrHigh, uAlignment, 0); 204 if (!pPages) 205 return pPages; 206 VM_OBJECT_LOCK(pObject); 207 for (vm_pindex_t iPage = 0; iPage < cPages; iPage++) 208 { 209 vm_page_t pPage = pPages + iPage; 210 vm_page_insert(pPage, pObject, iPIndex + iPage); 211 pPage->valid = VM_PAGE_BITS_ALL; 212 if (fWire) 213 { 214 pPage->wire_count = 1; 215 atomic_add_int(&cnt.v_wire_count, 1); 216 } 217 } 218 VM_OBJECT_UNLOCK(pObject); 219 return pPages; 220 #endif 221 } 222 223 static int rtR0MemObjFreeBSDPhysAllocHelper(vm_object_t pObject, u_long cPages, 224 vm_paddr_t VmPhysAddrHigh, u_long uAlignment, 225 bool fContiguous, bool fWire) 226 { 227 if (fContiguous) 228 { 229 if (rtR0MemObjFreeBSDContigPhysAllocHelper(pObject, 0, cPages, VmPhysAddrHigh, 230 uAlignment, fWire) != NULL) 231 return VINF_SUCCESS; 232 else 233 return VERR_NO_MEMORY; 234 } 235 236 for (vm_pindex_t iPage = 0; iPage < cPages; iPage++) 237 { 238 vm_page_t pPage = rtR0MemObjFreeBSDContigPhysAllocHelper(pObject, iPage, 1, VmPhysAddrHigh, 239 uAlignment, fWire); 240 if (!pPage) 241 { 242 /* Free all allocated pages */ 243 VM_OBJECT_LOCK(pObject); 244 while (iPage-- > 0) 245 { 246 pPage = vm_page_lookup(pObject, iPage); 247 vm_page_lock_queues(); 248 if (fWire) 249 vm_page_unwire(pPage, 0); 250 vm_page_free(pPage); 251 vm_page_unlock_queues(); 252 } 253 VM_OBJECT_UNLOCK(pObject); 254 return VERR_NO_MEMORY; 255 } 256 } 257 return VINF_SUCCESS; 258 } 259 260 static int rtR0MemObjFreeBSDAllocHelper(PRTR0MEMOBJFREEBSD pMemFreeBSD, bool fExecutable, 261 vm_paddr_t VmPhysAddrHigh, bool fContiguous) 262 { 263 int rc; 264 size_t cPages = atop(pMemFreeBSD->Core.cb); 265 266 pMemFreeBSD->pObject = vm_object_allocate(OBJT_PHYS, cPages); 267 vm_offset_t MapAddress; 268 269 /* No additional object reference for auto-deallocation upon unmapping. */ 270 rc = vm_map_find(kernel_map, pMemFreeBSD->pObject, 0, 271 &MapAddress, pMemFreeBSD->Core.cb, VMFS_ANY_SPACE, 272 fExecutable ? VM_PROT_ALL : VM_PROT_RW, VM_PROT_ALL, 0); 273 274 if (rc == KERN_SUCCESS) 275 { 276 rc = rtR0MemObjFreeBSDPhysAllocHelper(pMemFreeBSD->pObject, cPages, 277 VmPhysAddrHigh, PAGE_SIZE, fContiguous, false); 278 if (RT_SUCCESS(rc)) { 279 vm_map_wire(kernel_map, MapAddress, MapAddress + pMemFreeBSD->Core.cb, 280 VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES); 281 282 /* Store start address */ 283 pMemFreeBSD->Core.pv = (void *)MapAddress; 284 return VINF_SUCCESS; 285 } 286 287 vm_map_remove(kernel_map, MapAddress, MapAddress + pMemFreeBSD->Core.cb); 288 } 289 rc = VERR_NO_MEMORY; /** @todo fix translation (borrow from darwin) */ 290 291 vm_object_deallocate(pMemFreeBSD->pObject); 292 rtR0MemObjDelete(&pMemFreeBSD->Core); 293 return rc; 294 } 223 295 DECLHIDDEN(int) rtR0MemObjNativeAllocPage(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable) 224 296 { 225 int rc; 226 size_t cPages = cb >> PAGE_SHIFT; 227 228 /* create the object. */ 229 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(RT_OFFSETOF(RTR0MEMOBJFREEBSD, u.Phys.apPages[cPages]), 297 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), 230 298 RTR0MEMOBJTYPE_PAGE, NULL, cb); 231 299 if (!pMemFreeBSD) 232 300 return VERR_NO_MEMORY; 233 301 234 pMemFreeBSD->u.Phys.cPages = cPages; 235 236 vm_offset_t MapAddress = vm_map_min(kernel_map); 237 rc = vm_map_find(kernel_map, /* map */ 238 NULL, /* object */ 239 0, /* offset */ 240 &MapAddress, /* addr (IN/OUT) */ 241 cb, /* length */ 242 TRUE, /* find_space */ 243 fExecutable /* protection */ 244 ? VM_PROT_ALL 245 : VM_PROT_RW, 246 VM_PROT_ALL, /* max(_prot) */ 247 0); /* cow (copy-on-write) */ 248 if (rc == KERN_SUCCESS) 249 { 250 rc = VINF_SUCCESS; 251 252 for (size_t iPage = 0; iPage < cPages; iPage++) 253 { 254 vm_page_t pPage; 255 256 pPage = vm_page_alloc(NULL, iPage, 257 VM_ALLOC_SYSTEM | 258 VM_ALLOC_WIRED | VM_ALLOC_NOOBJ); 259 260 if (!pPage) 261 { 262 /* 263 * Out of pages 264 * Remove already allocated pages 265 */ 266 while (iPage-- > 0) 267 { 268 pPage = pMemFreeBSD->u.Phys.apPages[iPage]; 269 vm_page_lock_queues(); 270 vm_page_unwire(pPage, 0); 271 vm_page_free(pPage); 272 vm_page_unlock_queues(); 273 } 274 rc = VERR_NO_MEMORY; 275 break; 276 } 277 278 pPage->valid = VM_PAGE_BITS_ALL; 279 pMemFreeBSD->u.Phys.apPages[iPage] = pPage; 280 } 281 282 if (rc == VINF_SUCCESS) 283 { 284 vm_offset_t AddressDst = MapAddress; 285 286 for (size_t iPage = 0; iPage < cPages; iPage++) 287 { 288 vm_page_t pPage = pMemFreeBSD->u.Phys.apPages[iPage]; 289 290 MY_PMAP_ENTER(kernel_map->pmap, AddressDst, pPage, 291 fExecutable 292 ? VM_PROT_ALL 293 : VM_PROT_RW, 294 TRUE); 295 296 AddressDst += PAGE_SIZE; 297 } 298 299 /* Store start address */ 300 pMemFreeBSD->Core.pv = (void *)MapAddress; 301 *ppMem = &pMemFreeBSD->Core; 302 return VINF_SUCCESS; 303 } 304 } 305 rc = VERR_NO_MEMORY; /** @todo fix translation (borrow from darwin) */ 306 307 rtR0MemObjDelete(&pMemFreeBSD->Core); 302 int rc = rtR0MemObjFreeBSDAllocHelper(pMemFreeBSD, fExecutable, ~(vm_paddr_t)0, false); 303 if (RT_FAILURE(rc)) 304 { 305 rtR0MemObjDelete(&pMemFreeBSD->Core); 306 return rc; 307 } 308 309 *ppMem = &pMemFreeBSD->Core; 308 310 return rc; 309 311 } … … 312 314 DECLHIDDEN(int) rtR0MemObjNativeAllocLow(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable) 313 315 { 314 #ifdef USE_KMEM_ALLOC_ATTR 315 /* 316 * Use kmem_alloc_attr, fExectuable is not needed because the 317 * memory will be executable by default 318 */ 319 NOREF(fExecutable); 320 321 /* create the object. */ 322 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), RTR0MEMOBJTYPE_LOW, NULL, cb); 316 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), 317 RTR0MEMOBJTYPE_LOW, NULL, cb); 323 318 if (!pMemFreeBSD) 324 319 return VERR_NO_MEMORY; 325 320 326 pMemFreeBSD->Core.pv = (void *)kmem_alloc_attr(kernel_map, /* Kernel */ 327 cb, /* Amount */ 328 M_ZERO, /* Zero memory */ 329 0, /* Low physical address */ 330 _4G - PAGE_SIZE, /* Highest physical address */ 331 VM_MEMATTR_DEFAULT); /* Default memory attributes */ 332 if (!pMemFreeBSD->Core.pv) 333 return VERR_NO_MEMORY; 321 int rc = rtR0MemObjFreeBSDAllocHelper(pMemFreeBSD, fExecutable, _4G, false); 322 if (RT_FAILURE(rc)) 323 { 324 rtR0MemObjDelete(&pMemFreeBSD->Core); 325 return rc; 326 } 334 327 335 328 *ppMem = &pMemFreeBSD->Core; 336 337 return VINF_SUCCESS;338 #else339 /*340 * Try a Alloc first and see if we get luck, if not try contigmalloc.341 * Might wish to try find our own pages or something later if this342 * turns into a problemspot on AMD64 boxes.343 */344 int rc = rtR0MemObjNativeAllocPage(ppMem, cb, fExecutable);345 if (RT_SUCCESS(rc))346 {347 size_t iPage = cb >> PAGE_SHIFT;348 while (iPage-- > 0)349 if (rtR0MemObjNativeGetPagePhysAddr(*ppMem, iPage) > (_4G - PAGE_SIZE))350 {351 RTR0MemObjFree(*ppMem, false);352 *ppMem = NULL;353 rc = VERR_NO_MEMORY;354 break;355 }356 }357 if (RT_FAILURE(rc))358 rc = rtR0MemObjNativeAllocCont(ppMem, cb, fExecutable);359 329 return rc; 360 #endif361 330 } 362 331 … … 364 333 DECLHIDDEN(int) rtR0MemObjNativeAllocCont(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, bool fExecutable) 365 334 { 366 /* create the object. */367 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD),RTR0MEMOBJTYPE_CONT, NULL, cb);335 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), 336 RTR0MEMOBJTYPE_CONT, NULL, cb); 368 337 if (!pMemFreeBSD) 369 338 return VERR_NO_MEMORY; 370 339 371 /* do the allocation. */ 372 pMemFreeBSD->Core.pv = contigmalloc(cb, /* size */ 373 M_IPRTMOBJ, /* type */ 374 M_NOWAIT | M_ZERO, /* flags */ 375 0, /* lowest physical address*/ 376 _4G-1, /* highest physical address */ 377 PAGE_SIZE, /* alignment. */ 378 0); /* boundary */ 379 if (pMemFreeBSD->Core.pv) 380 { 381 pMemFreeBSD->Core.u.Cont.Phys = vtophys(pMemFreeBSD->Core.pv); 382 *ppMem = &pMemFreeBSD->Core; 383 return VINF_SUCCESS; 384 } 385 386 NOREF(fExecutable); 387 rtR0MemObjDelete(&pMemFreeBSD->Core); 388 return VERR_NO_MEMORY; 389 } 390 391 392 static void rtR0MemObjFreeBSDPhysPageInit(vm_page_t pPage, vm_pindex_t iPage) 393 { 394 #if __FreeBSD_version <= 1000000 395 pPage->wire_count = 1; 396 pPage->pindex = iPage; 397 pPage->act_count = 0; 398 atomic_add_int(&cnt.v_wire_count, 1); 399 400 #if __FreeBSD_version >= 900040 401 Assert(pPage->oflags & VPO_UNMANAGED != 0); 402 #else 403 Assert(pPage->flags & PG_UNMANAGED != 0); 404 #endif 405 #endif 340 int rc = rtR0MemObjFreeBSDAllocHelper(pMemFreeBSD, fExecutable, _4G, true); 341 if (RT_FAILURE(rc)) 342 { 343 rtR0MemObjDelete(&pMemFreeBSD->Core); 344 return rc; 345 } 346 347 pMemFreeBSD->Core.u.Cont.Phys = vtophys(pMemFreeBSD->Core.pv); 348 *ppMem = &pMemFreeBSD->Core; 349 return rc; 406 350 } 407 351 … … 412 356 bool fContiguous) 413 357 { 414 int rc = VINF_SUCCESS; 415 uint32_t cPages = cb >> PAGE_SHIFT; 358 uint32_t cPages = atop(cb); 416 359 vm_paddr_t VmPhysAddrHigh; 417 #if __FreeBSD_version >= 1000001418 int pFlags = VM_ALLOC_INTERRUPT | VM_ALLOC_NOOBJ | VM_ALLOC_WIRED;419 #endif420 360 421 361 /* create the object. */ 422 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew( RT_OFFSETOF(RTR0MEMOBJFREEBSD, u.Phys.apPages[cPages]),362 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), 423 363 enmType, NULL, cb); 424 364 if (!pMemFreeBSD) 425 365 return VERR_NO_MEMORY; 426 366 427 pMemFreeBSD-> u.Phys.cPages = cPages;367 pMemFreeBSD->pObject = vm_object_allocate(OBJT_PHYS, atop(cb)); 428 368 429 369 if (PhysHighest != NIL_RTHCPHYS) … … 432 372 VmPhysAddrHigh = ~(vm_paddr_t)0; 433 373 434 if (fContiguous) 435 { 436 #if __FreeBSD_version >= 1000001 437 vm_page_t pPage = vm_page_alloc_contig(NULL, 0, pFlags, cPages, 0, VmPhysAddrHigh, uAlignment, 0, VM_MEMATTR_DEFAULT); 438 #else 439 vm_page_t pPage = vm_phys_alloc_contig(cPages, 0, VmPhysAddrHigh, uAlignment, 0); 440 #endif 441 442 if (pPage) 443 for (uint32_t iPage = 0; iPage < cPages; iPage++) 444 { 445 rtR0MemObjFreeBSDPhysPageInit(&pPage[iPage], iPage); 446 pMemFreeBSD->u.Phys.apPages[iPage] = &pPage[iPage]; 447 } 448 else 449 rc = VERR_NO_MEMORY; 374 int rc = rtR0MemObjFreeBSDPhysAllocHelper(pMemFreeBSD->pObject, cPages, VmPhysAddrHigh, 375 uAlignment, fContiguous, true); 376 377 if (RT_FAILURE(rc)) { 378 vm_object_deallocate(pMemFreeBSD->pObject); 379 rtR0MemObjDelete(&pMemFreeBSD->Core); 450 380 } 451 381 else 452 382 { 453 /* Allocate page by page */ 454 for (uint32_t iPage = 0; iPage < cPages; iPage++) 455 { 456 #if __FreeBSD_version >= 1000001 457 vm_page_t pPage = vm_page_alloc_contig(NULL, iPage, pFlags, 1, 0, VmPhysAddrHigh, uAlignment, 0, VM_MEMATTR_DEFAULT); 458 #else 459 vm_page_t pPage = vm_phys_alloc_contig(1, 0, VmPhysAddrHigh, uAlignment, 0); 460 #endif 461 462 if (!pPage) 463 { 464 /* Free all allocated pages */ 465 while (iPage-- > 0) 466 { 467 pPage = pMemFreeBSD->u.Phys.apPages[iPage]; 468 vm_page_lock_queues(); 469 vm_page_unwire(pPage, 0); 470 vm_page_free(pPage); 471 vm_page_unlock_queues(); 472 } 473 rc = VERR_NO_MEMORY; 474 break; 475 } 476 rtR0MemObjFreeBSDPhysPageInit(pPage, iPage); 477 pMemFreeBSD->u.Phys.apPages[iPage] = pPage; 478 } 479 } 480 481 if (RT_FAILURE(rc)) 482 rtR0MemObjDelete(&pMemFreeBSD->Core); 483 else 484 { 485 if (enmType == RTR0MEMOBJTYPE_PHYS) 486 { 487 pMemFreeBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(pMemFreeBSD->u.Phys.apPages[0]); 383 if (fContiguous) 384 { 385 Assert(enmType == RTR0MEMOBJTYPE_PHYS); 386 VM_OBJECT_LOCK(pMemFreeBSD->pObject); 387 pMemFreeBSD->Core.u.Phys.PhysBase = VM_PAGE_TO_PHYS(vm_page_find_least(pMemFreeBSD->pObject, 0)); 388 VM_OBJECT_UNLOCK(pMemFreeBSD->pObject); 488 389 pMemFreeBSD->Core.u.Phys.fAllocated = true; 489 390 } … … 498 399 DECLHIDDEN(int) rtR0MemObjNativeAllocPhys(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest, size_t uAlignment) 499 400 { 500 #if 1501 401 return rtR0MemObjFreeBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS, cb, PhysHighest, uAlignment, true); 502 #else503 /* create the object. */504 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(*pMemFreeBSD), RTR0MEMOBJTYPE_CONT, NULL, cb);505 if (!pMemFreeBSD)506 return VERR_NO_MEMORY;507 508 /* do the allocation. */509 pMemFreeBSD->Core.pv = contigmalloc(cb, /* size */510 M_IPRTMOBJ, /* type */511 M_NOWAIT | M_ZERO, /* flags */512 0, /* lowest physical address*/513 _4G-1, /* highest physical address */514 uAlignment, /* alignment. */515 0); /* boundary */516 if (pMemFreeBSD->Core.pv)517 {518 pMemFreeBSD->Core.u.Cont.Phys = vtophys(pMemFreeBSD->Core.pv);519 *ppMem = &pMemFreeBSD->Core;520 return VINF_SUCCESS;521 }522 523 rtR0MemObjDelete(&pMemFreeBSD->Core);524 return VERR_NO_MEMORY;525 #endif526 402 } 527 403 … … 529 405 DECLHIDDEN(int) rtR0MemObjNativeAllocPhysNC(PPRTR0MEMOBJINTERNAL ppMem, size_t cb, RTHCPHYS PhysHighest) 530 406 { 531 #if 1532 407 return rtR0MemObjFreeBSDAllocPhysPages(ppMem, RTR0MEMOBJTYPE_PHYS_NC, cb, PhysHighest, PAGE_SIZE, false); 533 #else534 return VERR_NOT_SUPPORTED;535 #endif536 408 } 537 409 … … 643 515 return VERR_NO_MEMORY; 644 516 645 /* 646 * Allocate an empty VM object and map it into the requested map. 647 */ 648 pMemFreeBSD->u.NonPhys.pObject = vm_object_allocate(OBJT_DEFAULT, cb >> PAGE_SHIFT); 649 if (pMemFreeBSD->u.NonPhys.pObject) 650 { 651 vm_offset_t MapAddress = pvFixed != (void *)-1 652 ? (vm_offset_t)pvFixed 653 : vm_map_min(pMap); 654 if (pvFixed != (void *)-1) 655 vm_map_remove(pMap, 656 MapAddress, 657 MapAddress + cb); 658 659 rc = vm_map_find(pMap, /* map */ 660 pMemFreeBSD->u.NonPhys.pObject, /* object */ 661 0, /* offset */ 662 &MapAddress, /* addr (IN/OUT) */ 663 cb, /* length */ 664 pvFixed == (void *)-1, /* find_space */ 665 VM_PROT_NONE, /* protection */ 666 VM_PROT_ALL, /* max(_prot) ?? */ 667 0); /* cow (copy-on-write) */ 668 if (rc == KERN_SUCCESS) 669 { 670 if (R0Process != NIL_RTR0PROCESS) 671 { 672 rc = vm_map_inherit(pMap, 673 MapAddress, 674 MapAddress + cb, 675 VM_INHERIT_SHARE); 676 AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); 677 } 678 pMemFreeBSD->Core.pv = (void *)MapAddress; 679 pMemFreeBSD->Core.u.ResVirt.R0Process = R0Process; 680 *ppMem = &pMemFreeBSD->Core; 681 return VINF_SUCCESS; 682 } 683 vm_object_deallocate(pMemFreeBSD->u.NonPhys.pObject); 684 rc = VERR_NO_MEMORY; /** @todo fix translation (borrow from darwin) */ 685 } 686 else 687 rc = VERR_NO_MEMORY; 517 vm_offset_t MapAddress = pvFixed != (void *)-1 518 ? (vm_offset_t)pvFixed 519 : vm_map_min(pMap); 520 if (pvFixed != (void *)-1) 521 vm_map_remove(pMap, 522 MapAddress, 523 MapAddress + cb); 524 525 rc = vm_map_find(pMap, /* map */ 526 NULL, /* object */ 527 0, /* offset */ 528 &MapAddress, /* addr (IN/OUT) */ 529 cb, /* length */ 530 pvFixed == (void *)-1 ? VMFS_ANY_SPACE : VMFS_NO_SPACE, 531 /* find_space */ 532 VM_PROT_NONE, /* protection */ 533 VM_PROT_ALL, /* max(_prot) ?? */ 534 0); /* cow (copy-on-write) */ 535 if (rc == KERN_SUCCESS) 536 { 537 if (R0Process != NIL_RTR0PROCESS) 538 { 539 rc = vm_map_inherit(pMap, 540 MapAddress, 541 MapAddress + cb, 542 VM_INHERIT_SHARE); 543 AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); 544 } 545 pMemFreeBSD->Core.pv = (void *)MapAddress; 546 pMemFreeBSD->Core.u.ResVirt.R0Process = R0Process; 547 *ppMem = &pMemFreeBSD->Core; 548 return VINF_SUCCESS; 549 } 550 551 rc = VERR_NO_MEMORY; /** @todo fix translation (borrow from darwin) */ 688 552 rtR0MemObjDelete(&pMemFreeBSD->Core); 689 553 return rc; … … 708 572 unsigned fProt, size_t offSub, size_t cbSub) 709 573 { 710 574 // AssertMsgReturn(!offSub && !cbSub, ("%#x %#x\n", offSub, cbSub), VERR_NOT_SUPPORTED); 711 575 AssertMsgReturn(pvFixed == (void *)-1, ("%p\n", pvFixed), VERR_NOT_SUPPORTED); 712 576 … … 717 581 return VERR_NOT_SUPPORTED; 718 582 719 /* Phys: see pmap_mapdev in i386/i386/pmap.c (http://fxr.watson.org/fxr/source/i386/i386/pmap.c?v=RELENG62#L2860) */720 /** @todo finish the implementation. */721 722 return VERR_NOT_SUPPORTED;723 }724 725 726 /* see http://markmail.org/message/udhq33tefgtyfozs */727 DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, unsigned fProt, RTR0PROCESS R0Process)728 {729 /*730 * Check for unsupported stuff.731 */732 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED);733 AssertMsgReturn(R3PtrFixed == (RTR3PTR)-1, ("%p\n", R3PtrFixed), VERR_NOT_SUPPORTED);734 if (uAlignment > PAGE_SIZE)735 return VERR_NOT_SUPPORTED;736 737 583 int rc; 738 584 PRTR0MEMOBJFREEBSD pMemToMapFreeBSD = (PRTR0MEMOBJFREEBSD)pMemToMap; 739 struct proc *pProc = (struct proc *)R0Process;740 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map;741 585 742 586 /* calc protection */ … … 751 595 ProtectionFlags |= VM_PROT_EXECUTE; 752 596 597 vm_offset_t Addr = vm_map_min(kernel_map); 598 if (cbSub == 0) 599 cbSub = pMemToMap->cb - offSub; 600 601 vm_object_reference(pMemToMapFreeBSD->pObject); 602 rc = vm_map_find(kernel_map, /* Map to insert the object in */ 603 pMemToMapFreeBSD->pObject, /* Object to map */ 604 offSub, /* Start offset in the object */ 605 &Addr, /* Start address IN/OUT */ 606 cbSub, /* Size of the mapping */ 607 VMFS_ANY_SPACE, /* Whether a suitable address should be searched for first */ 608 ProtectionFlags, /* protection flags */ 609 VM_PROT_ALL, /* Maximum protection flags */ 610 0); /* copy-on-write and similar flags */ 611 612 if (rc == KERN_SUCCESS) 613 { 614 rc = vm_map_wire(kernel_map, Addr, Addr + cbSub, VM_MAP_WIRE_SYSTEM|VM_MAP_WIRE_NOHOLES); 615 AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); 616 617 PRTR0MEMOBJFREEBSD pMemFreeBSD = (PRTR0MEMOBJFREEBSD)rtR0MemObjNew(sizeof(RTR0MEMOBJFREEBSD), 618 RTR0MEMOBJTYPE_MAPPING, 619 (void *)Addr, 620 cbSub); 621 if (pMemFreeBSD) 622 { 623 Assert((vm_offset_t)pMemFreeBSD->Core.pv == Addr); 624 pMemFreeBSD->Core.u.Mapping.R0Process = NIL_RTR0PROCESS; 625 *ppMem = &pMemFreeBSD->Core; 626 return VINF_SUCCESS; 627 } 628 rc = vm_map_remove(kernel_map, Addr, Addr + cbSub); 629 AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n")); 630 } 631 else 632 vm_object_deallocate(pMemToMapFreeBSD->pObject); 633 634 return VERR_NO_MEMORY; 635 } 636 637 638 DECLHIDDEN(int) rtR0MemObjNativeMapUser(PPRTR0MEMOBJINTERNAL ppMem, RTR0MEMOBJ pMemToMap, RTR3PTR R3PtrFixed, size_t uAlignment, 639 unsigned fProt, RTR0PROCESS R0Process) 640 { 641 /* 642 * Check for unsupported stuff. 643 */ 644 AssertMsgReturn(R0Process == RTR0ProcHandleSelf(), ("%p != %p\n", R0Process, RTR0ProcHandleSelf()), VERR_NOT_SUPPORTED); 645 if (uAlignment > PAGE_SIZE) 646 return VERR_NOT_SUPPORTED; 647 648 int rc; 649 PRTR0MEMOBJFREEBSD pMemToMapFreeBSD = (PRTR0MEMOBJFREEBSD)pMemToMap; 650 struct proc *pProc = (struct proc *)R0Process; 651 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map; 652 653 /* calc protection */ 654 vm_prot_t ProtectionFlags = 0; 655 if ((fProt & RTMEM_PROT_NONE) == RTMEM_PROT_NONE) 656 ProtectionFlags = VM_PROT_NONE; 657 if ((fProt & RTMEM_PROT_READ) == RTMEM_PROT_READ) 658 ProtectionFlags |= VM_PROT_READ; 659 if ((fProt & RTMEM_PROT_WRITE) == RTMEM_PROT_WRITE) 660 ProtectionFlags |= VM_PROT_WRITE; 661 if ((fProt & RTMEM_PROT_EXEC) == RTMEM_PROT_EXEC) 662 ProtectionFlags |= VM_PROT_EXECUTE; 663 753 664 /* calc mapping address */ 754 PROC_LOCK(pProc); 755 vm_offset_t AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA)); 756 PROC_UNLOCK(pProc); 757 758 /* Insert the object in the map. */ 665 vm_offset_t AddrR3; 666 if (R3PtrFixed == (RTR3PTR)-1) 667 { 668 /** @todo: is this needed?. */ 669 PROC_LOCK(pProc); 670 AddrR3 = round_page((vm_offset_t)pProc->p_vmspace->vm_daddr + lim_max(pProc, RLIMIT_DATA)); 671 PROC_UNLOCK(pProc); 672 } 673 else 674 AddrR3 = (vm_offset_t)R3PtrFixed; 675 676 /* Insert the pObject in the map. */ 677 vm_object_reference(pMemToMapFreeBSD->pObject); 759 678 rc = vm_map_find(pProcMap, /* Map to insert the object in */ 760 NULL,/* Object to map */679 pMemToMapFreeBSD->pObject, /* Object to map */ 761 680 0, /* Start offset in the object */ 762 681 &AddrR3, /* Start address IN/OUT */ 763 682 pMemToMap->cb, /* Size of the mapping */ 764 TRUE, /* Whether a suitable address should be searched for first */ 683 R3PtrFixed == (RTR3PTR)-1 ? VMFS_ANY_SPACE : VMFS_NO_SPACE, 684 /* Whether a suitable address should be searched for first */ 765 685 ProtectionFlags, /* protection flags */ 766 686 VM_PROT_ALL, /* Maximum protection flags */ 767 0); /* Copy on write */ 768 769 /* Map the memory page by page into the destination map. */ 687 0); /* copy-on-write and similar flags */ 688 770 689 if (rc == KERN_SUCCESS) 771 690 { 772 size_t cPages = pMemToMap->cb >> PAGE_SHIFT;; 773 pmap_t pPhysicalMap = pProcMap->pmap; 774 vm_offset_t AddrR3Dst = AddrR3; 775 776 if ( pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS 777 || pMemToMap->enmType == RTR0MEMOBJTYPE_PHYS_NC 778 || pMemToMap->enmType == RTR0MEMOBJTYPE_PAGE) 779 { 780 /* Mapping physical allocations */ 781 Assert(cPages == pMemToMapFreeBSD->u.Phys.cPages); 782 783 /* Insert the memory page by page into the mapping. */ 784 for (uint32_t iPage = 0; iPage < cPages; iPage++) 785 { 786 vm_page_t pPage = pMemToMapFreeBSD->u.Phys.apPages[iPage]; 787 788 MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE); 789 AddrR3Dst += PAGE_SIZE; 790 } 791 } 792 else 793 { 794 /* Mapping cont or low memory types */ 795 vm_offset_t AddrToMap = (vm_offset_t)pMemToMap->pv; 796 797 for (uint32_t iPage = 0; iPage < cPages; iPage++) 798 { 799 vm_page_t pPage = PHYS_TO_VM_PAGE(vtophys(AddrToMap)); 800 801 MY_PMAP_ENTER(pPhysicalMap, AddrR3Dst, pPage, ProtectionFlags, TRUE); 802 AddrR3Dst += PAGE_SIZE; 803 AddrToMap += PAGE_SIZE; 804 } 805 } 806 } 807 808 if (RT_SUCCESS(rc)) 809 { 691 rc = vm_map_wire(pProcMap, AddrR3, AddrR3 + pMemToMap->cb, VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES); 692 AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); 693 694 rc = vm_map_inherit(pProcMap, AddrR3, AddrR3 + pMemToMap->cb, VM_INHERIT_SHARE); 695 AssertMsg(rc == KERN_SUCCESS, ("%#x\n", rc)); 696 810 697 /* 811 698 * Create a mapping object for it. … … 823 710 } 824 711 825 rc = vm_map_remove(pProcMap, ((vm_offset_t)AddrR3), ((vm_offset_t)AddrR3)+ pMemToMap->cb);712 rc = vm_map_remove(pProcMap, AddrR3, AddrR3 + pMemToMap->cb); 826 713 AssertMsg(rc == KERN_SUCCESS, ("Deleting mapping failed\n")); 827 714 } 715 else 716 vm_object_deallocate(pMemToMapFreeBSD->pObject); 828 717 829 718 return VERR_NO_MEMORY; … … 873 762 } 874 763 875 vm_offset_t pb = (vm_offset_t)pMemFreeBSD->Core.pv + (iPage << PAGE_SHIFT);764 vm_offset_t pb = (vm_offset_t)pMemFreeBSD->Core.pv + ptoa(iPage); 876 765 877 766 struct proc *pProc = (struct proc *)pMemFreeBSD->Core.u.Lock.R0Process; 878 767 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map; 879 pmap_t pPhysicalMap = pProcMap->pmap;768 pmap_t pPhysicalMap = vm_map_pmap(pProcMap); 880 769 881 770 return pmap_extract(pPhysicalMap, pb); … … 884 773 case RTR0MEMOBJTYPE_MAPPING: 885 774 { 886 vm_offset_t pb = (vm_offset_t)pMemFreeBSD->Core.pv + (iPage << PAGE_SHIFT);775 vm_offset_t pb = (vm_offset_t)pMemFreeBSD->Core.pv + ptoa(iPage); 887 776 888 777 if (pMemFreeBSD->Core.u.Mapping.R0Process != NIL_RTR0PROCESS) … … 890 779 struct proc *pProc = (struct proc *)pMemFreeBSD->Core.u.Mapping.R0Process; 891 780 struct vm_map *pProcMap = &pProc->p_vmspace->vm_map; 892 pmap_t pPhysicalMap = pProcMap->pmap;781 pmap_t pPhysicalMap = vm_map_pmap(pProcMap); 893 782 894 783 return pmap_extract(pPhysicalMap, pb); … … 897 786 } 898 787 788 case RTR0MEMOBJTYPE_PAGE: 789 case RTR0MEMOBJTYPE_LOW: 790 case RTR0MEMOBJTYPE_PHYS_NC: 791 { 792 RTHCPHYS addr; 793 VM_OBJECT_LOCK(pMemFreeBSD->pObject); 794 addr = VM_PAGE_TO_PHYS(vm_page_lookup(pMemFreeBSD->pObject, iPage)); 795 VM_OBJECT_UNLOCK(pMemFreeBSD->pObject); 796 return addr; 797 } 798 799 case RTR0MEMOBJTYPE_PHYS: 800 return pMemFreeBSD->Core.u.Cont.Phys + ptoa(iPage); 801 899 802 case RTR0MEMOBJTYPE_CONT: 900 return pMemFreeBSD->Core.u.Cont.Phys + (iPage << PAGE_SHIFT); 901 902 case RTR0MEMOBJTYPE_PHYS: 903 return pMemFreeBSD->Core.u.Phys.PhysBase + (iPage << PAGE_SHIFT); 904 905 case RTR0MEMOBJTYPE_PAGE: 906 case RTR0MEMOBJTYPE_PHYS_NC: 907 return VM_PAGE_TO_PHYS(pMemFreeBSD->u.Phys.apPages[iPage]); 908 909 #ifdef USE_KMEM_ALLOC_ATTR 910 case RTR0MEMOBJTYPE_LOW: 911 { 912 vm_offset_t pb = (vm_offset_t)pMemFreeBSD->Core.pv + (iPage << PAGE_SHIFT); 913 return vtophys(pb); 914 } 915 #else 916 case RTR0MEMOBJTYPE_LOW: 917 #endif 803 return pMemFreeBSD->Core.u.Phys.PhysBase + ptoa(iPage); 804 918 805 case RTR0MEMOBJTYPE_RES_VIRT: 919 806 default:
Note:
See TracChangeset
for help on using the changeset viewer.