The signal return code was trying to access user mode addresses
[dragonfly.git] / sys / platform / vkernel / platform / pmap.c
1 /*
2  * Copyright (c) 2006 The DragonFly Project.  All rights reserved.
3  * Copyright (c) 1991 Regents of the University of California.
4  * All rights reserved.
5  * Copyright (c) 1994 John S. Dyson
6  * All rights reserved.
7  * Copyright (c) 1994 David Greenman
8  * All rights reserved.
9  * Copyright (c) 2004-2006 Matthew Dillon
10  * All rights reserved.
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  * 
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in
20  *    the documentation and/or other materials provided with the
21  *    distribution.
22  * 3. Neither the name of The DragonFly Project nor the names of its
23  *    contributors may be used to endorse or promote products derived
24  *    from this software without specific, prior written permission.
25  * 
26  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
29  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
30  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
32  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
33  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
35  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
36  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  * 
39  * from:   @(#)pmap.c      7.7 (Berkeley)  5/12/91
40  * $FreeBSD: src/sys/i386/i386/pmap.c,v 1.250.2.18 2002/03/06 22:48:53 silby Exp $
41  * $DragonFly: src/sys/platform/vkernel/platform/pmap.c,v 1.7 2007/01/08 08:17:17 dillon Exp $
42  */
43
44 #include <sys/types.h>
45 #include <sys/systm.h>
46 #include <sys/kernel.h>
47 #include <sys/stat.h>
48 #include <sys/mman.h>
49 #include <sys/vkernel.h>
50 #include <sys/proc.h>
51 #include <sys/thread.h>
52 #include <sys/user.h>
53 #include <sys/vmspace.h>
54
55 #include <vm/pmap.h>
56 #include <vm/vm_page.h>
57 #include <vm/vm_extern.h>
58 #include <vm/vm_kern.h>
59 #include <vm/vm_object.h>
60 #include <vm/vm_zone.h>
61 #include <vm/vm_pageout.h>
62
63 #include <machine/md_var.h>
64 #include <machine/pcb.h>
65 #include <machine/pmap_inval.h>
66 #include <machine/globaldata.h>
67
68 #include <assert.h>
69
70 struct pmap kernel_pmap;
71
72 static struct vm_zone pvzone;
73 static struct vm_object pvzone_obj;
74 static TAILQ_HEAD(,pmap) pmap_list = TAILQ_HEAD_INITIALIZER(pmap_list);
75 static int pv_entry_count;
76 static int pv_entry_max;
77 static int pv_entry_high_water;
78 static int pmap_pagedaemon_waken;
79 static boolean_t pmap_initialized = FALSE;
80 static int protection_codes[8];
81
82 static void i386_protection_init(void);
83 static void pmap_remove_all(vm_page_t m);
84 static int pmap_release_free_page(struct pmap *pmap, vm_page_t p);
85
86 #define MINPV   2048
87 #ifndef PMAP_SHPGPERPROC
88 #define PMAP_SHPGPERPROC 200
89 #endif
90
91 #define pmap_pde(m, v)  (&((m)->pm_pdir[(vm_offset_t)(v) >> PDRSHIFT]))
92
93 #define pte_prot(m, p) \
94         (protection_codes[p & (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)])
95
96 void
97 pmap_init(void)
98 {
99         int i;
100         struct pv_entry *pvinit;
101
102         for (i = 0; i < vm_page_array_size; i++) {
103                 vm_page_t m;
104
105                 m = &vm_page_array[i];
106                 TAILQ_INIT(&m->md.pv_list);
107                 m->md.pv_list_count = 0;
108         }
109
110         i = vm_page_array_size;
111         if (i < MINPV)
112                 i = MINPV;
113         pvinit = (struct pv_entry *)kmem_alloc(&kernel_map, i*sizeof(*pvinit));
114         zbootinit(&pvzone, "PV ENTRY", sizeof(*pvinit), pvinit, i);
115         pmap_initialized = TRUE;
116 }
117
118 void
119 pmap_init2(void)
120 {
121         int shpgperproc = PMAP_SHPGPERPROC;
122
123         TUNABLE_INT_FETCH("vm.pmap.shpgperproc", &shpgperproc);
124         pv_entry_max = shpgperproc * maxproc + vm_page_array_size;
125         TUNABLE_INT_FETCH("vm.pmap.pv_entries", &pv_entry_max);
126         pv_entry_high_water = 9 * (pv_entry_max / 10);
127         zinitna(&pvzone, &pvzone_obj, NULL, 0, pv_entry_max, ZONE_INTERRUPT, 1);
128 }
129
130 /*
131  * Bootstrap the kernel_pmap so it can be used with pmap_enter().  
132  *
133  * NOTE! pm_pdir for the kernel pmap is offset so VA's translate
134  * directly into PTD indexes (PTA is also offset for the same reason).
135  * This is necessary because, for now, KVA is not mapped at address 0.
136  *
137  * Page table pages are not managed like they are in normal pmaps, so
138  * no pteobj is needed.
139  */
140 void
141 pmap_bootstrap(void)
142 {
143         vm_pindex_t i = (vm_offset_t)KernelPTD >> PAGE_SHIFT;
144
145         kernel_pmap.pm_pdir = KernelPTD - (KvaStart >> SEG_SHIFT);
146         kernel_pmap.pm_pdirpte = KernelPTA[i];
147         kernel_pmap.pm_count = 1;
148         kernel_pmap.pm_active = (cpumask_t)-1;
149         TAILQ_INIT(&kernel_pmap.pm_pvlist);
150         i386_protection_init();
151 }
152
153 /*
154  * Initialize pmap0/vmspace0 .  Since process 0 never enters user mode we
155  * just dummy it up so it works well enough for fork().
156  *
157  * In DragonFly, process pmaps may only be used to manipulate user address
158  * space, never kernel address space.
159  */
160 void
161 pmap_pinit0(struct pmap *pmap)
162 {
163         pmap_pinit(pmap);
164 }
165
166 /************************************************************************
167  *              Procedures to manage whole physical maps                *
168  ************************************************************************
169  *
170  * Initialize a preallocated and zeroed pmap structure,
171  * such as one in a vmspace structure.
172  */
173 void
174 pmap_pinit(struct pmap *pmap)
175 {
176         vm_page_t ptdpg;
177         int npages;
178
179         /*
180          * No need to allocate page table space yet but we do need a valid
181          * page directory table.
182          */
183         if (pmap->pm_pdir == NULL) {
184                 pmap->pm_pdir =
185                     (pd_entry_t *)kmem_alloc_pageable(&kernel_map, PAGE_SIZE);
186         }
187
188         /*
189          * allocate object for the pte array and page directory
190          */
191         npages = VPTE_PAGETABLE_SIZE +
192                  (VM_MAX_USER_ADDRESS / PAGE_SIZE) * sizeof(vpte_t);
193         npages = (npages + PAGE_MASK) / PAGE_SIZE;
194
195         if (pmap->pm_pteobj == NULL)
196                 pmap->pm_pteobj = vm_object_allocate(OBJT_DEFAULT, npages);
197         pmap->pm_pdindex = npages - 1;
198
199         /*
200          * allocate the page directory page
201          */
202         ptdpg = vm_page_grab(pmap->pm_pteobj, pmap->pm_pdindex,
203                              VM_ALLOC_NORMAL | VM_ALLOC_RETRY);
204
205         ptdpg->wire_count = 1;
206         ++vmstats.v_wire_count;
207
208         /* not usually mapped */
209         vm_page_flag_clear(ptdpg, PG_MAPPED | PG_BUSY);
210         ptdpg->valid = VM_PAGE_BITS_ALL;
211
212         pmap_kenter((vm_offset_t)pmap->pm_pdir, VM_PAGE_TO_PHYS(ptdpg));
213         pmap->pm_pdirpte = KernelPTA[(vm_offset_t)pmap->pm_pdir >> PAGE_SHIFT];
214         if ((ptdpg->flags & PG_ZERO) == 0)
215                 bzero(pmap->pm_pdir, PAGE_SIZE);
216
217         pmap->pm_count = 1;
218         pmap->pm_active = 0;
219         pmap->pm_ptphint = NULL;
220         TAILQ_INIT(&pmap->pm_pvlist);
221         bzero(&pmap->pm_stats, sizeof pmap->pm_stats);
222 }
223
224 /*
225  * Wire in kernel global address entries.  To avoid a race condition
226  * between pmap initialization and pmap_growkernel, this procedure
227  * adds the pmap to the master list (which growkernel scans to update),
228  * then copies the template.
229  *
230  * In a virtual kernel there are no kernel global address entries.
231  */
232 void
233 pmap_pinit2(struct pmap *pmap)
234 {
235         crit_enter();
236         TAILQ_INSERT_TAIL(&pmap_list, pmap, pm_pmnode);
237         crit_exit();
238 }
239
240 /*
241  * Release all resources held by the given physical map.
242  *
243  * Should only be called if the map contains no valid mappings.
244  */
245 static int pmap_release_callback(struct vm_page *p, void *data);
246
247 void
248 pmap_release(struct pmap *pmap)
249 {
250         struct mdglobaldata *gd = mdcpu;
251         vm_object_t object = pmap->pm_pteobj;
252         struct rb_vm_page_scan_info info;
253
254         KKASSERT(pmap != &kernel_pmap);
255
256 #if defined(DIAGNOSTIC)
257         if (object->ref_count != 1)
258                 panic("pmap_release: pteobj reference count != 1");
259 #endif
260 #ifdef SMP
261 #error "Must write code to clear PTxpdir cache across all CPUs"
262 #endif
263         /*
264          * Once we destroy the page table, the mapping becomes invalid.
265          * Rather then waste time doing a madvise 
266          */
267         if (pmap->pm_pdir == gd->gd_PT1pdir) {
268                 gd->gd_PT1pdir = NULL;
269                 *gd->gd_PT1pde = 0;
270                 /* madvise(gd->gd_PT1map, SEG_SIZE, MADV_INVAL); */
271         }
272         if (pmap->pm_pdir == gd->gd_PT2pdir) {
273                 gd->gd_PT2pdir = NULL;
274                 *gd->gd_PT2pde = 0;
275                 /* madvise(gd->gd_PT2map, SEG_SIZE, MADV_INVAL); */
276         }
277         
278         info.pmap = pmap;
279         info.object = object;
280         crit_enter();
281         TAILQ_REMOVE(&pmap_list, pmap, pm_pmnode);
282         crit_exit();
283
284         do {
285                 crit_enter();
286                 info.error = 0;
287                 info.mpte = NULL;
288                 info.limit = object->generation;
289
290                 vm_page_rb_tree_RB_SCAN(&object->rb_memq, NULL, 
291                                         pmap_release_callback, &info);
292                 if (info.error == 0 && info.mpte) {
293                         if (!pmap_release_free_page(pmap, info.mpte))
294                                 info.error = 1;
295                 }
296                 crit_exit();
297         } while (info.error);
298 }
299
300 static int
301 pmap_release_callback(struct vm_page *p, void *data)
302 {
303         struct rb_vm_page_scan_info *info = data;
304
305         if (p->pindex == info->pmap->pm_pdindex) {
306                 info->mpte = p;
307                 return(0);
308         }
309         if (!pmap_release_free_page(info->pmap, p)) {
310                 info->error = 1;
311                 return(-1);
312         }
313         if (info->object->generation != info->limit) {
314                 info->error = 1;
315                 return(-1);
316         }
317         return(0);
318 }
319
320 /*
321  * Retire the given physical map from service.  Should only be called if
322  * the map contains no valid mappings.
323  */
324 void
325 pmap_destroy(pmap_t pmap)
326 {
327         int count;
328
329         if (pmap == NULL)
330                 return;
331
332         count = --pmap->pm_count;
333         if (count == 0) {
334                 pmap_release(pmap);
335                 panic("destroying a pmap is not yet implemented");
336         }
337 }
338
339 /*
340  * Add a reference to the specified pmap.
341  */
342 void
343 pmap_reference(pmap_t pmap)
344 {
345         if (pmap != NULL) {
346                 pmap->pm_count++;
347         }
348 }
349
350 /************************************************************************
351  *                      VMSPACE MANAGEMENT                              *
352  ************************************************************************
353  *
354  * The VMSPACE management we do in our virtual kernel must be reflected
355  * in the real kernel.  This is accomplished by making vmspace system
356  * calls to the real kernel.
357  */
358 void
359 cpu_vmspace_alloc(struct vmspace *vm)
360 {
361         int r;
362         void *rp;
363
364 #define LAST_EXTENT     (VM_MAX_USER_ADDRESS - 0x80000000)
365
366         if (vmspace_create(&vm->vm_pmap, 0, NULL) < 0)
367                 panic("vmspace_create() failed");
368
369         rp = vmspace_mmap(&vm->vm_pmap, (void *)0x00000000, 0x40000000,
370                           PROT_READ|PROT_WRITE,
371                           MAP_FILE|MAP_SHARED|MAP_VPAGETABLE|MAP_FIXED,
372                           MemImageFd, 0);
373         if (rp == MAP_FAILED)
374                 panic("vmspace_mmap: failed1");
375         rp = vmspace_mmap(&vm->vm_pmap, (void *)0x40000000, 0x40000000,
376                           PROT_READ|PROT_WRITE,
377                           MAP_FILE|MAP_SHARED|MAP_VPAGETABLE|MAP_FIXED,
378                           MemImageFd, 0x40000000);
379         if (rp == MAP_FAILED)
380                 panic("vmspace_mmap: failed2");
381         rp = vmspace_mmap(&vm->vm_pmap, (void *)0x80000000, LAST_EXTENT,
382                           PROT_READ|PROT_WRITE,
383                           MAP_FILE|MAP_SHARED|MAP_VPAGETABLE|MAP_FIXED,
384                           MemImageFd, 0x80000000);
385         if (rp == MAP_FAILED)
386                 panic("vmspace_mmap: failed3");
387
388         r = vmspace_mcontrol(&vm->vm_pmap, (void *)0x00000000, 0x40000000, 
389                              MADV_SETMAP, vmspace_pmap(vm)->pm_pdirpte);
390         if (r < 0)
391                 panic("vmspace_mcontrol: failed1");
392         r = vmspace_mcontrol(&vm->vm_pmap, (void *)0x40000000, 0x40000000,
393                              MADV_SETMAP, vmspace_pmap(vm)->pm_pdirpte);
394         if (r < 0)
395                 panic("vmspace_mcontrol: failed2");
396         r = vmspace_mcontrol(&vm->vm_pmap, (void *)0x80000000, LAST_EXTENT,
397                              MADV_SETMAP, vmspace_pmap(vm)->pm_pdirpte);
398         if (r < 0)
399                 panic("vmspace_mcontrol: failed3");
400 }
401
402 void
403 cpu_vmspace_free(struct vmspace *vm)
404 {
405         if (vmspace_destroy(&vm->vm_pmap) < 0)
406                 panic("vmspace_destroy() failed");
407 }
408
409 /************************************************************************
410  *          Procedures which operate directly on the kernel PMAP        *
411  ************************************************************************/
412
413 /*
414  * This maps the requested page table and gives us access to it.
415  */
416 static vpte_t *
417 get_ptbase(struct pmap *pmap, vm_offset_t va)
418 {
419         struct mdglobaldata *gd = mdcpu;
420
421         if (pmap == &kernel_pmap) {
422                 KKASSERT(va >= KvaStart && va < KvaEnd);
423                 return(KernelPTA + (va >> PAGE_SHIFT));
424         } else if (pmap->pm_pdir == gd->gd_PT1pdir) {
425                 return(gd->gd_PT1map + (va >> PAGE_SHIFT));
426         } else if (pmap->pm_pdir == gd->gd_PT2pdir) {
427                 return(gd->gd_PT2map + (va >> PAGE_SHIFT));
428         }
429
430         /*
431          * Otherwise choose one or the other and map the page table
432          * in the KVA space reserved for it.
433          */
434         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
435                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
436
437         if ((gd->gd_PTflip = 1 - gd->gd_PTflip) == 0) {
438                 gd->gd_PT1pdir = pmap->pm_pdir;
439                 *gd->gd_PT1pde = pmap->pm_pdirpte;
440                 madvise(gd->gd_PT1map, SEG_SIZE, MADV_INVAL);
441                 return(gd->gd_PT1map + (va >> PAGE_SHIFT));
442         } else {
443                 gd->gd_PT2pdir = pmap->pm_pdir;
444                 *gd->gd_PT2pde = pmap->pm_pdirpte;
445                 madvise(gd->gd_PT2map, SEG_SIZE, MADV_INVAL);
446                 return(gd->gd_PT2map + (va >> PAGE_SHIFT));
447         }
448 }
449
450 static vpte_t *
451 get_ptbase1(struct pmap *pmap, vm_offset_t va)
452 {
453         struct mdglobaldata *gd = mdcpu;
454
455         if (pmap == &kernel_pmap) {
456                 KKASSERT(va >= KvaStart && va < KvaEnd);
457                 return(KernelPTA + (va >> PAGE_SHIFT));
458         } else if (pmap->pm_pdir == gd->gd_PT1pdir) {
459                 return(gd->gd_PT1map + (va >> PAGE_SHIFT));
460         }
461         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
462                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
463         gd->gd_PT1pdir = pmap->pm_pdir;
464         *gd->gd_PT1pde = pmap->pm_pdirpte;
465         madvise(gd->gd_PT1map, SEG_SIZE, MADV_INVAL);
466         return(gd->gd_PT1map + (va >> PAGE_SHIFT));
467 }
468
469 static vpte_t *
470 get_ptbase2(struct pmap *pmap, vm_offset_t va)
471 {
472         struct mdglobaldata *gd = mdcpu;
473
474         if (pmap == &kernel_pmap) {
475                 KKASSERT(va >= KvaStart && va < KvaEnd);
476                 return(KernelPTA + (va >> PAGE_SHIFT));
477         } else if (pmap->pm_pdir == gd->gd_PT2pdir) {
478                 return(gd->gd_PT2map + (va >> PAGE_SHIFT));
479         }
480         KKASSERT(gd->mi.gd_intr_nesting_level == 0 &&
481                  (gd->mi.gd_curthread->td_flags & TDF_INTTHREAD) == 0);
482         gd->gd_PT2pdir = pmap->pm_pdir;
483         *gd->gd_PT2pde = pmap->pm_pdirpte;
484         madvise(gd->gd_PT2map, SEG_SIZE, MADV_INVAL);
485         return(gd->gd_PT2map + (va >> PAGE_SHIFT));
486 }
487
488 /*
489  * Return a pointer to the page table entry for the specified va in the
490  * specified pmap.  NULL is returned if there is no valid page table page
491  * for the VA.
492  */
493 static __inline vpte_t *
494 pmap_pte(struct pmap *pmap, vm_offset_t va)
495 {
496         vpte_t *ptep;
497
498         ptep = &pmap->pm_pdir[va >> SEG_SHIFT];
499         if (*ptep & VPTE_PS)
500                 return(ptep);
501         if (*ptep)
502                 return (get_ptbase(pmap, va));
503         return(NULL);
504 }
505
506
507 /*
508  * Enter a mapping into kernel_pmap.  Mappings created in this fashion
509  * are not managed.
510  */
511 void
512 pmap_kenter(vm_offset_t va, vm_paddr_t pa)
513 {
514         vpte_t *ptep;
515         vpte_t npte;
516 #ifdef SMP
517         pmap_inval_info info;
518 #endif
519
520         KKASSERT(va >= KvaStart && va < KvaEnd);
521         npte = (vpte_t)pa | VPTE_R | VPTE_W | VPTE_V;
522         ptep = KernelPTA + (va >> PAGE_SHIFT);
523         if (*ptep & VPTE_V) {
524 #ifdef SMP
525                 pmap_inval_init(&info);
526                 pmap_inval_add(&info, &kernel_pmap, va);
527 #endif
528                 *ptep = npte;
529 #ifdef SMP
530                 pmap_inval_flush(&info);
531 #else
532                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
533 #endif
534         } else {
535                 *ptep = npte;
536         }
537 }
538
539 void
540 pmap_kenter_sync(vm_offset_t va)
541 {
542         pmap_inval_info info;
543
544         pmap_inval_init(&info);
545         pmap_inval_add(&info, &kernel_pmap, va);
546         pmap_inval_flush(&info);
547 }
548
549 void
550 pmap_kenter_sync_quick(vm_offset_t va)
551 {
552         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
553 }
554
555 /*
556  * XXX these need to be recoded.  They are not used in any critical path.
557  */
558 void
559 pmap_kmodify_rw(vm_offset_t va)
560 {
561         *pmap_kpte(va) |= VPTE_R | VPTE_W;
562         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
563 }
564
565 void
566 pmap_kmodify_nc(vm_offset_t va)
567 {
568 #if 0
569         *pmap_kpte(va) |= VPTE_N;
570         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
571 #endif
572 }
573
574 /*
575  * Map a contiguous range of physical memory to a KVM
576  */
577 vm_offset_t
578 pmap_map(vm_offset_t virt, vm_paddr_t start, vm_paddr_t end, int prot)
579 {
580         while (start < end) {
581                 pmap_kenter(virt, start);
582                 virt += PAGE_SIZE;
583                 start += PAGE_SIZE;
584         }
585         return (virt);
586 }
587
588 vpte_t *
589 pmap_kpte(vm_offset_t va)
590 {
591         vpte_t *ptep;
592
593         KKASSERT(va >= KvaStart && va < KvaEnd);
594         ptep = KernelPTA + (va >> PAGE_SHIFT);
595         return(ptep);
596 }
597
598 /*
599  * Enter a mapping into kernel_pmap without any SMP interactions.
600  * 
601  * Mappings created in this fashion are not managed.
602  */
603 void
604 pmap_kenter_quick(vm_offset_t va, vm_paddr_t pa)
605 {
606         vpte_t *ptep;
607         vpte_t npte;
608
609         KKASSERT(va >= KvaStart && va < KvaEnd);
610
611         npte = (vpte_t)pa | VPTE_R | VPTE_W | VPTE_V;
612         ptep = KernelPTA + (va >> PAGE_SHIFT);
613         if (*ptep & VPTE_V) {
614                 *ptep = npte;
615                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
616         } else {
617                 *ptep = npte;
618         }
619 }
620
621 /*
622  * Make a temporary mapping for a physical address.  This is only intended
623  * to be used for panic dumps.
624  */
625 void *
626 pmap_kenter_temporary(vm_paddr_t pa, int i)
627 {
628         pmap_kenter(crashdumpmap + (i * PAGE_SIZE), pa);
629         return ((void *)crashdumpmap);
630 }
631
632 /*
633  * Remove an unmanaged mapping created with pmap_kenter*().
634  */
635 void
636 pmap_kremove(vm_offset_t va)
637 {
638         vpte_t *ptep;
639 #ifdef SMP
640         pmap_inval_info info;
641 #endif
642
643         KKASSERT(va >= KvaStart && va < KvaEnd);
644
645         ptep = KernelPTA + (va >> PAGE_SHIFT);
646         if (*ptep & VPTE_V) {
647 #ifdef SMP
648                 pmap_inval_init(&info);
649                 pmap_inval_add(&info, &kernel_pmap, va);
650 #endif
651                 *ptep = 0;
652 #ifdef SMP
653                 pmap_inval_flush(&info);
654 #else
655                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
656 #endif
657         } else {
658                 *ptep = 0;
659         }
660
661 }
662
663 /*
664  * Remove an unmanaged mapping created with pmap_kenter*() without
665  * going through any SMP interactions.
666  */
667 void
668 pmap_kremove_quick(vm_offset_t va)
669 {
670         vpte_t *ptep;
671
672         KKASSERT(va >= KvaStart && va < KvaEnd);
673
674         ptep = KernelPTA + (va >> PAGE_SHIFT);
675         if (*ptep & VPTE_V) {
676                 *ptep = 0;
677                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
678         } else {
679                 *ptep = 0;
680         }
681 }
682
683 /*
684  * Extract the physical address from the kernel_pmap that is associated
685  * with the specified virtual address.
686  */
687 vm_paddr_t
688 pmap_kextract(vm_offset_t va)
689 {
690         vpte_t *ptep;
691         vm_paddr_t pa;
692
693         KKASSERT(va >= KvaStart && va < KvaEnd);
694
695         ptep = KernelPTA + (va >> PAGE_SHIFT);
696         pa = (vm_paddr_t)(*ptep & VPTE_FRAME) | (va & PAGE_MASK);
697         return(pa);
698 }
699
700 /*
701  * Map a set of unmanaged VM pages into KVM.
702  */
703 void
704 pmap_qenter(vm_offset_t va, struct vm_page **m, int count)
705 {
706         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
707         while (count) {
708                 vpte_t *ptep;
709
710                 ptep = KernelPTA + (va >> PAGE_SHIFT);
711                 if (*ptep & VPTE_V)
712                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
713                 *ptep = (vpte_t)(*m)->phys_addr | VPTE_R | VPTE_W | VPTE_V;
714                 --count;
715                 ++m;
716                 va += PAGE_SIZE;
717         }
718 #ifdef SMP
719         XXX
720         smp_invltlb();
721 #endif
722 }
723
724 /*
725  * Map a set of VM pages to kernel virtual memory.  If a mapping changes
726  * clear the supplied mask.  The caller handles any SMP interactions.
727  * The mask is used to provide the caller with hints on what SMP interactions
728  * might be needed.
729  */
730 void
731 pmap_qenter2(vm_offset_t va, struct vm_page **m, int count, cpumask_t *mask)
732 {
733         cpumask_t cmask = mycpu->gd_cpumask;
734
735         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
736         while (count) {
737                 vpte_t *ptep;
738                 vpte_t npte;
739
740                 ptep = KernelPTA + (va >> PAGE_SHIFT);
741                 npte = (vpte_t)(*m)->phys_addr | VPTE_R | VPTE_W | VPTE_V;
742                 if (*ptep != npte) {
743                         *mask = 0;
744                         *ptep = npte;
745                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
746                 } else if ((*mask & cmask) == 0) {
747                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
748                 }
749                 --count;
750                 ++m;
751                 va += PAGE_SIZE;
752         }
753         *mask |= cmask;
754 }
755
756 /*
757  * Undo the effects of pmap_qenter*().
758  */
759 void
760 pmap_qremove(vm_offset_t va, int count)
761 {
762         KKASSERT(va >= KvaStart && va + count * PAGE_SIZE < KvaEnd);
763         while (count) {
764                 vpte_t *ptep;
765
766                 ptep = KernelPTA + (va >> PAGE_SHIFT);
767                 if (*ptep & VPTE_V)
768                         madvise((void *)va, PAGE_SIZE, MADV_INVAL);
769                 *ptep = 0;
770                 --count;
771                 va += PAGE_SIZE;
772         }
773 #ifdef SMP
774         XXX
775         smp_invltlb();
776 #endif
777 }
778
779 /************************************************************************
780  *        Misc support glue called by machine independant code          *
781  ************************************************************************
782  *
783  * These routines are called by machine independant code to operate on
784  * certain machine-dependant aspects of processes, threads, and pmaps.
785  */
786
787 /*
788  * Initialize MD portions of the thread structure.
789  */
790 void
791 pmap_init_thread(thread_t td)
792 {
793         /* enforce pcb placement */
794         td->td_pcb = (struct pcb *)(td->td_kstack + td->td_kstack_size) - 1;
795         td->td_savefpu = &td->td_pcb->pcb_save;
796         td->td_sp = (char *)td->td_pcb - 16;
797 }
798
799 /*
800  * Initialize MD portions of a process structure. XXX this aint MD
801  */
802 void
803 pmap_init_proc(struct proc *p, struct thread *td)
804 {
805         p->p_addr = (void *)td->td_kstack;
806         p->p_thread = td;
807         td->td_proc = p;
808         td->td_lwp = &p->p_lwp;
809         td->td_switch = cpu_heavy_switch;
810 #ifdef SMP
811         KKASSERT(td->td_mpcount == 1);
812 #endif
813         bzero(p->p_addr, sizeof(*p->p_addr));
814 }
815
816 /*
817  * Destroy the UPAGES for a process that has exited and disassociate
818  * the process from its thread.
819  */
820 struct thread *
821 pmap_dispose_proc(struct proc *p)
822 {
823         struct thread *td;
824
825         KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
826
827         if ((td = p->p_thread) != NULL) {
828                 p->p_thread = NULL;
829                 td->td_proc = NULL;
830         }
831         p->p_addr = NULL;
832         return(td);
833 }
834
835 /*
836  * We pre-allocate all page table pages for kernel virtual memory so
837  * this routine will only be called if KVM has been exhausted.
838  */
839 void
840 pmap_growkernel(vm_offset_t size)
841 {
842         panic("KVM exhausted");
843 }
844
845 /*
846  * The modification bit is not tracked for any pages in this range. XXX
847  * such pages in this maps should always use pmap_k*() functions and not
848  * be managed anyhow.
849  */
850 static int
851 pmap_track_modified(vm_offset_t va)
852 {
853         if ((va < clean_sva) || (va >= clean_eva))
854                 return 1;
855         else
856                 return 0;
857 }
858
859 /************************************************************************
860  *          Procedures supporting managed page table pages              *
861  ************************************************************************
862  *
863  * These procedures are used to track managed page table pages.  These pages
864  * use the page table page's vm_page_t to track PTEs in the page.  The
865  * page table pages themselves are arranged in a VM object, pmap->pm_pteobj.
866  *
867  * This allows the system to throw away page table pages for user processes
868  * at will and reinstantiate them on demand.
869  */
870
871 /*
872  * This routine works like vm_page_lookup() but also blocks as long as the
873  * page is busy.  This routine does not busy the page it returns.
874  *
875  * Unless the caller is managing objects whos pages are in a known state,
876  * the call should be made with a critical section held so the page's object
877  * association remains valid on return.
878  */
879 static vm_page_t
880 pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
881 {
882         vm_page_t m;
883                          
884 retry:
885         m = vm_page_lookup(object, pindex);
886         if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))
887                 goto retry;
888         return(m);
889 }
890
891 /*
892  * This routine unholds page table pages, and if the hold count
893  * drops to zero, then it decrements the wire count.
894  */
895 static int 
896 _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info) 
897 {
898         pmap_inval_flush(info);
899         while (vm_page_sleep_busy(m, FALSE, "pmuwpt"))
900                 ;
901
902         if (m->hold_count == 0) {
903                 /*
904                  * unmap the page table page
905                  */
906                 pmap_inval_add(info, pmap, -1);
907                 pmap->pm_pdir[m->pindex] = 0;
908                 --pmap->pm_stats.resident_count;
909
910                 if (pmap->pm_ptphint == m)
911                         pmap->pm_ptphint = NULL;
912
913                 /*
914                  * If the page is finally unwired, simply free it.
915                  */
916                 --m->wire_count;
917                 if (m->wire_count == 0) {
918                         vm_page_flash(m);
919                         vm_page_busy(m);
920                         vm_page_free_zero(m);
921                         --vmstats.v_wire_count;
922                 }
923                 return 1;
924         }
925         return 0;
926 }
927
928 static __inline int
929 pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info)
930 {
931         vm_page_unhold(m);
932         if (m->hold_count == 0)
933                 return _pmap_unwire_pte_hold(pmap, m, info);
934         else
935                 return 0;
936 }
937
938 /*
939  * After removing a page table entry, this routine is used to
940  * conditionally free the page, and manage the hold/wire counts.
941  */
942 static int
943 pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte,
944                 pmap_inval_info_t info)
945 {
946         unsigned ptepindex;
947
948         if (mpte == NULL) {
949                 /*
950                  * page table pages in the kernel_pmap are not managed.
951                  */
952                 if (pmap == &kernel_pmap)
953                         return(0);
954                 ptepindex = (va >> PDRSHIFT);
955                 if (pmap->pm_ptphint &&
956                         (pmap->pm_ptphint->pindex == ptepindex)) {
957                         mpte = pmap->pm_ptphint;
958                 } else {
959                         pmap_inval_flush(info);
960                         mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
961                         pmap->pm_ptphint = mpte;
962                 }
963         }
964         return pmap_unwire_pte_hold(pmap, mpte, info);
965 }
966
967 /*
968  * Attempt to release and free an vm_page in a pmap.  Returns 1 on success,
969  * 0 on failure (if the procedure had to sleep).
970  */
971 static int
972 pmap_release_free_page(struct pmap *pmap, vm_page_t p)
973 {
974         vpte_t *pde = pmap->pm_pdir;
975         /*
976          * This code optimizes the case of freeing non-busy
977          * page-table pages.  Those pages are zero now, and
978          * might as well be placed directly into the zero queue.
979          */
980         if (vm_page_sleep_busy(p, FALSE, "pmaprl"))
981                 return 0;
982
983         vm_page_busy(p);
984
985         /*
986          * Remove the page table page from the processes address space.
987          */
988         pde[p->pindex] = 0;
989         pmap->pm_stats.resident_count--;
990
991         if (p->hold_count)  {
992                 panic("pmap_release: freeing held page table page");
993         }
994         /*
995          * Page directory pages need to have the kernel stuff cleared, so
996          * they can go into the zero queue also.
997          *
998          * In virtual kernels there is no 'kernel stuff'.  For the moment
999          * I just make sure the whole thing has been zero'd even though
1000          * it should already be completely zero'd.
1001          */
1002         if (p->pindex == pmap->pm_pdindex) {
1003                 bzero(pde, VPTE_PAGETABLE_SIZE);
1004                 pmap_kremove((vm_offset_t)pmap->pm_pdir);
1005         }
1006
1007         /*
1008          * Clear the matching hint
1009          */
1010         if (pmap->pm_ptphint && (pmap->pm_ptphint->pindex == p->pindex))
1011                 pmap->pm_ptphint = NULL;
1012
1013         /*
1014          * And throw the page away.  The page is completely zero'd out so
1015          * optimize the free call.
1016          */
1017         p->wire_count--;
1018         vmstats.v_wire_count--;
1019         vm_page_free_zero(p);
1020         return 1;
1021 }
1022
1023 /*
1024  * This routine is called if the page table page is not mapped in the page
1025  * table directory.
1026  *
1027  * The routine is broken up into two parts for readability.
1028  */
1029 static vm_page_t
1030 _pmap_allocpte(pmap_t pmap, unsigned ptepindex)
1031 {
1032         vm_paddr_t ptepa;
1033         vm_page_t m;
1034
1035         /*
1036          * Find or fabricate a new pagetable page
1037          */
1038         m = vm_page_grab(pmap->pm_pteobj, ptepindex,
1039                          VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
1040
1041         KASSERT(m->queue == PQ_NONE,
1042                 ("_pmap_allocpte: %p->queue != PQ_NONE", m));
1043
1044         if (m->wire_count == 0)
1045                 vmstats.v_wire_count++;
1046         m->wire_count++;
1047
1048         /*
1049          * Increment the hold count for the page table page
1050          * (denoting a new mapping.)
1051          */
1052         m->hold_count++;
1053
1054         /*
1055          * Map the pagetable page into the process address space, if
1056          * it isn't already there.
1057          */
1058         pmap->pm_stats.resident_count++;
1059
1060         ptepa = VM_PAGE_TO_PHYS(m);
1061         pmap->pm_pdir[ptepindex] = (vpte_t)ptepa | VPTE_R | VPTE_W | VPTE_V |
1062                                    VPTE_A | VPTE_M;
1063
1064         /*
1065          * We are likely about to access this page table page, so set the
1066          * page table hint to reduce overhead.
1067          */
1068         pmap->pm_ptphint = m;
1069
1070         /*
1071          * Try to use the new mapping, but if we cannot, then
1072          * do it with the routine that maps the page explicitly.
1073          */
1074         if ((m->flags & PG_ZERO) == 0)
1075                 pmap_zero_page(ptepa);
1076
1077         m->valid = VM_PAGE_BITS_ALL;
1078         vm_page_flag_clear(m, PG_ZERO);
1079         vm_page_flag_set(m, PG_MAPPED);
1080         vm_page_wakeup(m);
1081
1082         return (m);
1083 }
1084
1085 /*
1086  * Determine the page table page required to access the VA in the pmap
1087  * and allocate it if necessary.  Return a held vm_page_t for the page.
1088  *
1089  * Only used with user pmaps.
1090  */
1091 static vm_page_t
1092 pmap_allocpte(pmap_t pmap, vm_offset_t va)
1093 {
1094         unsigned ptepindex;
1095         vm_offset_t ptepa;
1096         vm_page_t m;
1097
1098         /*
1099          * Calculate pagetable page index
1100          */
1101         ptepindex = va >> PDRSHIFT;
1102
1103         /*
1104          * Get the page directory entry
1105          */
1106         ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1107
1108         /*
1109          * This supports switching from a 4MB page to a
1110          * normal 4K page.
1111          */
1112         if (ptepa & VPTE_PS) {
1113                 pmap->pm_pdir[ptepindex] = 0;
1114                 ptepa = 0;
1115                 cpu_invltlb();
1116                 smp_invltlb();
1117         }
1118
1119         /*
1120          * If the page table page is mapped, we just increment the
1121          * hold count, and activate it.
1122          */
1123         if (ptepa) {
1124                 /*
1125                  * In order to get the page table page, try the
1126                  * hint first.
1127                  */
1128                 if (pmap->pm_ptphint &&
1129                         (pmap->pm_ptphint->pindex == ptepindex)) {
1130                         m = pmap->pm_ptphint;
1131                 } else {
1132                         m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1133                         pmap->pm_ptphint = m;
1134                 }
1135                 m->hold_count++;
1136                 return m;
1137         }
1138         /*
1139          * Here if the pte page isn't mapped, or if it has been deallocated.
1140          */
1141         return _pmap_allocpte(pmap, ptepindex);
1142 }
1143
1144 /************************************************************************
1145  *                      Managed pages in pmaps                          *
1146  ************************************************************************
1147  *
1148  * All pages entered into user pmaps and some pages entered into the kernel
1149  * pmap are managed, meaning that pmap_protect() and other related management
1150  * functions work on these pages.
1151  */
1152
1153 /*
1154  * free the pv_entry back to the free list.  This function may be
1155  * called from an interrupt.
1156  */
1157 static __inline void
1158 free_pv_entry(pv_entry_t pv)
1159 {
1160         pv_entry_count--;
1161         zfree(&pvzone, pv);
1162 }
1163
1164 /*
1165  * get a new pv_entry, allocating a block from the system
1166  * when needed.  This function may be called from an interrupt.
1167  */
1168 static pv_entry_t
1169 get_pv_entry(void)
1170 {
1171         pv_entry_count++;
1172         if (pv_entry_high_water &&
1173                 (pv_entry_count > pv_entry_high_water) &&
1174                 (pmap_pagedaemon_waken == 0)) {
1175                 pmap_pagedaemon_waken = 1;
1176                 wakeup (&vm_pages_needed);
1177         }
1178         return zalloc(&pvzone);
1179 }
1180
1181 /*
1182  * This routine is very drastic, but can save the system
1183  * in a pinch.
1184  */
1185 void
1186 pmap_collect(void)
1187 {
1188         int i;
1189         vm_page_t m;
1190         static int warningdone=0;
1191
1192         if (pmap_pagedaemon_waken == 0)
1193                 return;
1194
1195         if (warningdone < 5) {
1196                 kprintf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
1197                 warningdone++;
1198         }
1199
1200         for(i = 0; i < vm_page_array_size; i++) {
1201                 m = &vm_page_array[i];
1202                 if (m->wire_count || m->hold_count || m->busy ||
1203                     (m->flags & PG_BUSY))
1204                         continue;
1205                 pmap_remove_all(m);
1206         }
1207         pmap_pagedaemon_waken = 0;
1208 }
1209         
1210 /*
1211  * If it is the first entry on the list, it is actually
1212  * in the header and we must copy the following entry up
1213  * to the header.  Otherwise we must search the list for
1214  * the entry.  In either case we free the now unused entry.
1215  */
1216 static int
1217 pmap_remove_entry(struct pmap *pmap, vm_page_t m, 
1218                   vm_offset_t va, pmap_inval_info_t info)
1219 {
1220         pv_entry_t pv;
1221         int rtval;
1222
1223         crit_enter();
1224         if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
1225                 TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1226                         if (pmap == pv->pv_pmap && va == pv->pv_va) 
1227                                 break;
1228                 }
1229         } else {
1230                 TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
1231                         if (va == pv->pv_va) 
1232                                 break;
1233                 }
1234         }
1235
1236         /*
1237          * Note that pv_ptem is NULL if the page table page itself is not
1238          * managed, even if the page being removed IS managed.
1239          */
1240         rtval = 0;
1241         if (pv) {
1242                 rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem, info);
1243                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1244                 m->md.pv_list_count--;
1245                 if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1246                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1247                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1248                 free_pv_entry(pv);
1249         }
1250         crit_exit();
1251         return rtval;
1252 }
1253
1254 /*
1255  * Create a pv entry for page at pa for (pmap, va).  If the page table page
1256  * holding the VA is managed, mpte will be non-NULL.
1257  */
1258 static void
1259 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t mpte, vm_page_t m)
1260 {
1261         pv_entry_t pv;
1262
1263         crit_enter();
1264         pv = get_pv_entry();
1265         pv->pv_va = va;
1266         pv->pv_pmap = pmap;
1267         pv->pv_ptem = mpte;
1268
1269         TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
1270         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
1271         m->md.pv_list_count++;
1272
1273         crit_exit();
1274 }
1275
1276 /*
1277  * pmap_remove_pte: do the things to unmap a page in a process
1278  */
1279 static int
1280 pmap_remove_pte(struct pmap *pmap, vpte_t *ptq, vm_offset_t va,
1281         pmap_inval_info_t info)
1282 {
1283         vpte_t oldpte;
1284         vm_page_t m;
1285
1286         pmap_inval_add(info, pmap, va);
1287         oldpte = loadandclear(ptq);
1288         if (oldpte & VPTE_W)
1289                 pmap->pm_stats.wired_count -= 1;
1290         /*
1291          * Machines that don't support invlpg, also don't support
1292          * VPTE_G.  XXX VPTE_G is disabled for SMP so don't worry about
1293          * the SMP case.
1294          */
1295         if (oldpte & VPTE_G)
1296                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
1297         pmap->pm_stats.resident_count -= 1;
1298         if (oldpte & PG_MANAGED) {
1299                 m = PHYS_TO_VM_PAGE(oldpte);
1300                 if (oldpte & VPTE_M) {
1301 #if defined(PMAP_DIAGNOSTIC)
1302                         if (pmap_nw_modified((pt_entry_t) oldpte)) {
1303                                 kprintf(
1304         "pmap_remove: modified page not writable: va: 0x%x, pte: 0x%x\n",
1305                                     va, oldpte);
1306                         }
1307 #endif
1308                         if (pmap_track_modified(va))
1309                                 vm_page_dirty(m);
1310                 }
1311                 if (oldpte & VPTE_A)
1312                         vm_page_flag_set(m, PG_REFERENCED);
1313                 return pmap_remove_entry(pmap, m, va, info);
1314         } else {
1315                 return pmap_unuse_pt(pmap, va, NULL, info);
1316         }
1317
1318         return 0;
1319 }
1320
1321 /*
1322  * pmap_remove_page:
1323  *
1324  *      Remove a single page from a process address space.
1325  *
1326  *      This function may not be called from an interrupt if the pmap is
1327  *      not kernel_pmap.
1328  */
1329 static void
1330 pmap_remove_page(struct pmap *pmap, vm_offset_t va, pmap_inval_info_t info)
1331 {
1332         vpte_t *ptq;
1333
1334         /*
1335          * if there is no pte for this address, just skip it!!!  Otherwise
1336          * get a local va for mappings for this pmap and remove the entry.
1337          */
1338         if (*pmap_pde(pmap, va) != 0) {
1339                 ptq = get_ptbase(pmap, va);
1340                 if (*ptq) {
1341                         pmap_remove_pte(pmap, ptq, va, info);
1342                 }
1343         }
1344 }
1345
1346 /*
1347  * pmap_remove:
1348  *
1349  *      Remove the given range of addresses from the specified map.
1350  *
1351  *      It is assumed that the start and end are properly
1352  *      rounded to the page size.
1353  *
1354  *      This function may not be called from an interrupt if the pmap is
1355  *      not kernel_pmap.
1356  */
1357 void
1358 pmap_remove(struct pmap *pmap, vm_offset_t sva, vm_offset_t eva)
1359 {
1360         vpte_t *ptbase;
1361         vm_offset_t pdnxt;
1362         vm_offset_t ptpaddr;
1363         vm_pindex_t sindex, eindex;
1364         vm_pindex_t sbase;
1365         struct pmap_inval_info info;
1366
1367         if (pmap == NULL)
1368                 return;
1369
1370         if (pmap->pm_stats.resident_count == 0)
1371                 return;
1372
1373         pmap_inval_init(&info);
1374
1375         /*
1376          * special handling of removing one page.  a very
1377          * common operation and easy to short circuit some
1378          * code.
1379          */
1380         if (((sva + PAGE_SIZE) == eva) && 
1381                 ((pmap->pm_pdir[(sva >> PDRSHIFT)] & VPTE_PS) == 0)) {
1382                 pmap_remove_page(pmap, sva, &info);
1383                 pmap_inval_flush(&info);
1384                 return;
1385         }
1386
1387         /*
1388          * Get a local virtual address for the mappings that are being
1389          * worked with.
1390          *
1391          * XXX this is really messy because the kernel pmap is not relative
1392          * to address 0
1393          */
1394         ptbase = get_ptbase(pmap, sva);
1395
1396         sindex = (sva >> PAGE_SHIFT);
1397         eindex = (eva >> PAGE_SHIFT);
1398         sbase = sindex;
1399
1400         for (; sindex < eindex; sindex = pdnxt) {
1401                 vpte_t pdirindex;
1402
1403                 /*
1404                  * Calculate index for next page table.
1405                  */
1406                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1407                 if (pmap->pm_stats.resident_count == 0)
1408                         break;
1409
1410                 pdirindex = sindex / NPDEPG;
1411                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1412                         pmap_inval_add(&info, pmap, -1);
1413                         pmap->pm_pdir[pdirindex] = 0;
1414                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1415                         continue;
1416                 }
1417
1418                 /*
1419                  * Weed out invalid mappings. Note: we assume that the page
1420                  * directory table is always allocated, and in kernel virtual.
1421                  */
1422                 if (ptpaddr == 0)
1423                         continue;
1424
1425                 /*
1426                  * Limit our scan to either the end of the va represented
1427                  * by the current page table page, or to the end of the
1428                  * range being removed.
1429                  */
1430                 if (pdnxt > eindex) {
1431                         pdnxt = eindex;
1432                 }
1433
1434                 for (; sindex != pdnxt; sindex++) {
1435                         vm_offset_t va;
1436                         if (ptbase[sindex - sbase] == 0)
1437                                 continue;
1438                         va = i386_ptob(sindex);
1439                         if (pmap_remove_pte(pmap, ptbase + sindex - sbase, va, &info))
1440                                 break;
1441                 }
1442         }
1443         pmap_inval_flush(&info);
1444 }
1445
1446 /*
1447  * pmap_remove_all:
1448  *
1449  * Removes this physical page from all physical maps in which it resides.
1450  * Reflects back modify bits to the pager.
1451  *
1452  * This routine may not be called from an interrupt.
1453  */
1454 static void
1455 pmap_remove_all(vm_page_t m)
1456 {
1457         struct pmap_inval_info info;
1458         vpte_t *pte, tpte;
1459         pv_entry_t pv;
1460
1461 #if defined(PMAP_DIAGNOSTIC)
1462         /*
1463          * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1464          * pages!
1465          */
1466         if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) {
1467                 panic("pmap_page_protect: illegal for unmanaged page, va: 0x%08llx", (long long)VM_PAGE_TO_PHYS(m));
1468         }
1469 #endif
1470
1471         pmap_inval_init(&info);
1472         crit_enter();
1473         while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1474                 pv->pv_pmap->pm_stats.resident_count--;
1475
1476                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
1477                 pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
1478
1479                 tpte = loadandclear(pte);
1480                 if (tpte & VPTE_W)
1481                         pv->pv_pmap->pm_stats.wired_count--;
1482
1483                 if (tpte & VPTE_A)
1484                         vm_page_flag_set(m, PG_REFERENCED);
1485
1486                 /*
1487                  * Update the vm_page_t clean and reference bits.
1488                  */
1489                 if (tpte & VPTE_M) {
1490 #if defined(PMAP_DIAGNOSTIC)
1491                         if (pmap_nw_modified((pt_entry_t) tpte)) {
1492                                 kprintf(
1493         "pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x\n",
1494                                     pv->pv_va, tpte);
1495                         }
1496 #endif
1497                         if (pmap_track_modified(pv->pv_va))
1498                                 vm_page_dirty(m);
1499                 }
1500                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
1501                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1502                 m->md.pv_list_count--;
1503                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem, &info);
1504                 free_pv_entry(pv);
1505         }
1506
1507         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1508         crit_exit();
1509         pmap_inval_flush(&info);
1510 }
1511
1512 /*
1513  * pmap_protect:
1514  *
1515  *      Set the physical protection on the specified range of this map
1516  *      as requested.
1517  *
1518  *      This function may not be called from an interrupt if the map is
1519  *      not the kernel_pmap.
1520  */
1521 void
1522 pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1523 {
1524         vpte_t *ptbase;
1525         vm_offset_t pdnxt, ptpaddr;
1526         vm_pindex_t sindex, eindex;
1527         vm_pindex_t sbase;
1528         pmap_inval_info info;
1529
1530         if (pmap == NULL)
1531                 return;
1532
1533         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1534                 pmap_remove(pmap, sva, eva);
1535                 return;
1536         }
1537
1538         if (prot & VM_PROT_WRITE)
1539                 return;
1540
1541         pmap_inval_init(&info);
1542
1543         ptbase = get_ptbase(pmap, sva);
1544
1545         sindex = (sva >> PAGE_SHIFT);
1546         eindex = (eva >> PAGE_SHIFT);
1547         sbase = sindex;
1548
1549         for (; sindex < eindex; sindex = pdnxt) {
1550
1551                 unsigned pdirindex;
1552
1553                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1554
1555                 pdirindex = sindex / NPDEPG;
1556                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1557                         pmap_inval_add(&info, pmap, -1);
1558                         pmap->pm_pdir[pdirindex] &= ~(VPTE_M|VPTE_W);
1559                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1560                         continue;
1561                 }
1562
1563                 /*
1564                  * Weed out invalid mappings. Note: we assume that the page
1565                  * directory table is always allocated, and in kernel virtual.
1566                  */
1567                 if (ptpaddr == 0)
1568                         continue;
1569
1570                 if (pdnxt > eindex) {
1571                         pdnxt = eindex;
1572                 }
1573
1574                 for (; sindex != pdnxt; sindex++) {
1575
1576                         unsigned pbits;
1577                         vm_page_t m;
1578
1579                         /* XXX this isn't optimal */
1580                         pmap_inval_add(&info, pmap, i386_ptob(sindex));
1581                         pbits = ptbase[sindex - sbase];
1582
1583                         if (pbits & PG_MANAGED) {
1584                                 m = NULL;
1585                                 if (pbits & VPTE_A) {
1586                                         m = PHYS_TO_VM_PAGE(pbits);
1587                                         vm_page_flag_set(m, PG_REFERENCED);
1588                                         pbits &= ~VPTE_A;
1589                                 }
1590                                 if (pbits & VPTE_M) {
1591                                         if (pmap_track_modified(i386_ptob(sindex))) {
1592                                                 if (m == NULL)
1593                                                         m = PHYS_TO_VM_PAGE(pbits);
1594                                                 vm_page_dirty(m);
1595                                                 pbits &= ~VPTE_M;
1596                                         }
1597                                 }
1598                         }
1599
1600                         pbits &= ~VPTE_W;
1601
1602                         if (pbits != ptbase[sindex - sbase]) {
1603                                 ptbase[sindex - sbase] = pbits;
1604                         }
1605                 }
1606         }
1607         pmap_inval_flush(&info);
1608 }
1609
1610 /*
1611  * Enter a managed page into a pmap.  If the page is not wired related pmap
1612  * data can be destroyed at any time for later demand-operation.
1613  *
1614  * Insert the vm_page (m) at virtual address (v) in (pmap), with the
1615  * specified protection, and wire the mapping if requested.
1616  *
1617  * NOTE: This routine may not lazy-evaluate or lose information.  The
1618  * page must actually be inserted into the given map NOW.
1619  *
1620  * NOTE: When entering a page at a KVA address, the pmap must be the
1621  * kernel_pmap.
1622  */
1623 void
1624 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1625            boolean_t wired)
1626 {
1627         vm_paddr_t pa;
1628         vpte_t *pte;
1629         vm_paddr_t opa;
1630         vm_offset_t origpte, newpte;
1631         vm_page_t mpte;
1632         pmap_inval_info info;
1633
1634         if (pmap == NULL)
1635                 return;
1636
1637         va &= VPTE_FRAME;
1638
1639         /*
1640          * Get the page table page.   The kernel_pmap's page table pages
1641          * are preallocated and have no associated vm_page_t.
1642          */
1643         if (pmap == &kernel_pmap)
1644                 mpte = NULL;
1645         else
1646                 mpte = pmap_allocpte(pmap, va);
1647
1648         pmap_inval_init(&info);
1649         pte = pmap_pte(pmap, va);
1650
1651         /*
1652          * Page Directory table entry not valid, we need a new PT page
1653          * and pmap_allocpte() didn't give us one.  Oops!
1654          */
1655         if (pte == NULL) {
1656                 panic("pmap_enter: invalid page directory pmap=%p, va=0x%p\n",
1657                       pmap, (void *)va);
1658         }
1659
1660         pa = VM_PAGE_TO_PHYS(m) & VPTE_FRAME;
1661         pmap_inval_add(&info, pmap, va); /* XXX non-optimal */
1662         origpte = *pte;
1663         opa = origpte & VPTE_FRAME;
1664 #if 0
1665         printf("pmap_enter: pmap %p va %08x pa %08x PDE %08x origpte %08x\n", pmap, va, (int)pa, pmap->pm_pdir[va >> SEG_SHIFT], origpte);
1666 #endif
1667
1668         if (origpte & VPTE_PS)
1669                 panic("pmap_enter: attempted pmap_enter on 4MB page");
1670
1671         /*
1672          * Mapping has not changed, must be protection or wiring change.
1673          */
1674         if (origpte && (opa == pa)) {
1675                 /*
1676                  * Wiring change, just update stats. We don't worry about
1677                  * wiring PT pages as they remain resident as long as there
1678                  * are valid mappings in them. Hence, if a user page is wired,
1679                  * the PT page will be also.
1680                  */
1681                 if (wired && ((origpte & VPTE_W) == 0))
1682                         pmap->pm_stats.wired_count++;
1683                 else if (!wired && (origpte & VPTE_W))
1684                         pmap->pm_stats.wired_count--;
1685
1686 #if defined(PMAP_DIAGNOSTIC)
1687                 if (pmap_nw_modified((pt_entry_t) origpte)) {
1688                         kprintf(
1689         "pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x\n",
1690                             va, origpte);
1691                 }
1692 #endif
1693
1694                 /*
1695                  * Remove the extra pte reference.  Note that we cannot
1696                  * optimize the RO->RW case because we have adjusted the
1697                  * wiring count above and may need to adjust the wiring
1698                  * bits below.
1699                  */
1700                 if (mpte)
1701                         mpte->hold_count--;
1702
1703                 /*
1704                  * We might be turning off write access to the page,
1705                  * so we go ahead and sense modify status.
1706                  */
1707                 if (origpte & PG_MANAGED) {
1708                         if ((origpte & VPTE_M) && pmap_track_modified(va)) {
1709                                 vm_page_t om;
1710                                 om = PHYS_TO_VM_PAGE(opa);
1711                                 vm_page_dirty(om);
1712                         }
1713                         pa |= PG_MANAGED;
1714                 }
1715                 goto validate;
1716         } 
1717         /*
1718          * Mapping has changed, invalidate old range and fall through to
1719          * handle validating new mapping.
1720          */
1721         if (opa) {
1722                 int err;
1723                 err = pmap_remove_pte(pmap, pte, va, &info);
1724                 if (err)
1725                         panic("pmap_enter: pte vanished, va: 0x%x", va);
1726         }
1727
1728         /*
1729          * Enter on the PV list if part of our managed memory. Note that we
1730          * raise IPL while manipulating pv_table since pmap_enter can be
1731          * called at interrupt time.
1732          */
1733         if (pmap_initialized && 
1734             (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) {
1735                 pmap_insert_entry(pmap, va, mpte, m);
1736                 pa |= PG_MANAGED;
1737         }
1738
1739         /*
1740          * Increment counters
1741          */
1742         pmap->pm_stats.resident_count++;
1743         if (wired)
1744                 pmap->pm_stats.wired_count++;
1745
1746 validate:
1747         /*
1748          * Now validate mapping with desired protection/wiring.
1749          */
1750         newpte = (vm_offset_t) (pa | pte_prot(pmap, prot) | VPTE_V);
1751
1752         if (wired)
1753                 newpte |= VPTE_W;
1754         newpte |= VPTE_U;
1755
1756         /*
1757          * if the mapping or permission bits are different, we need
1758          * to update the pte.
1759          */
1760         if ((origpte & ~(VPTE_M|VPTE_A)) != newpte) {
1761                 *pte = newpte | VPTE_A;
1762         }
1763         pmap_inval_flush(&info);
1764 }
1765
1766 /*
1767  * This is a quick version of pmap_enter().  It is used only under the 
1768  * following conditions:
1769  *
1770  * (1) The pmap is not the kernel_pmap
1771  * (2) The page is not to be wired into the map
1772  * (3) The page is to mapped read-only in the pmap (initially that is)
1773  * (4) The calling procedure is responsible for flushing the TLB
1774  * (5) The page is always managed
1775  * (6) There is no prior mapping at the VA
1776  */
1777
1778 static vm_page_t
1779 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t mpte)
1780 {
1781         vpte_t *pte;
1782         vm_paddr_t pa;
1783         pmap_inval_info info;
1784         unsigned ptepindex;
1785         vm_offset_t ptepa;
1786
1787         KKASSERT(pmap != &kernel_pmap);
1788         pmap_inval_init(&info);
1789
1790         KKASSERT(va >= VM_MIN_USER_ADDRESS && va < VM_MAX_USER_ADDRESS);
1791
1792         /*
1793          * Instantiate the page table page if required
1794          */
1795
1796         /*
1797          * Calculate pagetable page index
1798          */
1799         ptepindex = va >> PDRSHIFT;
1800         if (mpte && (mpte->pindex == ptepindex)) {
1801                 mpte->hold_count++;
1802         } else {
1803 retry:
1804                 /*
1805                  * Get the page directory entry
1806                  */
1807                 ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1808
1809                 /*
1810                  * If the page table page is mapped, we just increment
1811                  * the hold count, and activate it.
1812                  */
1813                 if (ptepa) {
1814                         if (ptepa & VPTE_PS)
1815                                 panic("pmap_enter_quick: unexpected mapping into 4MB page");
1816                         if (pmap->pm_ptphint &&
1817                                 (pmap->pm_ptphint->pindex == ptepindex)) {
1818                                 mpte = pmap->pm_ptphint;
1819                         } else {
1820                                 mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1821                                 pmap->pm_ptphint = mpte;
1822                         }
1823                         if (mpte == NULL)
1824                                 goto retry;
1825                         mpte->hold_count++;
1826                 } else {
1827                         mpte = _pmap_allocpte(pmap, ptepindex);
1828                 }
1829         }
1830
1831         /*
1832          * Ok, now that the page table page has been validated, get the pte.
1833          * If the pte is already mapped undo mpte's hold_count and
1834          * just return.
1835          */
1836         pte = pmap_pte(pmap, va);
1837         if (*pte) {
1838                 if (mpte)
1839                         pmap_unwire_pte_hold(pmap, mpte, &info);
1840                 return 0;
1841         }
1842
1843         /*
1844          * Enter on the PV list if part of our managed memory. Note that we
1845          * raise IPL while manipulating pv_table since pmap_enter can be
1846          * called at interrupt time.
1847          */
1848         if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0)
1849                 pmap_insert_entry(pmap, va, mpte, m);
1850
1851         /*
1852          * Increment counters
1853          */
1854         pmap->pm_stats.resident_count++;
1855
1856         pa = VM_PAGE_TO_PHYS(m);
1857
1858         /*
1859          * Now validate mapping with RO protection
1860          */
1861         if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED))
1862                 *pte = pa | VPTE_V | VPTE_U;
1863         else
1864                 *pte = pa | VPTE_V | VPTE_U | VPTE_MANAGED;
1865
1866         return mpte;
1867 }
1868
1869 vm_paddr_t
1870 pmap_extract(pmap_t pmap, vm_offset_t va)
1871 {
1872         vm_paddr_t rtval;
1873         vpte_t pte;
1874
1875         if (pmap && (pte = pmap->pm_pdir[va >> SEG_SHIFT]) != 0) {
1876                 if (pte & VPTE_PS) {
1877                         rtval = pte & ~((vpte_t)(1 << SEG_SHIFT) - 1);
1878                         rtval |= va & SEG_MASK;
1879                 } else {
1880                         pte = *get_ptbase(pmap, va);
1881                         rtval = (pte & VPTE_FRAME) | (va & PAGE_MASK);
1882                 }
1883                 return(rtval);
1884         }
1885         return(0);
1886 }
1887
1888 #define MAX_INIT_PT (96)
1889
1890 /*
1891  * This routine preloads the ptes for a given object into the specified pmap.
1892  * This eliminates the blast of soft faults on process startup and
1893  * immediately after an mmap.
1894  */
1895 static int pmap_object_init_pt_callback(vm_page_t p, void *data);
1896
1897 void
1898 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot,
1899                     vm_object_t object, vm_pindex_t pindex, 
1900                     vm_size_t size, int limit)
1901 {
1902         struct rb_vm_page_scan_info info;
1903         int psize;
1904
1905         /*
1906          * We can't preinit if read access isn't set or there is no pmap
1907          * or object.
1908          */
1909         if ((prot & VM_PROT_READ) == 0 || pmap == NULL || object == NULL)
1910                 return;
1911
1912         /*
1913          * We can't preinit if the pmap is not the current pmap
1914          */
1915         if (curproc == NULL || pmap != vmspace_pmap(curproc->p_vmspace))
1916                 return;
1917
1918         psize = size >> PAGE_SHIFT;
1919
1920         if ((object->type != OBJT_VNODE) ||
1921                 ((limit & MAP_PREFAULT_PARTIAL) && (psize > MAX_INIT_PT) &&
1922                         (object->resident_page_count > MAX_INIT_PT))) {
1923                 return;
1924         }
1925
1926         if (psize + pindex > object->size) {
1927                 if (object->size < pindex)
1928                         return;           
1929                 psize = object->size - pindex;
1930         }
1931
1932         if (psize == 0)
1933                 return;
1934
1935         /*
1936          * Use a red-black scan to traverse the requested range and load
1937          * any valid pages found into the pmap.
1938          *
1939          * We cannot safely scan the object's memq unless we are in a
1940          * critical section since interrupts can remove pages from objects.
1941          */
1942         info.start_pindex = pindex;
1943         info.end_pindex = pindex + psize - 1;
1944         info.limit = limit;
1945         info.mpte = NULL;
1946         info.addr = addr;
1947         info.pmap = pmap;
1948
1949         crit_enter();
1950         vm_page_rb_tree_RB_SCAN(&object->rb_memq, rb_vm_page_scancmp,
1951                                 pmap_object_init_pt_callback, &info);
1952         crit_exit();
1953 }
1954
1955 static
1956 int
1957 pmap_object_init_pt_callback(vm_page_t p, void *data)
1958 {
1959         struct rb_vm_page_scan_info *info = data;
1960         vm_pindex_t rel_index;
1961         /*
1962          * don't allow an madvise to blow away our really
1963          * free pages allocating pv entries.
1964          */
1965         if ((info->limit & MAP_PREFAULT_MADVISE) &&
1966                 vmstats.v_free_count < vmstats.v_free_reserved) {
1967                     return(-1);
1968         }
1969         if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
1970             (p->busy == 0) && (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
1971                 if ((p->queue - p->pc) == PQ_CACHE)
1972                         vm_page_deactivate(p);
1973                 vm_page_busy(p);
1974                 rel_index = p->pindex - info->start_pindex;
1975                 info->mpte = pmap_enter_quick(info->pmap,
1976                                               info->addr + i386_ptob(rel_index),
1977                                               p, info->mpte);
1978                 vm_page_flag_set(p, PG_MAPPED);
1979                 vm_page_wakeup(p);
1980         }
1981         return(0);
1982 }
1983
1984 /*
1985  * pmap_prefault provides a quick way of clustering pagefaults into a
1986  * processes address space.  It is a "cousin" of pmap_object_init_pt, 
1987  * except it runs at page fault time instead of mmap time.
1988  */
1989 #define PFBAK 4
1990 #define PFFOR 4
1991 #define PAGEORDER_SIZE (PFBAK+PFFOR)
1992
1993 static int pmap_prefault_pageorder[] = {
1994         -PAGE_SIZE, PAGE_SIZE,
1995         -2 * PAGE_SIZE, 2 * PAGE_SIZE,
1996         -3 * PAGE_SIZE, 3 * PAGE_SIZE,
1997         -4 * PAGE_SIZE, 4 * PAGE_SIZE
1998 };
1999
2000 void
2001 pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
2002 {
2003         int i;
2004         vm_offset_t starta;
2005         vm_offset_t addr;
2006         vm_pindex_t pindex;
2007         vm_page_t m, mpte;
2008         vm_object_t object;
2009
2010         /*
2011          * We do not currently prefault mappings that use virtual page
2012          * tables.  We do not prefault foreign pmaps.
2013          */
2014         if (entry->maptype == VM_MAPTYPE_VPAGETABLE)
2015                 return;
2016         if (curproc == NULL || (pmap != vmspace_pmap(curproc->p_vmspace)))
2017                 return;
2018
2019         object = entry->object.vm_object;
2020
2021         starta = addra - PFBAK * PAGE_SIZE;
2022         if (starta < entry->start)
2023                 starta = entry->start;
2024         else if (starta > addra)
2025                 starta = 0;
2026
2027         /*
2028          * critical section protection is required to maintain the 
2029          * page/object association, interrupts can free pages and remove 
2030          * them from their objects.
2031          */
2032         mpte = NULL;
2033         crit_enter();
2034         for (i = 0; i < PAGEORDER_SIZE; i++) {
2035                 vm_object_t lobject;
2036                 vpte_t *pte;
2037
2038                 addr = addra + pmap_prefault_pageorder[i];
2039                 if (addr > addra + (PFFOR * PAGE_SIZE))
2040                         addr = 0;
2041
2042                 if (addr < starta || addr >= entry->end)
2043                         continue;
2044
2045                 /*
2046                  * Make sure the page table page already exists
2047                  */
2048                 if ((*pmap_pde(pmap, addr)) == NULL) 
2049                         continue;
2050
2051                 /*
2052                  * Get a pointer to the pte and make sure that no valid page
2053                  * has been mapped.
2054                  */
2055                 pte = get_ptbase(pmap, addr);
2056                 if (*pte)
2057                         continue;
2058
2059                 /*
2060                  * Get the page to be mapped
2061                  */
2062                 pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
2063                 lobject = object;
2064
2065                 for (m = vm_page_lookup(lobject, pindex);
2066                     (!m && (lobject->type == OBJT_DEFAULT) &&
2067                      (lobject->backing_object));
2068                     lobject = lobject->backing_object
2069                 ) {
2070                         if (lobject->backing_object_offset & PAGE_MASK)
2071                                 break;
2072                         pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
2073                         m = vm_page_lookup(lobject->backing_object, pindex);
2074                 }
2075
2076                 /*
2077                  * give-up when a page is not in memory
2078                  */
2079                 if (m == NULL)
2080                         break;
2081
2082                 /*
2083                  * If everything meets the requirements for pmap_enter_quick(),
2084                  * then enter the page.
2085                  */
2086
2087                 if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2088                         (m->busy == 0) &&
2089                     (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2090
2091                         if ((m->queue - m->pc) == PQ_CACHE) {
2092                                 vm_page_deactivate(m);
2093                         }
2094                         vm_page_busy(m);
2095                         mpte = pmap_enter_quick(pmap, addr, m, mpte);
2096                         vm_page_flag_set(m, PG_MAPPED);
2097                         vm_page_wakeup(m);
2098                 }
2099         }
2100         crit_exit();
2101 }
2102
2103 /*
2104  *      Routine:        pmap_change_wiring
2105  *      Function:       Change the wiring attribute for a map/virtual-address
2106  *                      pair.
2107  *      In/out conditions:
2108  *                      The mapping must already exist in the pmap.
2109  */
2110 void
2111 pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
2112 {
2113         vpte_t *pte;
2114
2115         if (pmap == NULL)
2116                 return;
2117
2118         pte = get_ptbase(pmap, va);
2119
2120         if (wired && (*pte & VPTE_W) == 0)
2121                 pmap->pm_stats.wired_count++;
2122         else if (!wired && (*pte & VPTE_W))
2123                 pmap->pm_stats.wired_count--;
2124
2125         /*
2126          * Wiring is not a hardware characteristic so there is no need to
2127          * invalidate TLB.  However, in an SMP environment we must use
2128          * a locked bus cycle to update the pte (if we are not using 
2129          * the pmap_inval_*() API that is)... it's ok to do this for simple
2130          * wiring changes.
2131          */
2132 #ifdef SMP
2133         if (wired)
2134                 atomic_set_int(pte, VPTE_W);
2135         else
2136                 atomic_clear_int(pte, VPTE_W);
2137 #else
2138         if (wired)
2139                 atomic_set_int_nonlocked(pte, VPTE_W);
2140         else
2141                 atomic_clear_int_nonlocked(pte, VPTE_W);
2142 #endif
2143 }
2144
2145 /*
2146  *      Copy the range specified by src_addr/len
2147  *      from the source map to the range dst_addr/len
2148  *      in the destination map.
2149  *
2150  *      This routine is only advisory and need not do anything.
2151  */
2152 void
2153 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, 
2154         vm_size_t len, vm_offset_t src_addr)
2155 {
2156         pmap_inval_info info;
2157         vm_offset_t addr;
2158         vm_offset_t end_addr = src_addr + len;
2159         vm_offset_t pdnxt;
2160         vpte_t *src_frame;
2161         vpte_t *dst_frame;
2162         vm_page_t m;
2163
2164         if (dst_addr != src_addr)
2165                 return;
2166         if (dst_pmap->pm_pdir == NULL)
2167                 return;
2168         if (src_pmap->pm_pdir == NULL)
2169                 return;
2170
2171         src_frame = get_ptbase1(src_pmap, src_addr);
2172         dst_frame = get_ptbase2(dst_pmap, src_addr);
2173
2174         pmap_inval_init(&info);
2175         pmap_inval_add(&info, dst_pmap, -1);
2176         pmap_inval_add(&info, src_pmap, -1);
2177
2178         /*
2179          * critical section protection is required to maintain the page/object
2180          * association, interrupts can free pages and remove them from 
2181          * their objects.
2182          */
2183         crit_enter();
2184         for (addr = src_addr; addr < end_addr; addr = pdnxt) {
2185                 vpte_t *src_pte, *dst_pte;
2186                 vm_page_t dstmpte, srcmpte;
2187                 vm_offset_t srcptepaddr;
2188                 unsigned ptepindex;
2189
2190                 if (addr >= VM_MAX_USER_ADDRESS)
2191                         panic("pmap_copy: invalid to pmap_copy page tables\n");
2192
2193                 /*
2194                  * Don't let optional prefaulting of pages make us go
2195                  * way below the low water mark of free pages or way
2196                  * above high water mark of used pv entries.
2197                  */
2198                 if (vmstats.v_free_count < vmstats.v_free_reserved ||
2199                     pv_entry_count > pv_entry_high_water)
2200                         break;
2201                 
2202                 pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
2203                 ptepindex = addr >> PDRSHIFT;
2204
2205                 srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[ptepindex];
2206                 if (srcptepaddr == 0)
2207                         continue;
2208                         
2209                 if (srcptepaddr & VPTE_PS) {
2210                         if (dst_pmap->pm_pdir[ptepindex] == 0) {
2211                                 dst_pmap->pm_pdir[ptepindex] = (pd_entry_t) srcptepaddr;
2212                                 dst_pmap->pm_stats.resident_count += NBPDR / PAGE_SIZE;
2213                         }
2214                         continue;
2215                 }
2216
2217                 srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
2218                 if ((srcmpte == NULL) ||
2219                         (srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
2220                         continue;
2221
2222                 if (pdnxt > end_addr)
2223                         pdnxt = end_addr;
2224
2225                 src_pte = src_frame + ((addr - src_addr) >> PAGE_SHIFT);
2226                 dst_pte = dst_frame + ((addr - src_addr) >> PAGE_SHIFT);
2227                 while (addr < pdnxt) {
2228                         vpte_t ptetemp;
2229                         ptetemp = *src_pte;
2230                         /*
2231                          * we only virtual copy managed pages
2232                          */
2233                         if ((ptetemp & PG_MANAGED) != 0) {
2234                                 /*
2235                                  * We have to check after allocpte for the
2236                                  * pte still being around...  allocpte can
2237                                  * block.
2238                                  */
2239                                 dstmpte = pmap_allocpte(dst_pmap, addr);
2240                                 if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
2241                                         /*
2242                                          * Clear the modified and
2243                                          * accessed (referenced) bits
2244                                          * during the copy.
2245                                          */
2246                                         m = PHYS_TO_VM_PAGE(ptetemp);
2247                                         *dst_pte = ptetemp & ~(VPTE_M | VPTE_A);
2248                                         dst_pmap->pm_stats.resident_count++;
2249                                         pmap_insert_entry(dst_pmap, addr,
2250                                                 dstmpte, m);
2251                                 } else {
2252                                         pmap_unwire_pte_hold(dst_pmap, dstmpte, &info);
2253                                 }
2254                                 if (dstmpte->hold_count >= srcmpte->hold_count)
2255                                         break;
2256                         }
2257                         addr += PAGE_SIZE;
2258                         src_pte++;
2259                         dst_pte++;
2260                 }
2261         }
2262         crit_exit();
2263         pmap_inval_flush(&info);
2264 }       
2265
2266 /*
2267  * pmap_zero_page:
2268  *
2269  *      Zero the specified PA by mapping the page into KVM and clearing its
2270  *      contents.
2271  *
2272  *      This function may be called from an interrupt and no locking is
2273  *      required.
2274  */
2275 void
2276 pmap_zero_page(vm_paddr_t phys)
2277 {
2278         struct mdglobaldata *gd = mdcpu;
2279
2280         crit_enter();
2281         if (*gd->gd_CMAP3)
2282                 panic("pmap_zero_page: CMAP3 busy");
2283         *gd->gd_CMAP3 = VPTE_V | VPTE_W | (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2284         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2285
2286         bzero(gd->gd_CADDR3, PAGE_SIZE);
2287         *gd->gd_CMAP3 = 0;
2288         crit_exit();
2289 }
2290
2291 /*
2292  * pmap_page_assertzero:
2293  *
2294  *      Assert that a page is empty, panic if it isn't.
2295  */
2296 void
2297 pmap_page_assertzero(vm_paddr_t phys)
2298 {
2299         struct mdglobaldata *gd = mdcpu;
2300         int i;
2301
2302         crit_enter();
2303         if (*gd->gd_CMAP3)
2304                 panic("pmap_zero_page: CMAP3 busy");
2305         *gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W |
2306                         (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2307         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2308         for (i = 0; i < PAGE_SIZE; i += 4) {
2309             if (*(int *)((char *)gd->gd_CADDR3 + i) != 0) {
2310                 panic("pmap_page_assertzero() @ %p not zero!\n",
2311                     (void *)gd->gd_CADDR3);
2312             }
2313         }
2314         *gd->gd_CMAP3 = 0;
2315         crit_exit();
2316 }
2317
2318 /*
2319  * pmap_zero_page:
2320  *
2321  *      Zero part of a physical page by mapping it into memory and clearing
2322  *      its contents with bzero.
2323  *
2324  *      off and size may not cover an area beyond a single hardware page.
2325  */
2326 void
2327 pmap_zero_page_area(vm_paddr_t phys, int off, int size)
2328 {
2329         struct mdglobaldata *gd = mdcpu;
2330
2331         crit_enter();
2332         if (*gd->gd_CMAP3)
2333                 panic("pmap_zero_page: CMAP3 busy");
2334         *gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W |
2335                         (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2336         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2337
2338         bzero((char *)gd->gd_CADDR3 + off, size);
2339         *gd->gd_CMAP3 = 0;
2340         crit_exit();
2341 }
2342
2343 /*
2344  * pmap_copy_page:
2345  *
2346  *      Copy the physical page from the source PA to the target PA.
2347  *      This function may be called from an interrupt.  No locking
2348  *      is required.
2349  */
2350 void
2351 pmap_copy_page(vm_paddr_t src, vm_paddr_t dst)
2352 {
2353         struct mdglobaldata *gd = mdcpu;
2354
2355         crit_enter();
2356         if (*(int *) gd->gd_CMAP1)
2357                 panic("pmap_copy_page: CMAP1 busy");
2358         if (*(int *) gd->gd_CMAP2)
2359                 panic("pmap_copy_page: CMAP2 busy");
2360
2361         *(int *) gd->gd_CMAP1 = VPTE_V | VPTE_R | (src & PG_FRAME) | VPTE_A;
2362         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2363
2364         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2365         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2366
2367         bcopy(gd->gd_CADDR1, gd->gd_CADDR2, PAGE_SIZE);
2368
2369         *(int *) gd->gd_CMAP1 = 0;
2370         *(int *) gd->gd_CMAP2 = 0;
2371         crit_exit();
2372 }
2373
2374 /*
2375  * pmap_copy_page_frag:
2376  *
2377  *      Copy the physical page from the source PA to the target PA.
2378  *      This function may be called from an interrupt.  No locking
2379  *      is required.
2380  */
2381 void
2382 pmap_copy_page_frag(vm_paddr_t src, vm_paddr_t dst, size_t bytes)
2383 {
2384         struct mdglobaldata *gd = mdcpu;
2385
2386         crit_enter();
2387         if (*(int *) gd->gd_CMAP1)
2388                 panic("pmap_copy_page: CMAP1 busy");
2389         if (*(int *) gd->gd_CMAP2)
2390                 panic("pmap_copy_page: CMAP2 busy");
2391
2392         *(int *) gd->gd_CMAP1 = VPTE_V | (src & VPTE_FRAME) | VPTE_A;
2393         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2394
2395         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2396         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2397
2398         bcopy((char *)gd->gd_CADDR1 + (src & PAGE_MASK),
2399               (char *)gd->gd_CADDR2 + (dst & PAGE_MASK),
2400               bytes);
2401
2402         *(int *) gd->gd_CMAP1 = 0;
2403         *(int *) gd->gd_CMAP2 = 0;
2404         crit_exit();
2405 }
2406
2407 /*
2408  * Returns true if the pmap's pv is one of the first
2409  * 16 pvs linked to from this page.  This count may
2410  * be changed upwards or downwards in the future; it
2411  * is only necessary that true be returned for a small
2412  * subset of pmaps for proper page aging.
2413  */
2414 boolean_t
2415 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
2416 {
2417         pv_entry_t pv;
2418         int loops = 0;
2419
2420         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2421                 return FALSE;
2422
2423         crit_enter();
2424
2425         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2426                 if (pv->pv_pmap == pmap) {
2427                         crit_exit();
2428                         return TRUE;
2429                 }
2430                 loops++;
2431                 if (loops >= 16)
2432                         break;
2433         }
2434         crit_exit();
2435         return (FALSE);
2436 }
2437
2438 /*
2439  * Remove all pages from specified address space
2440  * this aids process exit speeds.  Also, this code
2441  * is special cased for current process only, but
2442  * can have the more generic (and slightly slower)
2443  * mode enabled.  This is much faster than pmap_remove
2444  * in the case of running down an entire address space.
2445  */
2446 void
2447 pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
2448 {
2449         vpte_t *pte, tpte;
2450         pv_entry_t pv, npv;
2451         vm_page_t m;
2452         pmap_inval_info info;
2453         int iscurrentpmap;
2454
2455         if (curproc && pmap == vmspace_pmap(curproc->p_vmspace))
2456                 iscurrentpmap = 1;
2457         else
2458                 iscurrentpmap = 0;
2459
2460         pmap_inval_init(&info);
2461         crit_enter();
2462         for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
2463                 if (pv->pv_va >= eva || pv->pv_va < sva) {
2464                         npv = TAILQ_NEXT(pv, pv_plist);
2465                         continue;
2466                 }
2467
2468                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2469                 pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
2470                 tpte = *pte;
2471
2472                 /*
2473                  * We cannot remove wired pages from a process' mapping
2474                  * at this time
2475                  */
2476                 if (tpte & VPTE_W) {
2477                         npv = TAILQ_NEXT(pv, pv_plist);
2478                         continue;
2479                 }
2480                 *pte = 0;
2481
2482                 m = PHYS_TO_VM_PAGE(tpte);
2483
2484                 KASSERT(m < &vm_page_array[vm_page_array_size],
2485                         ("pmap_remove_pages: bad tpte %x", tpte));
2486
2487                 pv->pv_pmap->pm_stats.resident_count--;
2488
2489                 /*
2490                  * Update the vm_page_t clean and reference bits.
2491                  */
2492                 if (tpte & VPTE_M) {
2493                         vm_page_dirty(m);
2494                 }
2495
2496
2497                 npv = TAILQ_NEXT(pv, pv_plist);
2498                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
2499
2500                 m->md.pv_list_count--;
2501                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2502                 if (TAILQ_FIRST(&m->md.pv_list) == NULL) {
2503                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
2504                 }
2505
2506                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem, &info);
2507                 free_pv_entry(pv);
2508         }
2509         pmap_inval_flush(&info);
2510         crit_exit();
2511 }
2512
2513 /*
2514  * pmap_testbit tests bits in pte's
2515  * note that the testbit/changebit routines are inline,
2516  * and a lot of things compile-time evaluate.
2517  */
2518 static boolean_t
2519 pmap_testbit(vm_page_t m, int bit)
2520 {
2521         pv_entry_t pv;
2522         vpte_t *pte;
2523
2524         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2525                 return FALSE;
2526
2527         if (TAILQ_FIRST(&m->md.pv_list) == NULL)
2528                 return FALSE;
2529
2530         crit_enter();
2531
2532         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2533                 /*
2534                  * if the bit being tested is the modified bit, then
2535                  * mark clean_map and ptes as never
2536                  * modified.
2537                  */
2538                 if (bit & (VPTE_A|VPTE_M)) {
2539                         if (!pmap_track_modified(pv->pv_va))
2540                                 continue;
2541                 }
2542
2543 #if defined(PMAP_DIAGNOSTIC)
2544                 if (!pv->pv_pmap) {
2545                         kprintf("Null pmap (tb) at va: 0x%x\n", pv->pv_va);
2546                         continue;
2547                 }
2548 #endif
2549                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2550                 if (*pte & bit) {
2551                         crit_exit();
2552                         return TRUE;
2553                 }
2554         }
2555         crit_exit();
2556         return (FALSE);
2557 }
2558
2559 /*
2560  * this routine is used to modify bits in ptes
2561  */
2562 static __inline void
2563 pmap_changebit(vm_page_t m, int bit, boolean_t setem)
2564 {
2565         struct pmap_inval_info info;
2566         pv_entry_t pv;
2567         vpte_t *pte;
2568
2569         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2570                 return;
2571
2572         pmap_inval_init(&info);
2573         crit_enter();
2574
2575         /*
2576          * Loop over all current mappings setting/clearing as appropos If
2577          * setting RO do we need to clear the VAC?
2578          */
2579         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2580                 /*
2581                  * don't write protect pager mappings
2582                  */
2583                 if (!setem && (bit == VPTE_W)) {
2584                         if (!pmap_track_modified(pv->pv_va))
2585                                 continue;
2586                 }
2587
2588 #if defined(PMAP_DIAGNOSTIC)
2589                 if (!pv->pv_pmap) {
2590                         kprintf("Null pmap (cb) at va: 0x%x\n", pv->pv_va);
2591                         continue;
2592                 }
2593 #endif
2594
2595                 /*
2596                  * Careful here.  We can use a locked bus instruction to
2597                  * clear VPTE_A or VPTE_M safely but we need to synchronize
2598                  * with the target cpus when we mess with VPTE_W.
2599                  */
2600                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2601                 if (bit == VPTE_W)
2602                         pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
2603
2604                 if (setem) {
2605 #ifdef SMP
2606                         atomic_set_int(pte, bit);
2607 #else
2608                         atomic_set_int_nonlocked(pte, bit);
2609 #endif
2610                 } else {
2611                         vpte_t pbits = *pte;
2612                         if (pbits & bit) {
2613                                 if (bit == VPTE_W) {
2614                                         if (pbits & VPTE_M) {
2615                                                 vm_page_dirty(m);
2616                                         }
2617 #ifdef SMP
2618                                         atomic_clear_int(pte, VPTE_M|VPTE_W);
2619 #else
2620                                         atomic_clear_int_nonlocked(pte, VPTE_M|VPTE_W);
2621 #endif
2622                                 } else {
2623 #ifdef SMP
2624                                         atomic_clear_int(pte, bit);
2625 #else
2626                                         atomic_clear_int_nonlocked(pte, bit);
2627 #endif
2628                                 }
2629                         }
2630                 }
2631         }
2632         pmap_inval_flush(&info);
2633         crit_exit();
2634 }
2635
2636 /*
2637  *      pmap_page_protect:
2638  *
2639  *      Lower the permission for all mappings to a given page.
2640  */
2641 void
2642 pmap_page_protect(vm_page_t m, vm_prot_t prot)
2643 {
2644         if ((prot & VM_PROT_WRITE) == 0) {
2645                 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2646                         pmap_changebit(m, VPTE_W, FALSE);
2647                 } else {
2648                         pmap_remove_all(m);
2649                 }
2650         }
2651 }
2652
2653 vm_paddr_t
2654 pmap_phys_address(int ppn)
2655 {
2656         return (i386_ptob(ppn));
2657 }
2658
2659 /*
2660  *      pmap_ts_referenced:
2661  *
2662  *      Return a count of reference bits for a page, clearing those bits.
2663  *      It is not necessary for every reference bit to be cleared, but it
2664  *      is necessary that 0 only be returned when there are truly no
2665  *      reference bits set.
2666  *
2667  *      XXX: The exact number of bits to check and clear is a matter that
2668  *      should be tested and standardized at some point in the future for
2669  *      optimal aging of shared pages.
2670  */
2671 int
2672 pmap_ts_referenced(vm_page_t m)
2673 {
2674         pv_entry_t pv, pvf, pvn;
2675         vpte_t *pte;
2676         int rtval = 0;
2677
2678         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2679                 return (rtval);
2680
2681         crit_enter();
2682
2683         if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
2684
2685                 pvf = pv;
2686
2687                 do {
2688                         pvn = TAILQ_NEXT(pv, pv_list);
2689
2690                         TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2691
2692                         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
2693
2694                         if (!pmap_track_modified(pv->pv_va))
2695                                 continue;
2696
2697                         pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2698
2699                         if (pte && (*pte & VPTE_A)) {
2700 #ifdef SMP
2701                                 atomic_clear_int(pte, VPTE_A);
2702 #else
2703                                 atomic_clear_int_nonlocked(pte, VPTE_A);
2704 #endif
2705                                 rtval++;
2706                                 if (rtval > 4) {
2707                                         break;
2708                                 }
2709                         }
2710                 } while ((pv = pvn) != NULL && pv != pvf);
2711         }
2712         crit_exit();
2713
2714         return (rtval);
2715 }
2716
2717 /*
2718  *      pmap_is_modified:
2719  *
2720  *      Return whether or not the specified physical page was modified
2721  *      in any physical maps.
2722  */
2723 boolean_t
2724 pmap_is_modified(vm_page_t m)
2725 {
2726         return pmap_testbit(m, VPTE_M);
2727 }
2728
2729 /*
2730  *      Clear the modify bits on the specified physical page.
2731  */
2732 void
2733 pmap_clear_modify(vm_page_t m)
2734 {
2735         pmap_changebit(m, VPTE_M, FALSE);
2736 }
2737
2738 /*
2739  *      pmap_clear_reference:
2740  *
2741  *      Clear the reference bit on the specified physical page.
2742  */
2743 void
2744 pmap_clear_reference(vm_page_t m)
2745 {
2746         pmap_changebit(m, VPTE_A, FALSE);
2747 }
2748
2749 /*
2750  * Miscellaneous support routines follow
2751  */
2752
2753 static void
2754 i386_protection_init(void)
2755 {
2756         int *kp, prot;
2757
2758         kp = protection_codes;
2759         for (prot = 0; prot < 8; prot++) {
2760                 if (prot & VM_PROT_READ)
2761                         *kp |= VPTE_R;
2762                 if (prot & VM_PROT_WRITE)
2763                         *kp |= VPTE_W;
2764                 if (prot & VM_PROT_EXECUTE)
2765                         *kp |= VPTE_X;
2766                 ++kp;
2767         }
2768 }
2769
2770 /*
2771  * Map a set of physical memory pages into the kernel virtual
2772  * address space. Return a pointer to where it is mapped. This
2773  * routine is intended to be used for mapping device memory,
2774  * NOT real memory.
2775  *
2776  * NOTE: we can't use pgeflag unless we invalidate the pages one at
2777  * a time.
2778  */
2779 void *
2780 pmap_mapdev(vm_paddr_t pa, vm_size_t size)
2781 {
2782         vm_offset_t va, tmpva, offset;
2783         vpte_t *pte;
2784
2785         offset = pa & PAGE_MASK;
2786         size = roundup(offset + size, PAGE_SIZE);
2787
2788         va = kmem_alloc_nofault(&kernel_map, size);
2789         if (!va)
2790                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
2791
2792         pa = pa & VPTE_FRAME;
2793         for (tmpva = va; size > 0;) {
2794                 pte = KernelPTA + (tmpva >> PAGE_SHIFT);
2795                 *pte = pa | VPTE_R | VPTE_W | VPTE_V; /* | pgeflag; */
2796                 size -= PAGE_SIZE;
2797                 tmpva += PAGE_SIZE;
2798                 pa += PAGE_SIZE;
2799         }
2800         cpu_invltlb();
2801         smp_invltlb();
2802
2803         return ((void *)(va + offset));
2804 }
2805
2806 void
2807 pmap_unmapdev(vm_offset_t va, vm_size_t size)
2808 {
2809         vm_offset_t base, offset;
2810
2811         base = va & VPTE_FRAME;
2812         offset = va & PAGE_MASK;
2813         size = roundup(offset + size, PAGE_SIZE);
2814         pmap_qremove(va, size >> PAGE_SHIFT);
2815         kmem_free(&kernel_map, base, size);
2816 }
2817
2818 /*
2819  * perform the pmap work for mincore
2820  */
2821 int
2822 pmap_mincore(pmap_t pmap, vm_offset_t addr)
2823 {
2824         vpte_t *ptep, pte;
2825         vm_page_t m;
2826         int val = 0;
2827         
2828         ptep = pmap_pte(pmap, addr);
2829         if (ptep == 0) {
2830                 return 0;
2831         }
2832
2833         if ((pte = *ptep) != 0) {
2834                 vm_offset_t pa;
2835
2836                 val = MINCORE_INCORE;
2837                 if ((pte & VPTE_MANAGED) == 0)
2838                         return val;
2839
2840                 pa = pte & VPTE_FRAME;
2841
2842                 m = PHYS_TO_VM_PAGE(pa);
2843
2844                 /*
2845                  * Modified by us
2846                  */
2847                 if (pte & VPTE_M)
2848                         val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
2849                 /*
2850                  * Modified by someone
2851                  */
2852                 else if (m->dirty || pmap_is_modified(m))
2853                         val |= MINCORE_MODIFIED_OTHER;
2854                 /*
2855                  * Referenced by us
2856                  */
2857                 if (pte & VPTE_A)
2858                         val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
2859
2860                 /*
2861                  * Referenced by someone
2862                  */
2863                 else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
2864                         val |= MINCORE_REFERENCED_OTHER;
2865                         vm_page_flag_set(m, PG_REFERENCED);
2866                 }
2867         } 
2868         return val;
2869 }
2870
2871 void
2872 pmap_activate(struct proc *p)
2873 {
2874         pmap_t  pmap;
2875
2876         pmap = vmspace_pmap(p->p_vmspace);
2877 #if defined(SMP)
2878         atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
2879 #else
2880         pmap->pm_active |= 1;
2881 #endif
2882 #if defined(SWTCH_OPTIM_STATS)
2883         tlb_flush_count++;
2884 #endif
2885 #if 0
2886         p->p_thread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
2887         load_cr3(p->p_thread->td_pcb->pcb_cr3);
2888 #endif
2889 }
2890
2891 void
2892 pmap_deactivate(struct proc *p)
2893 {
2894         pmap_t  pmap;
2895
2896         pmap = vmspace_pmap(p->p_vmspace);
2897 #if defined(SMP)
2898         atomic_clear_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
2899 #else
2900         pmap->pm_active &= ~1;
2901 #endif
2902         /*
2903          * XXX - note we do not adjust %cr3.  The caller is expected to
2904          * activate a new pmap or do a thread-exit.
2905          */
2906 }
2907
2908 vm_offset_t
2909 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
2910 {
2911
2912         if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
2913                 return addr;
2914         }
2915
2916         addr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
2917         return addr;
2918 }
2919
2920
2921 #if defined(DEBUG)
2922
2923 static void     pads (pmap_t pm);
2924 void            pmap_pvdump (vm_paddr_t pa);
2925
2926 /* print address space of pmap*/
2927 static void
2928 pads(pmap_t pm)
2929 {
2930         vm_offset_t va;
2931         int i, j;
2932         vpte_t *ptep;
2933
2934         if (pm == &kernel_pmap)
2935                 return;
2936         for (i = 0; i < 1024; i++)
2937                 if (pm->pm_pdir[i])
2938                         for (j = 0; j < 1024; j++) {
2939                                 va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
2940                                 if (pm == &kernel_pmap && va < KERNBASE)
2941                                         continue;
2942                                 if (pm != &kernel_pmap && va > UPT_MAX_ADDRESS)
2943                                         continue;
2944                                 ptep = pmap_pte(pm, va);
2945                                 if (ptep && (*ptep & VPTE_V)) {
2946                                         kprintf("%p:%x ",
2947                                                 (void *)va, (unsigned)*ptep);
2948                                 }
2949                         };
2950
2951 }
2952
2953 void
2954 pmap_pvdump(vm_paddr_t pa)
2955 {
2956         pv_entry_t pv;
2957         vm_page_t m;
2958
2959         kprintf("pa %08llx", (long long)pa);
2960         m = PHYS_TO_VM_PAGE(pa);
2961         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2962 #ifdef used_to_be
2963                 kprintf(" -> pmap %p, va %x, flags %x",
2964                     (void *)pv->pv_pmap, pv->pv_va, pv->pv_flags);
2965 #endif
2966                 kprintf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va);
2967                 pads(pv->pv_pmap);
2968         }
2969         kprintf(" ");
2970 }
2971 #endif
2972