1/* $NetBSD$ */ 2 3/* 4 * Copyright (c) 1997 Charles D. Cranor and Washington University. 5 * Copyright (c) 1991, 1993, The Regents of the University of California. 6 * 7 * All rights reserved. 8 * 9 * This code is derived from software contributed to Berkeley by 10 * The Mach Operating System project at Carnegie-Mellon University. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. Neither the name of the University nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * 36 * @(#)vm_kern.c 8.3 (Berkeley) 1/12/94 37 * from: Id: uvm_km.c,v 1.1.2.14 1998/02/06 05:19:27 chs Exp 38 * 39 * 40 * Copyright (c) 1987, 1990 Carnegie-Mellon University. 41 * All rights reserved. 42 * 43 * Permission to use, copy, modify and distribute this software and 44 * its documentation is hereby granted, provided that both the copyright 45 * notice and this permission notice appear in all copies of the 46 * software, derivative works or modified versions, and any portions 47 * thereof, and that both notices appear in supporting documentation. 48 * 49 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 50 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 51 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 52 * 53 * Carnegie Mellon requests users of this software to return to 54 * 55 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 56 * School of Computer Science 57 * Carnegie Mellon University 58 * Pittsburgh PA 15213-3890 59 * 60 * any improvements or extensions that they make and grant Carnegie the 61 * rights to redistribute these changes. 62 */ 63 64/* 65 * uvm_km.c: handle kernel memory allocation and management 66 */ 67 68/* 69 * overview of kernel memory management: 70 * 71 * the kernel virtual address space is mapped by "kernel_map." kernel_map 72 * starts at VM_MIN_KERNEL_ADDRESS and goes to VM_MAX_KERNEL_ADDRESS. 73 * note that VM_MIN_KERNEL_ADDRESS is equal to vm_map_min(kernel_map). 74 * 75 * the kernel_map has several "submaps." submaps can only appear in 76 * the kernel_map (user processes can't use them). submaps "take over" 77 * the management of a sub-range of the kernel's address space. submaps 78 * are typically allocated at boot time and are never released. kernel 79 * virtual address space that is mapped by a submap is locked by the 80 * submap's lock -- not the kernel_map's lock. 81 * 82 * thus, the useful feature of submaps is that they allow us to break 83 * up the locking and protection of the kernel address space into smaller 84 * chunks. 85 * 86 * the vm system has several standard kernel submaps, including: 87 * pager_map => used to map "buf" structures into kernel space 88 * exec_map => used during exec to handle exec args 89 * etc... 90 * 91 * the kernel allocates its private memory out of special uvm_objects whose 92 * reference count is set to UVM_OBJ_KERN (thus indicating that the objects 93 * are "special" and never die). all kernel objects should be thought of 94 * as large, fixed-sized, sparsely populated uvm_objects. each kernel 95 * object is equal to the size of kernel virtual address space (i.e. the 96 * value "VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS"). 97 * 98 * note that just because a kernel object spans the entire kernel virtual 99 * address space doesn't mean that it has to be mapped into the entire space. 100 * large chunks of a kernel object's space go unused either because 101 * that area of kernel VM is unmapped, or there is some other type of 102 * object mapped into that range (e.g. a vnode). for submap's kernel 103 * objects, the only part of the object that can ever be populated is the 104 * offsets that are managed by the submap. 105 * 106 * note that the "offset" in a kernel object is always the kernel virtual 107 * address minus the VM_MIN_KERNEL_ADDRESS (aka vm_map_min(kernel_map)). 108 * example: 109 * suppose VM_MIN_KERNEL_ADDRESS is 0xf8000000 and the kernel does a 110 * uvm_km_alloc(kernel_map, PAGE_SIZE) [allocate 1 wired down page in the 111 * kernel map]. if uvm_km_alloc returns virtual address 0xf8235000, 112 * then that means that the page at offset 0x235000 in kernel_object is 113 * mapped at 0xf8235000. 114 * 115 * kernel object have one other special property: when the kernel virtual 116 * memory mapping them is unmapped, the backing memory in the object is 117 * freed right away. this is done with the uvm_km_pgremove() function. 118 * this has to be done because there is no backing store for kernel pages 119 * and no need to save them after they are no longer referenced. 120 */ 121 122#include <sys/cdefs.h> 123__KERNEL_RCSID(0, "$NetBSD$"); 124 125#include "opt_uvmhist.h" 126 127#include "opt_kmempages.h" 128 129#ifndef NKMEMPAGES 130#define NKMEMPAGES 0 131#endif 132 133/* 134 * Defaults for lower and upper-bounds for the kmem_arena page count. 135 * Can be overridden by kernel config options. 136 */ 137#ifndef NKMEMPAGES_MIN 138#define NKMEMPAGES_MIN NKMEMPAGES_MIN_DEFAULT 139#endif 140 141#ifndef NKMEMPAGES_MAX 142#define NKMEMPAGES_MAX NKMEMPAGES_MAX_DEFAULT 143#endif 144 145 146#include <sys/param.h> 147#include <sys/systm.h> 148#include <sys/proc.h> 149#include <sys/pool.h> 150#include <sys/vmem.h> 151#include <sys/kmem.h> 152 153#include <uvm/uvm.h> 154 155/* 156 * global data structures 157 */ 158 159struct vm_map *kernel_map = NULL; 160 161/* 162 * local data structues 163 */ 164 165static struct vm_map kernel_map_store; 166static struct vm_map_entry kernel_image_mapent_store; 167static struct vm_map_entry kernel_kmem_mapent_store; 168 169int nkmempages = 0; 170vaddr_t kmembase; 171vsize_t kmemsize; 172 173vmem_t *kmem_arena = NULL; 174vmem_t *kmem_va_arena; 175 176/* 177 * kmeminit_nkmempages: calculate the size of kmem_arena. 178 */ 179void 180kmeminit_nkmempages(void) 181{ 182 int npages; 183 184 if (nkmempages != 0) { 185 /* 186 * It's already been set (by us being here before) 187 * bail out now; 188 */ 189 return; 190 } 191 192#if defined(PMAP_MAP_POOLPAGE) 193 npages = (physmem / 4); 194#else 195 npages = (physmem / 3) * 2; 196#endif /* defined(PMAP_MAP_POOLPAGE) */ 197 198#ifndef NKMEMPAGES_MAX_UNLIMITED 199 if (npages > NKMEMPAGES_MAX) 200 npages = NKMEMPAGES_MAX; 201#endif 202 203 if (npages < NKMEMPAGES_MIN) 204 npages = NKMEMPAGES_MIN; 205 206 nkmempages = npages; 207} 208 209/* 210 * uvm_km_bootstrap: init kernel maps and objects to reflect reality (i.e. 211 * KVM already allocated for text, data, bss, and static data structures). 212 * 213 * => KVM is defined by VM_MIN_KERNEL_ADDRESS/VM_MAX_KERNEL_ADDRESS. 214 * we assume that [vmin -> start] has already been allocated and that 215 * "end" is the end. 216 */ 217 218void 219uvm_km_bootstrap(vaddr_t start, vaddr_t end) 220{ 221 bool kmem_arena_small; 222 vaddr_t base = VM_MIN_KERNEL_ADDRESS; 223 struct uvm_map_args args; 224 int error; 225 226 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 227 UVMHIST_LOG(maphist, "start=%"PRIxVADDR" end=%#"PRIxVADDR, 228 start, end, 0,0); 229 230 kmeminit_nkmempages(); 231 kmemsize = (vsize_t)nkmempages * PAGE_SIZE; 232 kmem_arena_small = kmemsize < 64 * 1024 * 1024; 233 234 UVMHIST_LOG(maphist, "kmemsize=%#"PRIxVSIZE, kmemsize, 0,0,0); 235 236 /* 237 * next, init kernel memory objects. 238 */ 239 240 /* kernel_object: for pageable anonymous kernel memory */ 241 uvm_kernel_object = uao_create(VM_MAX_KERNEL_ADDRESS - 242 VM_MIN_KERNEL_ADDRESS, UAO_FLAG_KERNOBJ); 243 244 /* 245 * init the map and reserve any space that might already 246 * have been allocated kernel space before installing. 247 */ 248 249 uvm_map_setup(&kernel_map_store, base, end, VM_MAP_PAGEABLE); 250 kernel_map_store.pmap = pmap_kernel(); 251 if (start != base) { 252 error = uvm_map_prepare(&kernel_map_store, 253 base, start - base, 254 NULL, UVM_UNKNOWN_OFFSET, 0, 255 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, 256 UVM_ADV_RANDOM, UVM_FLAG_FIXED), &args); 257 if (!error) { 258 kernel_image_mapent_store.flags = 259 UVM_MAP_KERNEL | UVM_MAP_STATIC | UVM_MAP_NOMERGE; 260 error = uvm_map_enter(&kernel_map_store, &args, 261 &kernel_image_mapent_store); 262 } 263 264 if (error) 265 panic( 266 "uvm_km_bootstrap: could not reserve space for kernel"); 267 268 kmembase = args.uma_start + args.uma_size; 269 } else { 270 kmembase = base; 271 } 272 273 error = uvm_map_prepare(&kernel_map_store, 274 kmembase, kmemsize, 275 NULL, UVM_UNKNOWN_OFFSET, 0, 276 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, 277 UVM_ADV_RANDOM, UVM_FLAG_FIXED), &args); 278 if (!error) { 279 kernel_kmem_mapent_store.flags = 280 UVM_MAP_KERNEL | UVM_MAP_STATIC | UVM_MAP_NOMERGE; 281 error = uvm_map_enter(&kernel_map_store, &args, 282 &kernel_kmem_mapent_store); 283 } 284 285 if (error) 286 panic("uvm_km_bootstrap: could not reserve kernel kmem"); 287 288 /* 289 * install! 290 */ 291 292 kernel_map = &kernel_map_store; 293 294 pool_subsystem_init(); 295 vmem_bootstrap(); 296 297 kmem_arena = vmem_create("kmem", kmembase, kmemsize, PAGE_SIZE, 298 NULL, NULL, NULL, 299 0, VM_NOSLEEP | VM_BOOTSTRAP, IPL_VM); 300#ifdef PMAP_GROWKERNEL 301 /* 302 * kmem_arena VA allocations happen independently of uvm_map. 303 * grow kernel to accommodate the kmem_arena. 304 */ 305 if (uvm_maxkaddr < kmembase + kmemsize) { 306 uvm_maxkaddr = pmap_growkernel(kmembase + kmemsize); 307 KASSERTMSG(uvm_maxkaddr >= kmembase + kmemsize, 308 "%#"PRIxVADDR" %#"PRIxVADDR" %#"PRIxVSIZE, 309 uvm_maxkaddr, kmembase, kmemsize); 310 } 311#endif 312 313 vmem_init(kmem_arena); 314 315 UVMHIST_LOG(maphist, "kmem vmem created (base=%#"PRIxVADDR 316 ", size=%#"PRIxVSIZE, kmembase, kmemsize, 0,0); 317 318 kmem_va_arena = vmem_create("kva", 0, 0, PAGE_SIZE, 319 vmem_alloc, vmem_free, kmem_arena, 320 (kmem_arena_small ? 4 : 8) * PAGE_SIZE, 321 VM_NOSLEEP | VM_BOOTSTRAP, IPL_VM); 322 323 UVMHIST_LOG(maphist, "<- done", 0,0,0,0); 324} 325 326/* 327 * uvm_km_init: init the kernel maps virtual memory caches 328 * and start the pool/kmem allocator. 329 */ 330void 331uvm_km_init(void) 332{ 333 334 kmem_init(); 335 336 kmeminit(); // killme 337} 338 339/* 340 * uvm_km_suballoc: allocate a submap in the kernel map. once a submap 341 * is allocated all references to that area of VM must go through it. this 342 * allows the locking of VAs in kernel_map to be broken up into regions. 343 * 344 * => if `fixed' is true, *vmin specifies where the region described 345 * pager_map => used to map "buf" structures into kernel space 346 * by the submap must start 347 * => if submap is non NULL we use that as the submap, otherwise we 348 * alloc a new map 349 */ 350 351struct vm_map * 352uvm_km_suballoc(struct vm_map *map, vaddr_t *vmin /* IN/OUT */, 353 vaddr_t *vmax /* OUT */, vsize_t size, int flags, bool fixed, 354 struct vm_map *submap) 355{ 356 int mapflags = UVM_FLAG_NOMERGE | (fixed ? UVM_FLAG_FIXED : 0); 357 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 358 359 KASSERT(vm_map_pmap(map) == pmap_kernel()); 360 361 size = round_page(size); /* round up to pagesize */ 362 363 /* 364 * first allocate a blank spot in the parent map 365 */ 366 367 if (uvm_map(map, vmin, size, NULL, UVM_UNKNOWN_OFFSET, 0, 368 UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, 369 UVM_ADV_RANDOM, mapflags)) != 0) { 370 panic("%s: unable to allocate space in parent map", __func__); 371 } 372 373 /* 374 * set VM bounds (vmin is filled in by uvm_map) 375 */ 376 377 *vmax = *vmin + size; 378 379 /* 380 * add references to pmap and create or init the submap 381 */ 382 383 pmap_reference(vm_map_pmap(map)); 384 if (submap == NULL) { 385 submap = kmem_alloc(sizeof(*submap), KM_SLEEP); 386 if (submap == NULL) 387 panic("uvm_km_suballoc: unable to create submap"); 388 } 389 uvm_map_setup(submap, *vmin, *vmax, flags); 390 submap->pmap = vm_map_pmap(map); 391 392 /* 393 * now let uvm_map_submap plug in it... 394 */ 395 396 if (uvm_map_submap(map, *vmin, *vmax, submap) != 0) 397 panic("uvm_km_suballoc: submap allocation failed"); 398 399 return(submap); 400} 401 402/* 403 * uvm_km_pgremove: remove pages from a kernel uvm_object and KVA. 404 */ 405 406void 407uvm_km_pgremove(vaddr_t startva, vaddr_t endva) 408{ 409 struct uvm_object * const uobj = uvm_kernel_object; 410 const voff_t start = startva - vm_map_min(kernel_map); 411 const voff_t end = endva - vm_map_min(kernel_map); 412 struct vm_page *pg; 413 voff_t curoff, nextoff; 414 int swpgonlydelta = 0; 415 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 416 417 KASSERT(VM_MIN_KERNEL_ADDRESS <= startva); 418 KASSERT(startva < endva); 419 KASSERT(endva <= VM_MAX_KERNEL_ADDRESS); 420 421 mutex_enter(uobj->vmobjlock); 422 pmap_remove(pmap_kernel(), startva, endva); 423 for (curoff = start; curoff < end; curoff = nextoff) { 424 nextoff = curoff + PAGE_SIZE; 425 pg = uvm_pagelookup(uobj, curoff); 426 if (pg != NULL && pg->flags & PG_BUSY) { 427 pg->flags |= PG_WANTED; 428 UVM_UNLOCK_AND_WAIT(pg, uobj->vmobjlock, 0, 429 "km_pgrm", 0); 430 mutex_enter(uobj->vmobjlock); 431 nextoff = curoff; 432 continue; 433 } 434 435 /* 436 * free the swap slot, then the page. 437 */ 438 439 if (pg == NULL && 440 uao_find_swslot(uobj, curoff >> PAGE_SHIFT) > 0) { 441 swpgonlydelta++; 442 } 443 uao_dropswap(uobj, curoff >> PAGE_SHIFT); 444 if (pg != NULL) { 445 mutex_enter(&uvm_pageqlock); 446 uvm_pagefree(pg); 447 mutex_exit(&uvm_pageqlock); 448 } 449 } 450 mutex_exit(uobj->vmobjlock); 451 452 if (swpgonlydelta > 0) { 453 mutex_enter(&uvm_swap_data_lock); 454 KASSERT(uvmexp.swpgonly >= swpgonlydelta); 455 uvmexp.swpgonly -= swpgonlydelta; 456 mutex_exit(&uvm_swap_data_lock); 457 } 458} 459 460 461/* 462 * uvm_km_pgremove_intrsafe: like uvm_km_pgremove(), but for non object backed 463 * regions. 464 * 465 * => when you unmap a part of anonymous kernel memory you want to toss 466 * the pages right away. (this is called from uvm_unmap_...). 467 * => none of the pages will ever be busy, and none of them will ever 468 * be on the active or inactive queues (because they have no object). 469 */ 470 471void 472uvm_km_pgremove_intrsafe(struct vm_map *map, vaddr_t start, vaddr_t end) 473{ 474#define __PGRM_BATCH 16 475 struct vm_page *pg; 476 paddr_t pa[__PGRM_BATCH]; 477 int npgrm, i; 478 vaddr_t va, batch_vastart; 479 480 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 481 482 KASSERT(VM_MAP_IS_KERNEL(map)); 483 KASSERT(vm_map_min(map) <= start); 484 KASSERT(start < end); 485 KASSERT(end <= vm_map_max(map)); 486 487 for (va = start; va < end;) { 488 batch_vastart = va; 489 /* create a batch of at most __PGRM_BATCH pages to free */ 490 for (i = 0; 491 i < __PGRM_BATCH && va < end; 492 va += PAGE_SIZE) { 493 if (!pmap_extract(pmap_kernel(), va, &pa[i])) { 494 continue; 495 } 496 i++; 497 } 498 npgrm = i; 499 /* now remove the mappings */ 500 pmap_kremove(batch_vastart, PAGE_SIZE * npgrm); 501 /* and free the pages */ 502 for (i = 0; i < npgrm; i++) { 503 pg = PHYS_TO_VM_PAGE(pa[i]); 504 KASSERT(pg); 505 KASSERT(pg->uobject == NULL && pg->uanon == NULL); 506 KASSERT((pg->flags & PG_BUSY) == 0); 507 uvm_pagefree(pg); 508 } 509 } 510#undef __PGRM_BATCH 511} 512 513#if defined(DEBUG) 514void 515uvm_km_check_empty(struct vm_map *map, vaddr_t start, vaddr_t end) 516{ 517 struct vm_page *pg; 518 vaddr_t va; 519 paddr_t pa; 520 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 521 522 KDASSERT(VM_MAP_IS_KERNEL(map)); 523 KDASSERT(vm_map_min(map) <= start); 524 KDASSERT(start < end); 525 KDASSERT(end <= vm_map_max(map)); 526 527 for (va = start; va < end; va += PAGE_SIZE) { 528 if (pmap_extract(pmap_kernel(), va, &pa)) { 529 panic("uvm_km_check_empty: va %p has pa 0x%llx", 530 (void *)va, (long long)pa); 531 } 532 if ((map->flags & VM_MAP_INTRSAFE) == 0) { 533 mutex_enter(uvm_kernel_object->vmobjlock); 534 pg = uvm_pagelookup(uvm_kernel_object, 535 va - vm_map_min(kernel_map)); 536 mutex_exit(uvm_kernel_object->vmobjlock); 537 if (pg) { 538 panic("uvm_km_check_empty: " 539 "has page hashed at %p", (const void *)va); 540 } 541 } 542 } 543} 544#endif /* defined(DEBUG) */ 545 546/* 547 * uvm_km_alloc: allocate an area of kernel memory. 548 * 549 * => NOTE: we can return 0 even if we can wait if there is not enough 550 * free VM space in the map... caller should be prepared to handle 551 * this case. 552 * => we return KVA of memory allocated 553 */ 554 555vaddr_t 556uvm_km_alloc(struct vm_map *map, vsize_t size, vsize_t align, uvm_flag_t flags) 557{ 558 vaddr_t kva, loopva; 559 vaddr_t offset; 560 vsize_t loopsize; 561 struct vm_page *pg; 562 struct uvm_object *obj; 563 int pgaflags; 564 vm_prot_t prot; 565 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 566 567 KASSERT(vm_map_pmap(map) == pmap_kernel()); 568 KASSERT((flags & UVM_KMF_TYPEMASK) == UVM_KMF_WIRED || 569 (flags & UVM_KMF_TYPEMASK) == UVM_KMF_PAGEABLE || 570 (flags & UVM_KMF_TYPEMASK) == UVM_KMF_VAONLY); 571 KASSERT((flags & UVM_KMF_VAONLY) != 0 || (flags & UVM_KMF_COLORMATCH) == 0); 572 KASSERT((flags & UVM_KMF_COLORMATCH) == 0 || (flags & UVM_KMF_VAONLY) != 0); 573 574 /* 575 * setup for call 576 */ 577 578 kva = vm_map_min(map); /* hint */ 579 size = round_page(size); 580 obj = (flags & UVM_KMF_PAGEABLE) ? uvm_kernel_object : NULL; 581 UVMHIST_LOG(maphist," (map=0x%x, obj=0x%x, size=0x%x, flags=%d)", 582 map, obj, size, flags); 583 584 /* 585 * allocate some virtual space 586 */ 587 588 if (__predict_false(uvm_map(map, &kva, size, obj, UVM_UNKNOWN_OFFSET, 589 align, UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, 590 UVM_ADV_RANDOM, 591 (flags & (UVM_KMF_TRYLOCK | UVM_KMF_NOWAIT | UVM_KMF_WAITVA 592 | UVM_KMF_COLORMATCH)))) != 0)) { 593 UVMHIST_LOG(maphist, "<- done (no VM)",0,0,0,0); 594 return(0); 595 } 596 597 /* 598 * if all we wanted was VA, return now 599 */ 600 601 if (flags & (UVM_KMF_VAONLY | UVM_KMF_PAGEABLE)) { 602 UVMHIST_LOG(maphist,"<- done valloc (kva=0x%x)", kva,0,0,0); 603 return(kva); 604 } 605 606 /* 607 * recover object offset from virtual address 608 */ 609 610 offset = kva - vm_map_min(kernel_map); 611 UVMHIST_LOG(maphist, " kva=0x%x, offset=0x%x", kva, offset,0,0); 612 613 /* 614 * now allocate and map in the memory... note that we are the only ones 615 * whom should ever get a handle on this area of VM. 616 */ 617 618 loopva = kva; 619 loopsize = size; 620 621 pgaflags = UVM_FLAG_COLORMATCH; 622 if (flags & UVM_KMF_NOWAIT) 623 pgaflags |= UVM_PGA_USERESERVE; 624 if (flags & UVM_KMF_ZERO) 625 pgaflags |= UVM_PGA_ZERO; 626 prot = VM_PROT_READ | VM_PROT_WRITE; 627 if (flags & UVM_KMF_EXEC) 628 prot |= VM_PROT_EXECUTE; 629 while (loopsize) { 630 KASSERTMSG(!pmap_extract(pmap_kernel(), loopva, NULL), 631 "loopva=%#"PRIxVADDR, loopva); 632 633 pg = uvm_pagealloc_strat(NULL, offset, NULL, pgaflags, 634#ifdef UVM_KM_VMFREELIST 635 UVM_PGA_STRAT_ONLY, UVM_KM_VMFREELIST 636#else 637 UVM_PGA_STRAT_NORMAL, 0 638#endif 639 ); 640 641 /* 642 * out of memory? 643 */ 644 645 if (__predict_false(pg == NULL)) { 646 if ((flags & UVM_KMF_NOWAIT) || 647 ((flags & UVM_KMF_CANFAIL) && !uvm_reclaimable())) { 648 /* free everything! */ 649 uvm_km_free(map, kva, size, 650 flags & UVM_KMF_TYPEMASK); 651 return (0); 652 } else { 653 uvm_wait("km_getwait2"); /* sleep here */ 654 continue; 655 } 656 } 657 658 pg->flags &= ~PG_BUSY; /* new page */ 659 UVM_PAGE_OWN(pg, NULL); 660 661 /* 662 * map it in 663 */ 664 665 pmap_kenter_pa(loopva, VM_PAGE_TO_PHYS(pg), 666 prot, PMAP_KMPAGE); 667 loopva += PAGE_SIZE; 668 offset += PAGE_SIZE; 669 loopsize -= PAGE_SIZE; 670 } 671 672 pmap_update(pmap_kernel()); 673 674 UVMHIST_LOG(maphist,"<- done (kva=0x%x)", kva,0,0,0); 675 return(kva); 676} 677 678/* 679 * uvm_km_free: free an area of kernel memory 680 */ 681 682void 683uvm_km_free(struct vm_map *map, vaddr_t addr, vsize_t size, uvm_flag_t flags) 684{ 685 UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist); 686 687 KASSERT((flags & UVM_KMF_TYPEMASK) == UVM_KMF_WIRED || 688 (flags & UVM_KMF_TYPEMASK) == UVM_KMF_PAGEABLE || 689 (flags & UVM_KMF_TYPEMASK) == UVM_KMF_VAONLY); 690 KASSERT((addr & PAGE_MASK) == 0); 691 KASSERT(vm_map_pmap(map) == pmap_kernel()); 692 693 size = round_page(size); 694 695 if (flags & UVM_KMF_PAGEABLE) { 696 uvm_km_pgremove(addr, addr + size); 697 } else if (flags & UVM_KMF_WIRED) { 698 /* 699 * Note: uvm_km_pgremove_intrsafe() extracts mapping, thus 700 * remove it after. See comment below about KVA visibility. 701 */ 702 uvm_km_pgremove_intrsafe(map, addr, addr + size); 703 } 704 705 /* 706 * Note: uvm_unmap_remove() calls pmap_update() for us, before 707 * KVA becomes globally available. 708 */ 709 710 uvm_unmap1(map, addr, addr + size, UVM_FLAG_VAONLY); 711} 712 713/* Sanity; must specify both or none. */ 714#if (defined(PMAP_MAP_POOLPAGE) || defined(PMAP_UNMAP_POOLPAGE)) && \ 715 (!defined(PMAP_MAP_POOLPAGE) || !defined(PMAP_UNMAP_POOLPAGE)) 716#error Must specify MAP and UNMAP together. 717#endif 718 719int 720uvm_km_kmem_alloc(vmem_t *vm, vmem_size_t size, vm_flag_t flags, 721 vmem_addr_t *addr) 722{ 723 struct vm_page *pg; 724 vmem_addr_t va; 725 int rc; 726 vaddr_t loopva; 727 vsize_t loopsize; 728 729 size = round_page(size); 730 731#if defined(PMAP_MAP_POOLPAGE) 732 if (size == PAGE_SIZE) { 733again: 734#ifdef PMAP_ALLOC_POOLPAGE 735 pg = PMAP_ALLOC_POOLPAGE((flags & VM_SLEEP) ? 736 0 : UVM_PGA_USERESERVE); 737#else 738 pg = uvm_pagealloc(NULL, 0, NULL, 739 (flags & VM_SLEEP) ? 0 : UVM_PGA_USERESERVE); 740#endif /* PMAP_ALLOC_POOLPAGE */ 741 if (__predict_false(pg == NULL)) { 742 if (flags & VM_SLEEP) { 743 uvm_wait("plpg"); 744 goto again; 745 } 746 return ENOMEM; 747 } 748 va = PMAP_MAP_POOLPAGE(VM_PAGE_TO_PHYS(pg)); 749 if (__predict_false(va == 0)) { 750 uvm_pagefree(pg); 751 return ENOMEM; 752 } 753 *addr = va; 754 return 0; 755 } 756#endif /* PMAP_MAP_POOLPAGE */ 757 758 rc = vmem_alloc(vm, size, flags, &va); 759 if (rc != 0) 760 return rc; 761 762#ifdef PMAP_GROWKERNEL 763 /* 764 * These VA allocations happen independently of uvm_map 765 * so this allocation must not extend beyond the current limit. 766 */ 767 KASSERTMSG(uvm_maxkaddr >= va + size, 768 "%#"PRIxVADDR" %#"PRIxPTR" %#zx", 769 uvm_maxkaddr, va, size); 770#endif 771 772 loopva = va; 773 loopsize = size; 774 775 while (loopsize) { 776 KASSERTMSG(!pmap_extract(pmap_kernel(), loopva, NULL), 777 "loopva=%#"PRIxVADDR" loopsize=%#"PRIxVSIZE" vmem=%p", 778 loopva, loopsize, vm); 779 780 pg = uvm_pagealloc(NULL, loopva, NULL, 781 UVM_FLAG_COLORMATCH 782 | ((flags & VM_SLEEP) ? 0 : UVM_PGA_USERESERVE)); 783 if (__predict_false(pg == NULL)) { 784 if (flags & VM_SLEEP) { 785 uvm_wait("plpg"); 786 continue; 787 } else { 788 uvm_km_pgremove_intrsafe(kernel_map, va, 789 va + size); 790 vmem_free(vm, va, size); 791 return ENOMEM; 792 } 793 } 794 795 pg->flags &= ~PG_BUSY; /* new page */ 796 UVM_PAGE_OWN(pg, NULL); 797 pmap_kenter_pa(loopva, VM_PAGE_TO_PHYS(pg), 798 VM_PROT_READ|VM_PROT_WRITE, PMAP_KMPAGE); 799 800 loopva += PAGE_SIZE; 801 loopsize -= PAGE_SIZE; 802 } 803 pmap_update(pmap_kernel()); 804 805 *addr = va; 806 807 return 0; 808} 809 810void 811uvm_km_kmem_free(vmem_t *vm, vmem_addr_t addr, size_t size) 812{ 813 814 size = round_page(size); 815#if defined(PMAP_UNMAP_POOLPAGE) 816 if (size == PAGE_SIZE) { 817 paddr_t pa; 818 819 pa = PMAP_UNMAP_POOLPAGE(addr); 820 uvm_pagefree(PHYS_TO_VM_PAGE(pa)); 821 return; 822 } 823#endif /* PMAP_UNMAP_POOLPAGE */ 824 uvm_km_pgremove_intrsafe(kernel_map, addr, addr + size); 825 pmap_update(pmap_kernel()); 826 827 vmem_free(vm, addr, size); 828} 829 830bool 831uvm_km_va_starved_p(void) 832{ 833 vmem_size_t total; 834 vmem_size_t free; 835 836 if (kmem_arena == NULL) 837 return false; 838 839 total = vmem_size(kmem_arena, VMEM_ALLOC|VMEM_FREE); 840 free = vmem_size(kmem_arena, VMEM_FREE); 841 842 return (free < (total / 10)); 843} 844