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