1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Portions of this source code were derived from Berkeley 4.3 BSD 32 * under license from the Regents of the University of California. 33 */ 34 35 #pragma ident "%Z%%M% %I% %E% SMI" 36 37 /* 38 * segkp is a segment driver that administers the allocation and deallocation 39 * of pageable variable size chunks of kernel virtual address space. Each 40 * allocated resource is page-aligned. 41 * 42 * The user may specify whether the resource should be initialized to 0, 43 * include a redzone, or locked in memory. 44 */ 45 46 #include <sys/types.h> 47 #include <sys/t_lock.h> 48 #include <sys/thread.h> 49 #include <sys/param.h> 50 #include <sys/errno.h> 51 #include <sys/sysmacros.h> 52 #include <sys/systm.h> 53 #include <sys/buf.h> 54 #include <sys/mman.h> 55 #include <sys/vnode.h> 56 #include <sys/cmn_err.h> 57 #include <sys/swap.h> 58 #include <sys/tuneable.h> 59 #include <sys/kmem.h> 60 #include <sys/vmem.h> 61 #include <sys/cred.h> 62 #include <sys/dumphdr.h> 63 #include <sys/debug.h> 64 #include <sys/vtrace.h> 65 #include <sys/stack.h> 66 #include <sys/atomic.h> 67 #include <sys/archsystm.h> 68 #include <sys/lgrp.h> 69 70 #include <vm/as.h> 71 #include <vm/seg.h> 72 #include <vm/seg_kp.h> 73 #include <vm/seg_kmem.h> 74 #include <vm/anon.h> 75 #include <vm/page.h> 76 #include <vm/hat.h> 77 #include <sys/bitmap.h> 78 79 /* 80 * Private seg op routines 81 */ 82 static void segkp_badop(void); 83 static void segkp_dump(struct seg *seg); 84 static int segkp_checkprot(struct seg *seg, caddr_t addr, size_t len, 85 uint_t prot); 86 static int segkp_kluster(struct seg *seg, caddr_t addr, ssize_t delta); 87 static int segkp_pagelock(struct seg *seg, caddr_t addr, size_t len, 88 struct page ***page, enum lock_type type, 89 enum seg_rw rw); 90 static void segkp_insert(struct seg *seg, struct segkp_data *kpd); 91 static void segkp_delete(struct seg *seg, struct segkp_data *kpd); 92 static caddr_t segkp_get_internal(struct seg *seg, size_t len, uint_t flags, 93 struct segkp_data **tkpd, struct anon_map *amp); 94 static void segkp_release_internal(struct seg *seg, 95 struct segkp_data *kpd, size_t len); 96 static int segkp_unlock(struct hat *hat, struct seg *seg, caddr_t vaddr, 97 size_t len, struct segkp_data *kpd, uint_t flags); 98 static int segkp_load(struct hat *hat, struct seg *seg, caddr_t vaddr, 99 size_t len, struct segkp_data *kpd, uint_t flags); 100 static struct segkp_data *segkp_find(struct seg *seg, caddr_t vaddr); 101 static int segkp_getmemid(struct seg *seg, caddr_t addr, memid_t *memidp); 102 static lgrp_mem_policy_info_t *segkp_getpolicy(struct seg *seg, 103 caddr_t addr); 104 static int segkp_capable(struct seg *seg, segcapability_t capability); 105 106 /* 107 * Lock used to protect the hash table(s) and caches. 108 */ 109 static kmutex_t segkp_lock; 110 111 /* 112 * The segkp caches 113 */ 114 static struct segkp_cache segkp_cache[SEGKP_MAX_CACHE]; 115 116 #define SEGKP_BADOP(t) (t(*)())segkp_badop 117 118 /* 119 * When there are fewer than red_minavail bytes left on the stack, 120 * segkp_map_red() will map in the redzone (if called). 5000 seems 121 * to work reasonably well... 122 */ 123 long red_minavail = 5000; 124 125 /* 126 * will be set to 1 for 32 bit x86 systems only, in startup.c 127 */ 128 int segkp_fromheap = 0; 129 ulong_t *segkp_bitmap; 130 131 /* 132 * If segkp_map_red() is called with the redzone already mapped and 133 * with less than RED_DEEP_THRESHOLD bytes available on the stack, 134 * then the stack situation has become quite serious; if much more stack 135 * is consumed, we have the potential of scrogging the next thread/LWP 136 * structure. To help debug the "can't happen" panics which may 137 * result from this condition, we record lbolt and the calling thread 138 * in red_deep_lbolt and red_deep_thread respectively. 139 */ 140 #define RED_DEEP_THRESHOLD 2000 141 142 clock_t red_deep_lbolt; 143 kthread_t *red_deep_thread; 144 145 uint32_t red_nmapped; 146 uint32_t red_closest = UINT_MAX; 147 uint32_t red_ndoubles; 148 149 pgcnt_t anon_segkp_pages_locked; /* See vm/anon.h */ 150 151 static struct seg_ops segkp_ops = { 152 SEGKP_BADOP(int), /* dup */ 153 SEGKP_BADOP(int), /* unmap */ 154 SEGKP_BADOP(void), /* free */ 155 segkp_fault, 156 SEGKP_BADOP(faultcode_t), /* faulta */ 157 SEGKP_BADOP(int), /* setprot */ 158 segkp_checkprot, 159 segkp_kluster, 160 SEGKP_BADOP(size_t), /* swapout */ 161 SEGKP_BADOP(int), /* sync */ 162 SEGKP_BADOP(size_t), /* incore */ 163 SEGKP_BADOP(int), /* lockop */ 164 SEGKP_BADOP(int), /* getprot */ 165 SEGKP_BADOP(u_offset_t), /* getoffset */ 166 SEGKP_BADOP(int), /* gettype */ 167 SEGKP_BADOP(int), /* getvp */ 168 SEGKP_BADOP(int), /* advise */ 169 segkp_dump, /* dump */ 170 segkp_pagelock, /* pagelock */ 171 SEGKP_BADOP(int), /* setpgsz */ 172 segkp_getmemid, /* getmemid */ 173 segkp_getpolicy, /* getpolicy */ 174 segkp_capable, /* capable */ 175 }; 176 177 178 static void 179 segkp_badop(void) 180 { 181 panic("segkp_badop"); 182 /*NOTREACHED*/ 183 } 184 185 static void segkpinit_mem_config(struct seg *); 186 187 static uint32_t segkp_indel; 188 189 /* 190 * Allocate the segment specific private data struct and fill it in 191 * with the per kp segment mutex, anon ptr. array and hash table. 192 */ 193 int 194 segkp_create(struct seg *seg) 195 { 196 struct segkp_segdata *kpsd; 197 size_t np; 198 199 ASSERT(seg != NULL && seg->s_as == &kas); 200 ASSERT(RW_WRITE_HELD(&seg->s_as->a_lock)); 201 202 if (seg->s_size & PAGEOFFSET) { 203 panic("Bad segkp size"); 204 /*NOTREACHED*/ 205 } 206 207 kpsd = kmem_zalloc(sizeof (struct segkp_segdata), KM_SLEEP); 208 209 /* 210 * Allocate the virtual memory for segkp and initialize it 211 */ 212 if (segkp_fromheap) { 213 np = btop(kvseg.s_size); 214 segkp_bitmap = kmem_zalloc(BT_SIZEOFMAP(np), KM_SLEEP); 215 kpsd->kpsd_arena = vmem_create("segkp", NULL, 0, PAGESIZE, 216 vmem_alloc, vmem_free, heap_arena, 5 * PAGESIZE, VM_SLEEP); 217 } else { 218 segkp_bitmap = NULL; 219 np = btop(seg->s_size); 220 kpsd->kpsd_arena = vmem_create("segkp", seg->s_base, 221 seg->s_size, PAGESIZE, NULL, NULL, NULL, 5 * PAGESIZE, 222 VM_SLEEP); 223 } 224 225 kpsd->kpsd_anon = anon_create(np, ANON_SLEEP | ANON_ALLOC_FORCE); 226 227 kpsd->kpsd_hash = kmem_zalloc(SEGKP_HASHSZ * sizeof (struct segkp *), 228 KM_SLEEP); 229 seg->s_data = (void *)kpsd; 230 seg->s_ops = &segkp_ops; 231 segkpinit_mem_config(seg); 232 return (0); 233 } 234 235 236 /* 237 * Find a free 'freelist' and initialize it with the appropriate attributes 238 */ 239 void * 240 segkp_cache_init(struct seg *seg, int maxsize, size_t len, uint_t flags) 241 { 242 int i; 243 244 if ((flags & KPD_NO_ANON) && !(flags & KPD_LOCKED)) 245 return ((void *)-1); 246 247 mutex_enter(&segkp_lock); 248 for (i = 0; i < SEGKP_MAX_CACHE; i++) { 249 if (segkp_cache[i].kpf_inuse) 250 continue; 251 segkp_cache[i].kpf_inuse = 1; 252 segkp_cache[i].kpf_max = maxsize; 253 segkp_cache[i].kpf_flags = flags; 254 segkp_cache[i].kpf_seg = seg; 255 segkp_cache[i].kpf_len = len; 256 mutex_exit(&segkp_lock); 257 return ((void *)(uintptr_t)i); 258 } 259 mutex_exit(&segkp_lock); 260 return ((void *)-1); 261 } 262 263 /* 264 * Free all the cache resources. 265 */ 266 void 267 segkp_cache_free(void) 268 { 269 struct segkp_data *kpd; 270 struct seg *seg; 271 int i; 272 273 mutex_enter(&segkp_lock); 274 for (i = 0; i < SEGKP_MAX_CACHE; i++) { 275 if (!segkp_cache[i].kpf_inuse) 276 continue; 277 /* 278 * Disconnect the freelist and process each element 279 */ 280 kpd = segkp_cache[i].kpf_list; 281 seg = segkp_cache[i].kpf_seg; 282 segkp_cache[i].kpf_list = NULL; 283 segkp_cache[i].kpf_count = 0; 284 mutex_exit(&segkp_lock); 285 286 while (kpd != NULL) { 287 struct segkp_data *next; 288 289 next = kpd->kp_next; 290 segkp_release_internal(seg, kpd, kpd->kp_len); 291 kpd = next; 292 } 293 mutex_enter(&segkp_lock); 294 } 295 mutex_exit(&segkp_lock); 296 } 297 298 /* 299 * There are 2 entries into segkp_get_internal. The first includes a cookie 300 * used to access a pool of cached segkp resources. The second does not 301 * use the cache. 302 */ 303 caddr_t 304 segkp_get(struct seg *seg, size_t len, uint_t flags) 305 { 306 struct segkp_data *kpd = NULL; 307 308 if (segkp_get_internal(seg, len, flags, &kpd, NULL) != NULL) { 309 kpd->kp_cookie = -1; 310 return (stom(kpd->kp_base, flags)); 311 } 312 return (NULL); 313 } 314 315 /* 316 * Return a 'cached' segkp address 317 */ 318 caddr_t 319 segkp_cache_get(void *cookie) 320 { 321 struct segkp_cache *freelist = NULL; 322 struct segkp_data *kpd = NULL; 323 int index = (int)(uintptr_t)cookie; 324 struct seg *seg; 325 size_t len; 326 uint_t flags; 327 328 if (index < 0 || index >= SEGKP_MAX_CACHE) 329 return (NULL); 330 freelist = &segkp_cache[index]; 331 332 mutex_enter(&segkp_lock); 333 seg = freelist->kpf_seg; 334 flags = freelist->kpf_flags; 335 if (freelist->kpf_list != NULL) { 336 kpd = freelist->kpf_list; 337 freelist->kpf_list = kpd->kp_next; 338 freelist->kpf_count--; 339 mutex_exit(&segkp_lock); 340 kpd->kp_next = NULL; 341 segkp_insert(seg, kpd); 342 return (stom(kpd->kp_base, flags)); 343 } 344 len = freelist->kpf_len; 345 mutex_exit(&segkp_lock); 346 if (segkp_get_internal(seg, len, flags, &kpd, NULL) != NULL) { 347 kpd->kp_cookie = index; 348 return (stom(kpd->kp_base, flags)); 349 } 350 return (NULL); 351 } 352 353 caddr_t 354 segkp_get_withanonmap( 355 struct seg *seg, 356 size_t len, 357 uint_t flags, 358 struct anon_map *amp) 359 { 360 struct segkp_data *kpd = NULL; 361 362 ASSERT(amp != NULL); 363 flags |= KPD_HASAMP; 364 if (segkp_get_internal(seg, len, flags, &kpd, amp) != NULL) { 365 kpd->kp_cookie = -1; 366 return (stom(kpd->kp_base, flags)); 367 } 368 return (NULL); 369 } 370 371 /* 372 * This does the real work of segkp allocation. 373 * Return to client base addr. len must be page-aligned. A null value is 374 * returned if there are no more vm resources (e.g. pages, swap). The len 375 * and base recorded in the private data structure include the redzone 376 * and the redzone length (if applicable). If the user requests a redzone 377 * either the first or last page is left unmapped depending whether stacks 378 * grow to low or high memory. 379 * 380 * The client may also specify a no-wait flag. If that is set then the 381 * request will choose a non-blocking path when requesting resources. 382 * The default is make the client wait. 383 */ 384 static caddr_t 385 segkp_get_internal( 386 struct seg *seg, 387 size_t len, 388 uint_t flags, 389 struct segkp_data **tkpd, 390 struct anon_map *amp) 391 { 392 struct segkp_segdata *kpsd = (struct segkp_segdata *)seg->s_data; 393 struct segkp_data *kpd; 394 caddr_t vbase = NULL; /* always first virtual, may not be mapped */ 395 pgcnt_t np = 0; /* number of pages in the resource */ 396 pgcnt_t segkpindex; 397 long i; 398 caddr_t va; 399 pgcnt_t pages = 0; 400 ulong_t anon_idx = 0; 401 int kmflag = (flags & KPD_NOWAIT) ? KM_NOSLEEP : KM_SLEEP; 402 caddr_t s_base = (segkp_fromheap) ? kvseg.s_base : seg->s_base; 403 404 if (len & PAGEOFFSET) { 405 panic("segkp_get: len is not page-aligned"); 406 /*NOTREACHED*/ 407 } 408 409 ASSERT(((flags & KPD_HASAMP) == 0) == (amp == NULL)); 410 411 /* Only allow KPD_NO_ANON if we are going to lock it down */ 412 if ((flags & (KPD_LOCKED|KPD_NO_ANON)) == KPD_NO_ANON) 413 return (NULL); 414 415 if ((kpd = kmem_zalloc(sizeof (struct segkp_data), kmflag)) == NULL) 416 return (NULL); 417 /* 418 * Fix up the len to reflect the REDZONE if applicable 419 */ 420 if (flags & KPD_HASREDZONE) 421 len += PAGESIZE; 422 np = btop(len); 423 424 vbase = vmem_alloc(SEGKP_VMEM(seg), len, kmflag | VM_BESTFIT); 425 if (vbase == NULL) { 426 kmem_free(kpd, sizeof (struct segkp_data)); 427 return (NULL); 428 } 429 430 /* If locking, reserve physical memory */ 431 if (flags & KPD_LOCKED) { 432 pages = btop(SEGKP_MAPLEN(len, flags)); 433 if (page_resv(pages, kmflag) == 0) { 434 vmem_free(SEGKP_VMEM(seg), vbase, len); 435 kmem_free(kpd, sizeof (struct segkp_data)); 436 return (NULL); 437 } 438 if ((flags & KPD_NO_ANON) == 0) 439 atomic_add_long(&anon_segkp_pages_locked, pages); 440 } 441 442 /* 443 * Reserve sufficient swap space for this vm resource. We'll 444 * actually allocate it in the loop below, but reserving it 445 * here allows us to back out more gracefully than if we 446 * had an allocation failure in the body of the loop. 447 * 448 * Note that we don't need swap space for the red zone page. 449 */ 450 if (amp != NULL) { 451 ASSERT((flags & KPD_NO_ANON) == 0); 452 /* The reserve has been done and the anon_hdr is separate. */ 453 anon_idx = 0; 454 kpd->kp_anon_idx = anon_idx; 455 kpd->kp_anon = amp->ahp; 456 457 TRACE_5(TR_FAC_VM, TR_ANON_SEGKP, "anon segkp:%p %p %lu %u %u", 458 kpd, vbase, len, flags, 1); 459 460 } else if ((flags & KPD_NO_ANON) == 0) { 461 if (anon_resv(SEGKP_MAPLEN(len, flags)) == 0) { 462 if (flags & KPD_LOCKED) { 463 atomic_add_long(&anon_segkp_pages_locked, 464 -pages); 465 page_unresv(pages); 466 } 467 vmem_free(SEGKP_VMEM(seg), vbase, len); 468 kmem_free(kpd, sizeof (struct segkp_data)); 469 return (NULL); 470 } 471 anon_idx = ((uintptr_t)(vbase - s_base)) >> PAGESHIFT; 472 kpd->kp_anon_idx = anon_idx; 473 kpd->kp_anon = kpsd->kpsd_anon; 474 475 TRACE_5(TR_FAC_VM, TR_ANON_SEGKP, "anon segkp:%p %p %lu %u %u", 476 kpd, vbase, len, flags, 1); 477 } else { 478 kpd->kp_anon = NULL; 479 kpd->kp_anon_idx = 0; 480 } 481 482 /* 483 * Allocate page and anon resources for the virtual address range 484 * except the redzone 485 */ 486 if (segkp_fromheap) 487 segkpindex = btop((uintptr_t)(vbase - kvseg.s_base)); 488 for (i = 0, va = vbase; i < np; i++, va += PAGESIZE) { 489 page_t *pl[2]; 490 struct vnode *vp; 491 anoff_t off; 492 int err; 493 page_t *pp = NULL; 494 495 /* 496 * Mark this page to be a segkp page in the bitmap. 497 */ 498 if (segkp_fromheap) { 499 BT_ATOMIC_SET(segkp_bitmap, segkpindex); 500 segkpindex++; 501 } 502 503 /* 504 * If this page is the red zone page, we don't need swap 505 * space for it. Note that we skip over the code that 506 * establishes MMU mappings, so that the page remains 507 * invalid. 508 */ 509 if ((flags & KPD_HASREDZONE) && KPD_REDZONE(kpd) == i) 510 continue; 511 512 if (kpd->kp_anon != NULL) { 513 struct anon *ap; 514 515 ASSERT(anon_get_ptr(kpd->kp_anon, anon_idx + i) 516 == NULL); 517 /* 518 * Determine the "vp" and "off" of the anon slot. 519 */ 520 ap = anon_alloc(NULL, 0); 521 if (amp != NULL) 522 ANON_LOCK_ENTER(&->a_rwlock, RW_WRITER); 523 (void) anon_set_ptr(kpd->kp_anon, anon_idx + i, 524 ap, ANON_SLEEP); 525 if (amp != NULL) 526 ANON_LOCK_EXIT(&->a_rwlock); 527 swap_xlate(ap, &vp, &off); 528 529 /* 530 * Create a page with the specified identity. The 531 * page is returned with the "shared" lock held. 532 */ 533 err = VOP_GETPAGE(vp, (offset_t)off, PAGESIZE, 534 NULL, pl, PAGESIZE, seg, va, S_CREATE, 535 kcred); 536 if (err) { 537 /* 538 * XXX - This should not fail. 539 */ 540 panic("segkp_get: no pages"); 541 /*NOTREACHED*/ 542 } 543 pp = pl[0]; 544 } else { 545 ASSERT(page_exists(&kvp, 546 (u_offset_t)(uintptr_t)va) == NULL); 547 548 if ((pp = page_create_va(&kvp, 549 (u_offset_t)(uintptr_t)va, PAGESIZE, 550 (flags & KPD_NOWAIT ? 0 : PG_WAIT) | PG_EXCL | 551 PG_NORELOC, seg, va)) == NULL) { 552 /* 553 * Legitimize resource; then destroy it. 554 * Easier than trying to unwind here. 555 */ 556 kpd->kp_flags = flags; 557 kpd->kp_base = vbase; 558 kpd->kp_len = len; 559 segkp_release_internal(seg, kpd, va - vbase); 560 return (NULL); 561 } 562 page_io_unlock(pp); 563 } 564 565 if (flags & KPD_ZERO) 566 pagezero(pp, 0, PAGESIZE); 567 568 /* 569 * Load and lock an MMU translation for the page. 570 */ 571 hat_memload(seg->s_as->a_hat, va, pp, (PROT_READ|PROT_WRITE), 572 ((flags & KPD_LOCKED) ? HAT_LOAD_LOCK : HAT_LOAD)); 573 574 /* 575 * Now, release lock on the page. 576 */ 577 if (flags & KPD_LOCKED) 578 page_downgrade(pp); 579 else 580 page_unlock(pp); 581 } 582 583 kpd->kp_flags = flags; 584 kpd->kp_base = vbase; 585 kpd->kp_len = len; 586 segkp_insert(seg, kpd); 587 *tkpd = kpd; 588 return (stom(kpd->kp_base, flags)); 589 } 590 591 /* 592 * Release the resource to cache if the pool(designate by the cookie) 593 * has less than the maximum allowable. If inserted in cache, 594 * segkp_delete insures element is taken off of active list. 595 */ 596 void 597 segkp_release(struct seg *seg, caddr_t vaddr) 598 { 599 struct segkp_cache *freelist; 600 struct segkp_data *kpd = NULL; 601 602 if ((kpd = segkp_find(seg, vaddr)) == NULL) { 603 panic("segkp_release: null kpd"); 604 /*NOTREACHED*/ 605 } 606 607 if (kpd->kp_cookie != -1) { 608 freelist = &segkp_cache[kpd->kp_cookie]; 609 mutex_enter(&segkp_lock); 610 if (!segkp_indel && freelist->kpf_count < freelist->kpf_max) { 611 segkp_delete(seg, kpd); 612 kpd->kp_next = freelist->kpf_list; 613 freelist->kpf_list = kpd; 614 freelist->kpf_count++; 615 mutex_exit(&segkp_lock); 616 return; 617 } else { 618 mutex_exit(&segkp_lock); 619 kpd->kp_cookie = -1; 620 } 621 } 622 segkp_release_internal(seg, kpd, kpd->kp_len); 623 } 624 625 /* 626 * Free the entire resource. segkp_unlock gets called with the start of the 627 * mapped portion of the resource. The length is the size of the mapped 628 * portion 629 */ 630 static void 631 segkp_release_internal(struct seg *seg, struct segkp_data *kpd, size_t len) 632 { 633 caddr_t va; 634 long i; 635 long redzone; 636 size_t np; 637 page_t *pp; 638 struct vnode *vp; 639 anoff_t off; 640 struct anon *ap; 641 pgcnt_t segkpindex; 642 643 ASSERT(kpd != NULL); 644 ASSERT((kpd->kp_flags & KPD_HASAMP) == 0 || kpd->kp_cookie == -1); 645 np = btop(len); 646 647 /* Remove from active hash list */ 648 if (kpd->kp_cookie == -1) { 649 mutex_enter(&segkp_lock); 650 segkp_delete(seg, kpd); 651 mutex_exit(&segkp_lock); 652 } 653 654 /* 655 * Precompute redzone page index. 656 */ 657 redzone = -1; 658 if (kpd->kp_flags & KPD_HASREDZONE) 659 redzone = KPD_REDZONE(kpd); 660 661 662 va = kpd->kp_base; 663 664 hat_unload(seg->s_as->a_hat, va, (np << PAGESHIFT), 665 ((kpd->kp_flags & KPD_LOCKED) ? HAT_UNLOAD_UNLOCK : HAT_UNLOAD)); 666 /* 667 * Free up those anon resources that are quiescent. 668 */ 669 if (segkp_fromheap) 670 segkpindex = btop((uintptr_t)(va - kvseg.s_base)); 671 for (i = 0; i < np; i++, va += PAGESIZE) { 672 673 /* 674 * Clear the bit for this page from the bitmap. 675 */ 676 if (segkp_fromheap) { 677 BT_ATOMIC_CLEAR(segkp_bitmap, segkpindex); 678 segkpindex++; 679 } 680 681 if (i == redzone) 682 continue; 683 if (kpd->kp_anon) { 684 /* 685 * Free up anon resources and destroy the 686 * associated pages. 687 * 688 * Release the lock if there is one. Have to get the 689 * page to do this, unfortunately. 690 */ 691 if (kpd->kp_flags & KPD_LOCKED) { 692 ap = anon_get_ptr(kpd->kp_anon, 693 kpd->kp_anon_idx + i); 694 swap_xlate(ap, &vp, &off); 695 /* Find the shared-locked page. */ 696 pp = page_find(vp, (u_offset_t)off); 697 if (pp == NULL) { 698 panic("segkp_release: " 699 "kp_anon: no page to unlock "); 700 /*NOTREACHED*/ 701 } 702 page_unlock(pp); 703 } 704 if ((kpd->kp_flags & KPD_HASAMP) == 0) { 705 anon_free(kpd->kp_anon, kpd->kp_anon_idx + i, 706 PAGESIZE); 707 anon_unresv(PAGESIZE); 708 } 709 TRACE_5(TR_FAC_VM, 710 TR_ANON_SEGKP, "anon segkp:%p %p %lu %u %u", 711 kpd, va, PAGESIZE, 0, 0); 712 } else { 713 if (kpd->kp_flags & KPD_LOCKED) { 714 pp = page_find(&kvp, (u_offset_t)(uintptr_t)va); 715 if (pp == NULL) { 716 panic("segkp_release: " 717 "no page to unlock"); 718 /*NOTREACHED*/ 719 } 720 /* 721 * We should just upgrade the lock here 722 * but there is no upgrade that waits. 723 */ 724 page_unlock(pp); 725 } 726 pp = page_lookup(&kvp, (u_offset_t)(uintptr_t)va, 727 SE_EXCL); 728 if (pp != NULL) 729 page_destroy(pp, 0); 730 } 731 } 732 733 /* If locked, release physical memory reservation */ 734 if (kpd->kp_flags & KPD_LOCKED) { 735 pgcnt_t pages = btop(SEGKP_MAPLEN(kpd->kp_len, kpd->kp_flags)); 736 if ((kpd->kp_flags & KPD_NO_ANON) == 0) 737 atomic_add_long(&anon_segkp_pages_locked, -pages); 738 page_unresv(pages); 739 } 740 741 vmem_free(SEGKP_VMEM(seg), kpd->kp_base, kpd->kp_len); 742 kmem_free(kpd, sizeof (struct segkp_data)); 743 } 744 745 /* 746 * segkp_map_red() will check the current frame pointer against the 747 * stack base. If the amount of stack remaining is questionable 748 * (less than red_minavail), then segkp_map_red() will map in the redzone 749 * and return 1. Otherwise, it will return 0. segkp_map_red() can 750 * _only_ be called when: 751 * 752 * - it is safe to sleep on page_create_va(). 753 * - the caller is non-swappable. 754 * 755 * It is up to the caller to remember whether segkp_map_red() successfully 756 * mapped the redzone, and, if so, to call segkp_unmap_red() at a later 757 * time. Note that the caller must _remain_ non-swappable until after 758 * calling segkp_unmap_red(). 759 * 760 * Currently, this routine is only called from pagefault() (which necessarily 761 * satisfies the above conditions). 762 */ 763 #if defined(STACK_GROWTH_DOWN) 764 int 765 segkp_map_red(void) 766 { 767 uintptr_t fp = STACK_BIAS + (uintptr_t)getfp(); 768 #ifndef _LP64 769 caddr_t stkbase; 770 #endif 771 772 ASSERT(curthread->t_schedflag & TS_DONT_SWAP); 773 774 /* 775 * Optimize for the common case where we simply return. 776 */ 777 if ((curthread->t_red_pp == NULL) && 778 (fp - (uintptr_t)curthread->t_stkbase >= red_minavail)) 779 return (0); 780 781 #if defined(_LP64) 782 /* 783 * XXX We probably need something better than this. 784 */ 785 panic("kernel stack overflow"); 786 /*NOTREACHED*/ 787 #else /* _LP64 */ 788 if (curthread->t_red_pp == NULL) { 789 page_t *red_pp; 790 struct seg kseg; 791 792 caddr_t red_va = (caddr_t) 793 (((uintptr_t)curthread->t_stkbase & (uintptr_t)PAGEMASK) - 794 PAGESIZE); 795 796 ASSERT(page_exists(&kvp, (u_offset_t)(uintptr_t)red_va) == 797 NULL); 798 799 /* 800 * Allocate the physical for the red page. 801 */ 802 /* 803 * No PG_NORELOC here to avoid waits. Unlikely to get 804 * a relocate happening in the short time the page exists 805 * and it will be OK anyway. 806 */ 807 808 kseg.s_as = &kas; 809 red_pp = page_create_va(&kvp, (u_offset_t)(uintptr_t)red_va, 810 PAGESIZE, PG_WAIT | PG_EXCL, &kseg, red_va); 811 ASSERT(red_pp != NULL); 812 813 /* 814 * So we now have a page to jam into the redzone... 815 */ 816 page_io_unlock(red_pp); 817 818 hat_memload(kas.a_hat, red_va, red_pp, 819 (PROT_READ|PROT_WRITE), HAT_LOAD_LOCK); 820 page_downgrade(red_pp); 821 822 /* 823 * The page is left SE_SHARED locked so we can hold on to 824 * the page_t pointer. 825 */ 826 curthread->t_red_pp = red_pp; 827 828 atomic_add_32(&red_nmapped, 1); 829 while (fp - (uintptr_t)curthread->t_stkbase < red_closest) { 830 (void) cas32(&red_closest, red_closest, 831 (uint32_t)(fp - (uintptr_t)curthread->t_stkbase)); 832 } 833 return (1); 834 } 835 836 stkbase = (caddr_t)(((uintptr_t)curthread->t_stkbase & 837 (uintptr_t)PAGEMASK) - PAGESIZE); 838 839 atomic_add_32(&red_ndoubles, 1); 840 841 if (fp - (uintptr_t)stkbase < RED_DEEP_THRESHOLD) { 842 /* 843 * Oh boy. We're already deep within the mapped-in 844 * redzone page, and the caller is trying to prepare 845 * for a deep stack run. We're running without a 846 * redzone right now: if the caller plows off the 847 * end of the stack, it'll plow another thread or 848 * LWP structure. That situation could result in 849 * a very hard-to-debug panic, so, in the spirit of 850 * recording the name of one's killer in one's own 851 * blood, we're going to record lbolt and the calling 852 * thread. 853 */ 854 red_deep_lbolt = lbolt; 855 red_deep_thread = curthread; 856 } 857 858 /* 859 * If this is a DEBUG kernel, and we've run too deep for comfort, toss. 860 */ 861 ASSERT(fp - (uintptr_t)stkbase >= RED_DEEP_THRESHOLD); 862 return (0); 863 #endif /* _LP64 */ 864 } 865 866 void 867 segkp_unmap_red(void) 868 { 869 page_t *pp; 870 caddr_t red_va = (caddr_t)(((uintptr_t)curthread->t_stkbase & 871 (uintptr_t)PAGEMASK) - PAGESIZE); 872 873 ASSERT(curthread->t_red_pp != NULL); 874 ASSERT(curthread->t_schedflag & TS_DONT_SWAP); 875 876 /* 877 * Because we locked the mapping down, we can't simply rely 878 * on page_destroy() to clean everything up; we need to call 879 * hat_unload() to explicitly unlock the mapping resources. 880 */ 881 hat_unload(kas.a_hat, red_va, PAGESIZE, HAT_UNLOAD_UNLOCK); 882 883 pp = curthread->t_red_pp; 884 885 ASSERT(pp == page_find(&kvp, (u_offset_t)(uintptr_t)red_va)); 886 887 /* 888 * Need to upgrade the SE_SHARED lock to SE_EXCL. 889 */ 890 if (!page_tryupgrade(pp)) { 891 /* 892 * As there is now wait for upgrade, release the 893 * SE_SHARED lock and wait for SE_EXCL. 894 */ 895 page_unlock(pp); 896 pp = page_lookup(&kvp, (u_offset_t)(uintptr_t)red_va, SE_EXCL); 897 /* pp may be NULL here, hence the test below */ 898 } 899 900 /* 901 * Destroy the page, with dontfree set to zero (i.e. free it). 902 */ 903 if (pp != NULL) 904 page_destroy(pp, 0); 905 curthread->t_red_pp = NULL; 906 } 907 #else 908 #error Red stacks only supported with downwards stack growth. 909 #endif 910 911 /* 912 * Handle a fault on an address corresponding to one of the 913 * resources in the segkp segment. 914 */ 915 faultcode_t 916 segkp_fault( 917 struct hat *hat, 918 struct seg *seg, 919 caddr_t vaddr, 920 size_t len, 921 enum fault_type type, 922 enum seg_rw rw) 923 { 924 struct segkp_data *kpd = NULL; 925 int err; 926 927 ASSERT(seg->s_as == &kas && RW_READ_HELD(&seg->s_as->a_lock)); 928 929 /* 930 * Sanity checks. 931 */ 932 if (type == F_PROT) { 933 panic("segkp_fault: unexpected F_PROT fault"); 934 /*NOTREACHED*/ 935 } 936 937 if ((kpd = segkp_find(seg, vaddr)) == NULL) 938 return (FC_NOMAP); 939 940 mutex_enter(&kpd->kp_lock); 941 942 if (type == F_SOFTLOCK) { 943 ASSERT(!(kpd->kp_flags & KPD_LOCKED)); 944 /* 945 * The F_SOFTLOCK case has more stringent 946 * range requirements: the given range must exactly coincide 947 * with the resource's mapped portion. Note reference to 948 * redzone is handled since vaddr would not equal base 949 */ 950 if (vaddr != stom(kpd->kp_base, kpd->kp_flags) || 951 len != SEGKP_MAPLEN(kpd->kp_len, kpd->kp_flags)) { 952 mutex_exit(&kpd->kp_lock); 953 return (FC_MAKE_ERR(EFAULT)); 954 } 955 956 if ((err = segkp_load(hat, seg, vaddr, len, kpd, KPD_LOCKED))) { 957 mutex_exit(&kpd->kp_lock); 958 return (FC_MAKE_ERR(err)); 959 } 960 kpd->kp_flags |= KPD_LOCKED; 961 mutex_exit(&kpd->kp_lock); 962 return (0); 963 } 964 965 if (type == F_INVAL) { 966 ASSERT(!(kpd->kp_flags & KPD_NO_ANON)); 967 968 /* 969 * Check if we touched the redzone. Somewhat optimistic 970 * here if we are touching the redzone of our own stack 971 * since we wouldn't have a stack to get this far... 972 */ 973 if ((kpd->kp_flags & KPD_HASREDZONE) && 974 btop((uintptr_t)(vaddr - kpd->kp_base)) == KPD_REDZONE(kpd)) 975 panic("segkp_fault: accessing redzone"); 976 977 /* 978 * This fault may occur while the page is being F_SOFTLOCK'ed. 979 * Return since a 2nd segkp_load is unnecessary and also would 980 * result in the page being locked twice and eventually 981 * hang the thread_reaper thread. 982 */ 983 if (kpd->kp_flags & KPD_LOCKED) { 984 mutex_exit(&kpd->kp_lock); 985 return (0); 986 } 987 988 err = segkp_load(hat, seg, vaddr, len, kpd, kpd->kp_flags); 989 mutex_exit(&kpd->kp_lock); 990 return (err ? FC_MAKE_ERR(err) : 0); 991 } 992 993 if (type == F_SOFTUNLOCK) { 994 uint_t flags; 995 996 /* 997 * Make sure the addr is LOCKED and it has anon backing 998 * before unlocking 999 */ 1000 if ((kpd->kp_flags & (KPD_LOCKED|KPD_NO_ANON)) == KPD_NO_ANON) { 1001 panic("segkp_fault: bad unlock"); 1002 /*NOTREACHED*/ 1003 } 1004 1005 if (vaddr != stom(kpd->kp_base, kpd->kp_flags) || 1006 len != SEGKP_MAPLEN(kpd->kp_len, kpd->kp_flags)) { 1007 panic("segkp_fault: bad range"); 1008 /*NOTREACHED*/ 1009 } 1010 1011 if (rw == S_WRITE) 1012 flags = kpd->kp_flags | KPD_WRITEDIRTY; 1013 else 1014 flags = kpd->kp_flags; 1015 err = segkp_unlock(hat, seg, vaddr, len, kpd, flags); 1016 kpd->kp_flags &= ~KPD_LOCKED; 1017 mutex_exit(&kpd->kp_lock); 1018 return (err ? FC_MAKE_ERR(err) : 0); 1019 } 1020 mutex_exit(&kpd->kp_lock); 1021 panic("segkp_fault: bogus fault type: %d\n", type); 1022 /*NOTREACHED*/ 1023 } 1024 1025 /* 1026 * Check that the given protections suffice over the range specified by 1027 * vaddr and len. For this segment type, the only issue is whether or 1028 * not the range lies completely within the mapped part of an allocated 1029 * resource. 1030 */ 1031 /* ARGSUSED */ 1032 static int 1033 segkp_checkprot(struct seg *seg, caddr_t vaddr, size_t len, uint_t prot) 1034 { 1035 struct segkp_data *kpd = NULL; 1036 caddr_t mbase; 1037 size_t mlen; 1038 1039 if ((kpd = segkp_find(seg, vaddr)) == NULL) 1040 return (EACCES); 1041 1042 mutex_enter(&kpd->kp_lock); 1043 mbase = stom(kpd->kp_base, kpd->kp_flags); 1044 mlen = SEGKP_MAPLEN(kpd->kp_len, kpd->kp_flags); 1045 if (len > mlen || vaddr < mbase || 1046 ((vaddr + len) > (mbase + mlen))) { 1047 mutex_exit(&kpd->kp_lock); 1048 return (EACCES); 1049 } 1050 mutex_exit(&kpd->kp_lock); 1051 return (0); 1052 } 1053 1054 1055 /* 1056 * Check to see if it makes sense to do kluster/read ahead to 1057 * addr + delta relative to the mapping at addr. We assume here 1058 * that delta is a signed PAGESIZE'd multiple (which can be negative). 1059 * 1060 * For seg_u we always "approve" of this action from our standpoint. 1061 */ 1062 /*ARGSUSED*/ 1063 static int 1064 segkp_kluster(struct seg *seg, caddr_t addr, ssize_t delta) 1065 { 1066 return (0); 1067 } 1068 1069 /* 1070 * Load and possibly lock intra-slot resources in the range given by 1071 * vaddr and len. 1072 */ 1073 static int 1074 segkp_load( 1075 struct hat *hat, 1076 struct seg *seg, 1077 caddr_t vaddr, 1078 size_t len, 1079 struct segkp_data *kpd, 1080 uint_t flags) 1081 { 1082 caddr_t va; 1083 caddr_t vlim; 1084 ulong_t i; 1085 uint_t lock; 1086 1087 ASSERT(MUTEX_HELD(&kpd->kp_lock)); 1088 1089 len = P2ROUNDUP(len, PAGESIZE); 1090 1091 /* If locking, reserve physical memory */ 1092 if (flags & KPD_LOCKED) { 1093 pgcnt_t pages = btop(len); 1094 if ((kpd->kp_flags & KPD_NO_ANON) == 0) 1095 atomic_add_long(&anon_segkp_pages_locked, pages); 1096 (void) page_resv(pages, KM_SLEEP); 1097 } 1098 1099 /* 1100 * Loop through the pages in the given range. 1101 */ 1102 va = (caddr_t)((uintptr_t)vaddr & (uintptr_t)PAGEMASK); 1103 vaddr = va; 1104 vlim = va + len; 1105 lock = flags & KPD_LOCKED; 1106 i = ((uintptr_t)(va - kpd->kp_base)) >> PAGESHIFT; 1107 for (; va < vlim; va += PAGESIZE, i++) { 1108 page_t *pl[2]; /* second element NULL terminator */ 1109 struct vnode *vp; 1110 anoff_t off; 1111 int err; 1112 struct anon *ap; 1113 1114 /* 1115 * Summon the page. If it's not resident, arrange 1116 * for synchronous i/o to pull it in. 1117 */ 1118 ap = anon_get_ptr(kpd->kp_anon, kpd->kp_anon_idx + i); 1119 swap_xlate(ap, &vp, &off); 1120 1121 /* 1122 * The returned page list will have exactly one entry, 1123 * which is returned to us already kept. 1124 */ 1125 err = VOP_GETPAGE(vp, (offset_t)off, PAGESIZE, NULL, 1126 pl, PAGESIZE, seg, va, S_READ, kcred); 1127 1128 if (err) { 1129 /* 1130 * Back out of what we've done so far. 1131 */ 1132 (void) segkp_unlock(hat, seg, vaddr, 1133 (va - vaddr), kpd, flags); 1134 return (err); 1135 } 1136 1137 /* 1138 * Load an MMU translation for the page. 1139 */ 1140 hat_memload(hat, va, pl[0], (PROT_READ|PROT_WRITE), 1141 lock ? HAT_LOAD_LOCK : HAT_LOAD); 1142 1143 if (!lock) { 1144 /* 1145 * Now, release "shared" lock on the page. 1146 */ 1147 page_unlock(pl[0]); 1148 } 1149 } 1150 return (0); 1151 } 1152 1153 /* 1154 * At the very least unload the mmu-translations and unlock the range if locked 1155 * Can be called with the following flag value KPD_WRITEDIRTY which specifies 1156 * any dirty pages should be written to disk. 1157 */ 1158 static int 1159 segkp_unlock( 1160 struct hat *hat, 1161 struct seg *seg, 1162 caddr_t vaddr, 1163 size_t len, 1164 struct segkp_data *kpd, 1165 uint_t flags) 1166 { 1167 caddr_t va; 1168 caddr_t vlim; 1169 ulong_t i; 1170 struct page *pp; 1171 struct vnode *vp; 1172 anoff_t off; 1173 struct anon *ap; 1174 1175 #ifdef lint 1176 seg = seg; 1177 #endif /* lint */ 1178 1179 ASSERT(MUTEX_HELD(&kpd->kp_lock)); 1180 1181 /* 1182 * Loop through the pages in the given range. It is assumed 1183 * segkp_unlock is called with page aligned base 1184 */ 1185 va = vaddr; 1186 vlim = va + len; 1187 i = ((uintptr_t)(va - kpd->kp_base)) >> PAGESHIFT; 1188 hat_unload(hat, va, len, 1189 ((flags & KPD_LOCKED) ? HAT_UNLOAD_UNLOCK : HAT_UNLOAD)); 1190 for (; va < vlim; va += PAGESIZE, i++) { 1191 /* 1192 * Find the page associated with this part of the 1193 * slot, tracking it down through its associated swap 1194 * space. 1195 */ 1196 ap = anon_get_ptr(kpd->kp_anon, kpd->kp_anon_idx + i); 1197 swap_xlate(ap, &vp, &off); 1198 1199 if (flags & KPD_LOCKED) { 1200 if ((pp = page_find(vp, off)) == NULL) { 1201 if (flags & KPD_LOCKED) { 1202 panic("segkp_softunlock: missing page"); 1203 /*NOTREACHED*/ 1204 } 1205 } 1206 } else { 1207 /* 1208 * Nothing to do if the slot is not locked and the 1209 * page doesn't exist. 1210 */ 1211 if ((pp = page_lookup(vp, off, SE_SHARED)) == NULL) 1212 continue; 1213 } 1214 1215 /* 1216 * If the page doesn't have any translations, is 1217 * dirty and not being shared, then push it out 1218 * asynchronously and avoid waiting for the 1219 * pageout daemon to do it for us. 1220 * 1221 * XXX - Do we really need to get the "exclusive" 1222 * lock via an upgrade? 1223 */ 1224 if ((flags & KPD_WRITEDIRTY) && !hat_page_is_mapped(pp) && 1225 hat_ismod(pp) && page_tryupgrade(pp)) { 1226 /* 1227 * Hold the vnode before releasing the page lock to 1228 * prevent it from being freed and re-used by some 1229 * other thread. 1230 */ 1231 VN_HOLD(vp); 1232 page_unlock(pp); 1233 1234 /* 1235 * Want most powerful credentials we can get so 1236 * use kcred. 1237 */ 1238 (void) VOP_PUTPAGE(vp, (offset_t)off, PAGESIZE, 1239 B_ASYNC | B_FREE, kcred); 1240 VN_RELE(vp); 1241 } else { 1242 page_unlock(pp); 1243 } 1244 } 1245 1246 /* If unlocking, release physical memory */ 1247 if (flags & KPD_LOCKED) { 1248 pgcnt_t pages = btopr(len); 1249 if ((kpd->kp_flags & KPD_NO_ANON) == 0) 1250 atomic_add_long(&anon_segkp_pages_locked, -pages); 1251 page_unresv(pages); 1252 } 1253 return (0); 1254 } 1255 1256 /* 1257 * Insert the kpd in the hash table. 1258 */ 1259 static void 1260 segkp_insert(struct seg *seg, struct segkp_data *kpd) 1261 { 1262 struct segkp_segdata *kpsd = (struct segkp_segdata *)seg->s_data; 1263 int index; 1264 1265 /* 1266 * Insert the kpd based on the address that will be returned 1267 * via segkp_release. 1268 */ 1269 index = SEGKP_HASH(stom(kpd->kp_base, kpd->kp_flags)); 1270 mutex_enter(&segkp_lock); 1271 kpd->kp_next = kpsd->kpsd_hash[index]; 1272 kpsd->kpsd_hash[index] = kpd; 1273 mutex_exit(&segkp_lock); 1274 } 1275 1276 /* 1277 * Remove kpd from the hash table. 1278 */ 1279 static void 1280 segkp_delete(struct seg *seg, struct segkp_data *kpd) 1281 { 1282 struct segkp_segdata *kpsd = (struct segkp_segdata *)seg->s_data; 1283 struct segkp_data **kpp; 1284 int index; 1285 1286 ASSERT(MUTEX_HELD(&segkp_lock)); 1287 1288 index = SEGKP_HASH(stom(kpd->kp_base, kpd->kp_flags)); 1289 for (kpp = &kpsd->kpsd_hash[index]; 1290 *kpp != NULL; kpp = &((*kpp)->kp_next)) { 1291 if (*kpp == kpd) { 1292 *kpp = kpd->kp_next; 1293 return; 1294 } 1295 } 1296 panic("segkp_delete: unable to find element to delete"); 1297 /*NOTREACHED*/ 1298 } 1299 1300 /* 1301 * Find the kpd associated with a vaddr. 1302 * 1303 * Most of the callers of segkp_find will pass the vaddr that 1304 * hashes to the desired index, but there are cases where 1305 * this is not true in which case we have to (potentially) scan 1306 * the whole table looking for it. This should be very rare 1307 * (e.g. a segkp_fault(F_INVAL) on an address somewhere in the 1308 * middle of the segkp_data region). 1309 */ 1310 static struct segkp_data * 1311 segkp_find(struct seg *seg, caddr_t vaddr) 1312 { 1313 struct segkp_segdata *kpsd = (struct segkp_segdata *)seg->s_data; 1314 struct segkp_data *kpd; 1315 int i; 1316 int stop; 1317 1318 i = stop = SEGKP_HASH(vaddr); 1319 mutex_enter(&segkp_lock); 1320 do { 1321 for (kpd = kpsd->kpsd_hash[i]; kpd != NULL; 1322 kpd = kpd->kp_next) { 1323 if (vaddr >= kpd->kp_base && 1324 vaddr < kpd->kp_base + kpd->kp_len) { 1325 mutex_exit(&segkp_lock); 1326 return (kpd); 1327 } 1328 } 1329 if (--i < 0) 1330 i = SEGKP_HASHSZ - 1; /* Wrap */ 1331 } while (i != stop); 1332 mutex_exit(&segkp_lock); 1333 return (NULL); /* Not found */ 1334 } 1335 1336 /* 1337 * returns size of swappable area. 1338 */ 1339 size_t 1340 swapsize(caddr_t v) 1341 { 1342 struct segkp_data *kpd; 1343 1344 if ((kpd = segkp_find(segkp, v)) != NULL) 1345 return (SEGKP_MAPLEN(kpd->kp_len, kpd->kp_flags)); 1346 else 1347 return (NULL); 1348 } 1349 1350 /* 1351 * Dump out all the active segkp pages 1352 */ 1353 static void 1354 segkp_dump(struct seg *seg) 1355 { 1356 int i; 1357 struct segkp_data *kpd; 1358 struct segkp_segdata *kpsd = (struct segkp_segdata *)seg->s_data; 1359 1360 for (i = 0; i < SEGKP_HASHSZ; i++) { 1361 for (kpd = kpsd->kpsd_hash[i]; 1362 kpd != NULL; kpd = kpd->kp_next) { 1363 pfn_t pfn; 1364 caddr_t addr; 1365 caddr_t eaddr; 1366 1367 addr = kpd->kp_base; 1368 eaddr = addr + kpd->kp_len; 1369 while (addr < eaddr) { 1370 ASSERT(seg->s_as == &kas); 1371 pfn = hat_getpfnum(seg->s_as->a_hat, addr); 1372 if (pfn != PFN_INVALID) 1373 dump_addpage(seg->s_as, addr, pfn); 1374 addr += PAGESIZE; 1375 dump_timeleft = dump_timeout; 1376 } 1377 } 1378 } 1379 } 1380 1381 /*ARGSUSED*/ 1382 static int 1383 segkp_pagelock(struct seg *seg, caddr_t addr, size_t len, 1384 struct page ***ppp, enum lock_type type, enum seg_rw rw) 1385 { 1386 return (ENOTSUP); 1387 } 1388 1389 /*ARGSUSED*/ 1390 static int 1391 segkp_getmemid(struct seg *seg, caddr_t addr, memid_t *memidp) 1392 { 1393 return (ENODEV); 1394 } 1395 1396 /*ARGSUSED*/ 1397 static lgrp_mem_policy_info_t * 1398 segkp_getpolicy(struct seg *seg, caddr_t addr) 1399 { 1400 return (NULL); 1401 } 1402 1403 /*ARGSUSED*/ 1404 static int 1405 segkp_capable(struct seg *seg, segcapability_t capability) 1406 { 1407 return (0); 1408 } 1409 1410 #include <sys/mem_config.h> 1411 1412 /*ARGSUSED*/ 1413 static void 1414 segkp_mem_config_post_add(void *arg, pgcnt_t delta_pages) 1415 {} 1416 1417 /* 1418 * During memory delete, turn off caches so that pages are not held. 1419 * A better solution may be to unlock the pages while they are 1420 * in the cache so that they may be collected naturally. 1421 */ 1422 1423 /*ARGSUSED*/ 1424 static int 1425 segkp_mem_config_pre_del(void *arg, pgcnt_t delta_pages) 1426 { 1427 atomic_add_32(&segkp_indel, 1); 1428 segkp_cache_free(); 1429 return (0); 1430 } 1431 1432 /*ARGSUSED*/ 1433 static void 1434 segkp_mem_config_post_del(void *arg, pgcnt_t delta_pages, int cancelled) 1435 { 1436 atomic_add_32(&segkp_indel, -1); 1437 } 1438 1439 static kphysm_setup_vector_t segkp_mem_config_vec = { 1440 KPHYSM_SETUP_VECTOR_VERSION, 1441 segkp_mem_config_post_add, 1442 segkp_mem_config_pre_del, 1443 segkp_mem_config_post_del, 1444 }; 1445 1446 static void 1447 segkpinit_mem_config(struct seg *seg) 1448 { 1449 int ret; 1450 1451 ret = kphysm_setup_func_register(&segkp_mem_config_vec, (void *)seg); 1452 ASSERT(ret == 0); 1453 } 1454