1:1 Userland threading stage 2.11/4:
[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.16 2007/02/03 17:05:59 corecode 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         struct lwp *lp = ONLY_LWP_IN_PROC(p);
859
860         p->p_addr = (void *)td->td_kstack;
861         lp->lwp_thread = td;
862         td->td_proc = p;
863         td->td_lwp = lp;
864         td->td_switch = cpu_heavy_switch;
865 #ifdef SMP
866         KKASSERT(td->td_mpcount == 1);
867 #endif
868         bzero(p->p_addr, sizeof(*p->p_addr));
869 }
870
871 /*
872  * Destroy the UPAGES for a process that has exited and disassociate
873  * the process from its thread.
874  */
875 struct thread *
876 pmap_dispose_proc(struct proc *p)
877 {
878         struct thread *td = NULL;
879         struct lwp *lp;
880
881         KASSERT(p->p_lock == 0, ("attempt to dispose referenced proc! %p", p));
882
883         lp = ONLY_LWP_IN_PROC(p);
884         if (lp != NULL && (td = lp->lwp_thread) != NULL) {
885                 lp->lwp_thread = NULL;
886                 td->td_lwp = NULL;
887                 td->td_proc = NULL;
888         }
889         p->p_addr = NULL;
890         return(td);
891 }
892
893 /*
894  * We pre-allocate all page table pages for kernel virtual memory so
895  * this routine will only be called if KVM has been exhausted.
896  */
897 void
898 pmap_growkernel(vm_offset_t addr)
899 {
900         addr = (addr + PAGE_SIZE * NPTEPG) & ~(PAGE_SIZE * NPTEPG - 1);
901
902         if (addr > virtual_end - SEG_SIZE)
903                 panic("KVM exhausted");
904         kernel_vm_end = addr;
905 }
906
907 /*
908  * The modification bit is not tracked for any pages in this range. XXX
909  * such pages in this maps should always use pmap_k*() functions and not
910  * be managed anyhow.
911  *
912  * XXX User and kernel address spaces are independant for virtual kernels,
913  * this function only applies to the kernel pmap.
914  */
915 static int
916 pmap_track_modified(pmap_t pmap, vm_offset_t va)
917 {
918         if (pmap != &kernel_pmap)
919                 return 1;
920         if ((va < clean_sva) || (va >= clean_eva))
921                 return 1;
922         else
923                 return 0;
924 }
925
926 /************************************************************************
927  *          Procedures supporting managed page table pages              *
928  ************************************************************************
929  *
930  * These procedures are used to track managed page table pages.  These pages
931  * use the page table page's vm_page_t to track PTEs in the page.  The
932  * page table pages themselves are arranged in a VM object, pmap->pm_pteobj.
933  *
934  * This allows the system to throw away page table pages for user processes
935  * at will and reinstantiate them on demand.
936  */
937
938 /*
939  * This routine works like vm_page_lookup() but also blocks as long as the
940  * page is busy.  This routine does not busy the page it returns.
941  *
942  * Unless the caller is managing objects whos pages are in a known state,
943  * the call should be made with a critical section held so the page's object
944  * association remains valid on return.
945  */
946 static vm_page_t
947 pmap_page_lookup(vm_object_t object, vm_pindex_t pindex)
948 {
949         vm_page_t m;
950                          
951 retry:
952         m = vm_page_lookup(object, pindex);
953         if (m && vm_page_sleep_busy(m, FALSE, "pplookp"))
954                 goto retry;
955         return(m);
956 }
957
958 /*
959  * This routine unholds page table pages, and if the hold count
960  * drops to zero, then it decrements the wire count.
961  */
962 static int 
963 _pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info) 
964 {
965         pmap_inval_flush(info);
966         while (vm_page_sleep_busy(m, FALSE, "pmuwpt"))
967                 ;
968
969         if (m->hold_count == 0) {
970                 /*
971                  * unmap the page table page
972                  */
973                 pmap->pm_pdir[m->pindex] = 0;
974                 --pmap->pm_stats.resident_count;
975                 inval_ptbase_pagedir(pmap, m->pindex);
976
977                 if (pmap->pm_ptphint == m)
978                         pmap->pm_ptphint = NULL;
979
980                 /*
981                  * If the page is finally unwired, simply free it.
982                  */
983                 --m->wire_count;
984                 if (m->wire_count == 0) {
985                         vm_page_flash(m);
986                         vm_page_busy(m);
987                         vm_page_free_zero(m);
988                         --vmstats.v_wire_count;
989                 }
990                 return 1;
991         }
992         return 0;
993 }
994
995 static __inline int
996 pmap_unwire_pte_hold(pmap_t pmap, vm_page_t m, pmap_inval_info_t info)
997 {
998         vm_page_unhold(m);
999         if (m->hold_count == 0)
1000                 return _pmap_unwire_pte_hold(pmap, m, info);
1001         else
1002                 return 0;
1003 }
1004
1005 /*
1006  * After removing a page table entry, this routine is used to
1007  * conditionally free the page, and manage the hold/wire counts.
1008  */
1009 static int
1010 pmap_unuse_pt(pmap_t pmap, vm_offset_t va, vm_page_t mpte,
1011                 pmap_inval_info_t info)
1012 {
1013         unsigned ptepindex;
1014
1015         if (mpte == NULL) {
1016                 /*
1017                  * page table pages in the kernel_pmap are not managed.
1018                  */
1019                 if (pmap == &kernel_pmap)
1020                         return(0);
1021                 ptepindex = (va >> PDRSHIFT);
1022                 if (pmap->pm_ptphint &&
1023                         (pmap->pm_ptphint->pindex == ptepindex)) {
1024                         mpte = pmap->pm_ptphint;
1025                 } else {
1026                         pmap_inval_flush(info);
1027                         mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1028                         pmap->pm_ptphint = mpte;
1029                 }
1030         }
1031         return pmap_unwire_pte_hold(pmap, mpte, info);
1032 }
1033
1034 /*
1035  * Attempt to release and free an vm_page in a pmap.  Returns 1 on success,
1036  * 0 on failure (if the procedure had to sleep).
1037  */
1038 static int
1039 pmap_release_free_page(struct pmap *pmap, vm_page_t p)
1040 {
1041         vpte_t *pde = pmap->pm_pdir;
1042         /*
1043          * This code optimizes the case of freeing non-busy
1044          * page-table pages.  Those pages are zero now, and
1045          * might as well be placed directly into the zero queue.
1046          */
1047         if (vm_page_sleep_busy(p, FALSE, "pmaprl"))
1048                 return 0;
1049
1050         vm_page_busy(p);
1051         pmap->pm_stats.resident_count--;
1052
1053         if (p->hold_count)  {
1054                 panic("pmap_release: freeing held page table page");
1055         }
1056         /*
1057          * Page directory pages need to have the kernel stuff cleared, so
1058          * they can go into the zero queue also.
1059          *
1060          * In virtual kernels there is no 'kernel stuff'.  For the moment
1061          * I just make sure the whole thing has been zero'd even though
1062          * it should already be completely zero'd.
1063          *
1064          * pmaps for vkernels do not self-map because they do not share
1065          * their address space with the vkernel.  Clearing of pde[] thus
1066          * only applies to page table pages and not to the page directory
1067          * page.
1068          */
1069         if (p->pindex == pmap->pm_pdindex) {
1070                 bzero(pde, VPTE_PAGETABLE_SIZE);
1071                 pmap_kremove((vm_offset_t)pmap->pm_pdir);
1072         } else {
1073                 pde[p->pindex] = 0;
1074         }
1075
1076         /*
1077          * Clear the matching hint
1078          */
1079         if (pmap->pm_ptphint && (pmap->pm_ptphint->pindex == p->pindex))
1080                 pmap->pm_ptphint = NULL;
1081
1082         /*
1083          * And throw the page away.  The page is completely zero'd out so
1084          * optimize the free call.
1085          */
1086         p->wire_count--;
1087         vmstats.v_wire_count--;
1088         vm_page_free_zero(p);
1089         return 1;
1090 }
1091
1092 /*
1093  * This routine is called if the page table page is not mapped in the page
1094  * table directory.
1095  *
1096  * The routine is broken up into two parts for readability.
1097  */
1098 static vm_page_t
1099 _pmap_allocpte(pmap_t pmap, unsigned ptepindex)
1100 {
1101         vm_paddr_t ptepa;
1102         vm_page_t m;
1103
1104         /*
1105          * Find or fabricate a new pagetable page
1106          */
1107         m = vm_page_grab(pmap->pm_pteobj, ptepindex,
1108                          VM_ALLOC_NORMAL | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
1109
1110         KASSERT(m->queue == PQ_NONE,
1111                 ("_pmap_allocpte: %p->queue != PQ_NONE", m));
1112
1113         if (m->wire_count == 0)
1114                 vmstats.v_wire_count++;
1115         m->wire_count++;
1116
1117         /*
1118          * Increment the hold count for the page table page
1119          * (denoting a new mapping.)
1120          */
1121         m->hold_count++;
1122
1123         /*
1124          * Map the pagetable page into the process address space, if
1125          * it isn't already there.
1126          */
1127         pmap->pm_stats.resident_count++;
1128
1129         ptepa = VM_PAGE_TO_PHYS(m);
1130         pmap->pm_pdir[ptepindex] = (vpte_t)ptepa | VPTE_R | VPTE_W | VPTE_V |
1131                                    VPTE_A | VPTE_M;
1132
1133         /*
1134          * We are likely about to access this page table page, so set the
1135          * page table hint to reduce overhead.
1136          */
1137         pmap->pm_ptphint = m;
1138
1139         /*
1140          * Try to use the new mapping, but if we cannot, then
1141          * do it with the routine that maps the page explicitly.
1142          */
1143         if ((m->flags & PG_ZERO) == 0)
1144                 pmap_zero_page(ptepa);
1145
1146         m->valid = VM_PAGE_BITS_ALL;
1147         vm_page_flag_clear(m, PG_ZERO);
1148         vm_page_flag_set(m, PG_MAPPED);
1149         vm_page_wakeup(m);
1150
1151         return (m);
1152 }
1153
1154 /*
1155  * Determine the page table page required to access the VA in the pmap
1156  * and allocate it if necessary.  Return a held vm_page_t for the page.
1157  *
1158  * Only used with user pmaps.
1159  */
1160 static vm_page_t
1161 pmap_allocpte(pmap_t pmap, vm_offset_t va)
1162 {
1163         unsigned ptepindex;
1164         vm_offset_t ptepa;
1165         vm_page_t m;
1166
1167         /*
1168          * Calculate pagetable page index
1169          */
1170         ptepindex = va >> PDRSHIFT;
1171
1172         /*
1173          * Get the page directory entry
1174          */
1175         ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1176
1177         /*
1178          * This supports switching from a 4MB page to a
1179          * normal 4K page.
1180          */
1181         if (ptepa & VPTE_PS) {
1182                 pmap->pm_pdir[ptepindex] = 0;
1183                 ptepa = 0;
1184                 cpu_invltlb();
1185                 smp_invltlb();
1186         }
1187
1188         /*
1189          * If the page table page is mapped, we just increment the
1190          * hold count, and activate it.
1191          */
1192         if (ptepa) {
1193                 /*
1194                  * In order to get the page table page, try the
1195                  * hint first.
1196                  */
1197                 if (pmap->pm_ptphint &&
1198                         (pmap->pm_ptphint->pindex == ptepindex)) {
1199                         m = pmap->pm_ptphint;
1200                 } else {
1201                         m = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1202                         pmap->pm_ptphint = m;
1203                 }
1204                 m->hold_count++;
1205                 return m;
1206         }
1207         /*
1208          * Here if the pte page isn't mapped, or if it has been deallocated.
1209          */
1210         return _pmap_allocpte(pmap, ptepindex);
1211 }
1212
1213 /************************************************************************
1214  *                      Managed pages in pmaps                          *
1215  ************************************************************************
1216  *
1217  * All pages entered into user pmaps and some pages entered into the kernel
1218  * pmap are managed, meaning that pmap_protect() and other related management
1219  * functions work on these pages.
1220  */
1221
1222 /*
1223  * free the pv_entry back to the free list.  This function may be
1224  * called from an interrupt.
1225  */
1226 static __inline void
1227 free_pv_entry(pv_entry_t pv)
1228 {
1229         pv_entry_count--;
1230         zfree(&pvzone, pv);
1231 }
1232
1233 /*
1234  * get a new pv_entry, allocating a block from the system
1235  * when needed.  This function may be called from an interrupt.
1236  */
1237 static pv_entry_t
1238 get_pv_entry(void)
1239 {
1240         pv_entry_count++;
1241         if (pv_entry_high_water &&
1242                 (pv_entry_count > pv_entry_high_water) &&
1243                 (pmap_pagedaemon_waken == 0)) {
1244                 pmap_pagedaemon_waken = 1;
1245                 wakeup (&vm_pages_needed);
1246         }
1247         return zalloc(&pvzone);
1248 }
1249
1250 /*
1251  * This routine is very drastic, but can save the system
1252  * in a pinch.
1253  */
1254 void
1255 pmap_collect(void)
1256 {
1257         int i;
1258         vm_page_t m;
1259         static int warningdone=0;
1260
1261         if (pmap_pagedaemon_waken == 0)
1262                 return;
1263
1264         if (warningdone < 5) {
1265                 kprintf("pmap_collect: collecting pv entries -- suggest increasing PMAP_SHPGPERPROC\n");
1266                 warningdone++;
1267         }
1268
1269         for(i = 0; i < vm_page_array_size; i++) {
1270                 m = &vm_page_array[i];
1271                 if (m->wire_count || m->hold_count || m->busy ||
1272                     (m->flags & PG_BUSY))
1273                         continue;
1274                 pmap_remove_all(m);
1275         }
1276         pmap_pagedaemon_waken = 0;
1277 }
1278         
1279 /*
1280  * If it is the first entry on the list, it is actually
1281  * in the header and we must copy the following entry up
1282  * to the header.  Otherwise we must search the list for
1283  * the entry.  In either case we free the now unused entry.
1284  */
1285 static int
1286 pmap_remove_entry(struct pmap *pmap, vm_page_t m, 
1287                   vm_offset_t va, pmap_inval_info_t info)
1288 {
1289         pv_entry_t pv;
1290         int rtval;
1291
1292         crit_enter();
1293         if (m->md.pv_list_count < pmap->pm_stats.resident_count) {
1294                 TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
1295                         if (pmap == pv->pv_pmap && va == pv->pv_va) 
1296                                 break;
1297                 }
1298         } else {
1299                 TAILQ_FOREACH(pv, &pmap->pm_pvlist, pv_plist) {
1300                         if (va == pv->pv_va) 
1301                                 break;
1302                 }
1303         }
1304
1305         /*
1306          * Note that pv_ptem is NULL if the page table page itself is not
1307          * managed, even if the page being removed IS managed.
1308          */
1309         rtval = 0;
1310         if (pv) {
1311                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1312                 m->md.pv_list_count--;
1313                 if (TAILQ_FIRST(&m->md.pv_list) == NULL)
1314                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1315                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
1316                 ++pmap->pm_generation;
1317                 rtval = pmap_unuse_pt(pmap, va, pv->pv_ptem, info);
1318                 free_pv_entry(pv);
1319         }
1320         crit_exit();
1321         return rtval;
1322 }
1323
1324 /*
1325  * Create a pv entry for page at pa for (pmap, va).  If the page table page
1326  * holding the VA is managed, mpte will be non-NULL.
1327  */
1328 static void
1329 pmap_insert_entry(pmap_t pmap, vm_offset_t va, vm_page_t mpte, vm_page_t m)
1330 {
1331         pv_entry_t pv;
1332
1333         crit_enter();
1334         pv = get_pv_entry();
1335         pv->pv_va = va;
1336         pv->pv_pmap = pmap;
1337         pv->pv_ptem = mpte;
1338
1339         TAILQ_INSERT_TAIL(&pmap->pm_pvlist, pv, pv_plist);
1340         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
1341         m->md.pv_list_count++;
1342
1343         crit_exit();
1344 }
1345
1346 /*
1347  * pmap_remove_pte: do the things to unmap a page in a process
1348  */
1349 static int
1350 pmap_remove_pte(struct pmap *pmap, vpte_t *ptq, vm_offset_t va,
1351         pmap_inval_info_t info)
1352 {
1353         vpte_t oldpte;
1354         vm_page_t m;
1355
1356         oldpte = loadandclear(ptq);
1357         pmap_inval_add(info, pmap, va); /* See NOTE: PMAP_INVAL_ADD */
1358         if (oldpte & VPTE_WIRED)
1359                 --pmap->pm_stats.wired_count;
1360         KKASSERT(pmap->pm_stats.wired_count >= 0);
1361
1362 #if 0
1363         /*
1364          * Machines that don't support invlpg, also don't support
1365          * VPTE_G.  XXX VPTE_G is disabled for SMP so don't worry about
1366          * the SMP case.
1367          */
1368         if (oldpte & VPTE_G)
1369                 madvise((void *)va, PAGE_SIZE, MADV_INVAL);
1370 #endif
1371         pmap->pm_stats.resident_count -= 1;
1372         if (oldpte & VPTE_MANAGED) {
1373                 m = PHYS_TO_VM_PAGE(oldpte);
1374                 if (oldpte & VPTE_M) {
1375 #if defined(PMAP_DIAGNOSTIC)
1376                         if (pmap_nw_modified((pt_entry_t) oldpte)) {
1377                                 kprintf(
1378         "pmap_remove: modified page not writable: va: 0x%x, pte: 0x%x\n",
1379                                     va, oldpte);
1380                         }
1381 #endif
1382                         if (pmap_track_modified(pmap, va))
1383                                 vm_page_dirty(m);
1384                 }
1385                 if (oldpte & VPTE_A)
1386                         vm_page_flag_set(m, PG_REFERENCED);
1387                 return pmap_remove_entry(pmap, m, va, info);
1388         } else {
1389                 return pmap_unuse_pt(pmap, va, NULL, info);
1390         }
1391
1392         return 0;
1393 }
1394
1395 /*
1396  * pmap_remove_page:
1397  *
1398  *      Remove a single page from a process address space.
1399  *
1400  *      This function may not be called from an interrupt if the pmap is
1401  *      not kernel_pmap.
1402  */
1403 static void
1404 pmap_remove_page(struct pmap *pmap, vm_offset_t va, pmap_inval_info_t info)
1405 {
1406         vpte_t *ptq;
1407
1408         /*
1409          * if there is no pte for this address, just skip it!!!  Otherwise
1410          * get a local va for mappings for this pmap and remove the entry.
1411          */
1412         if (*pmap_pde(pmap, va) != 0) {
1413                 ptq = get_ptbase(pmap, va);
1414                 if (*ptq) {
1415                         pmap_remove_pte(pmap, ptq, va, info);
1416                 }
1417         }
1418 }
1419
1420 /*
1421  * pmap_remove:
1422  *
1423  *      Remove the given range of addresses from the specified map.
1424  *
1425  *      It is assumed that the start and end are properly
1426  *      rounded to the page size.
1427  *
1428  *      This function may not be called from an interrupt if the pmap is
1429  *      not kernel_pmap.
1430  */
1431 void
1432 pmap_remove(struct pmap *pmap, vm_offset_t sva, vm_offset_t eva)
1433 {
1434         vpte_t *ptbase;
1435         vm_offset_t pdnxt;
1436         vm_offset_t ptpaddr;
1437         vm_pindex_t sindex, eindex;
1438         struct pmap_inval_info info;
1439
1440         if (pmap == NULL)
1441                 return;
1442
1443         KKASSERT(pmap->pm_stats.resident_count >= 0);
1444         if (pmap->pm_stats.resident_count == 0)
1445                 return;
1446
1447         pmap_inval_init(&info);
1448
1449         /*
1450          * special handling of removing one page.  a very
1451          * common operation and easy to short circuit some
1452          * code.
1453          */
1454         if (((sva + PAGE_SIZE) == eva) && 
1455                 ((pmap->pm_pdir[(sva >> PDRSHIFT)] & VPTE_PS) == 0)) {
1456                 pmap_remove_page(pmap, sva, &info);
1457                 pmap_inval_flush(&info);
1458                 return;
1459         }
1460
1461         /*
1462          * Get a local virtual address for the mappings that are being
1463          * worked with.
1464          *
1465          * XXX this is really messy because the kernel pmap is not relative
1466          * to address 0
1467          */
1468         sindex = (sva >> PAGE_SHIFT);
1469         eindex = (eva >> PAGE_SHIFT);
1470
1471         for (; sindex < eindex; sindex = pdnxt) {
1472                 vpte_t pdirindex;
1473
1474                 /*
1475                  * Calculate index for next page table.
1476                  */
1477                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1478                 if (pmap->pm_stats.resident_count == 0)
1479                         break;
1480
1481                 pdirindex = sindex / NPDEPG;
1482                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1483                         pmap->pm_pdir[pdirindex] = 0;
1484                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1485                         inval_ptbase_pagedir(pmap, pdirindex);
1486                         continue;
1487                 }
1488
1489                 /*
1490                  * Weed out invalid mappings. Note: we assume that the page
1491                  * directory table is always allocated, and in kernel virtual.
1492                  */
1493                 if (ptpaddr == 0)
1494                         continue;
1495
1496                 /*
1497                  * Limit our scan to either the end of the va represented
1498                  * by the current page table page, or to the end of the
1499                  * range being removed.
1500                  */
1501                 if (pdnxt > eindex)
1502                         pdnxt = eindex;
1503
1504                 /*
1505                  * NOTE: pmap_remove_pte() can block.
1506                  */
1507                 for (; sindex != pdnxt; sindex++) {
1508                         vm_offset_t va;
1509
1510                         ptbase = get_ptbase(pmap, sindex << PAGE_SHIFT);
1511                         if (*ptbase == 0)
1512                                 continue;
1513                         va = i386_ptob(sindex);
1514                         if (pmap_remove_pte(pmap, ptbase, va, &info))
1515                                 break;
1516                 }
1517         }
1518         pmap_inval_flush(&info);
1519 }
1520
1521 /*
1522  * pmap_remove_all:
1523  *
1524  * Removes this physical page from all physical maps in which it resides.
1525  * Reflects back modify bits to the pager.
1526  *
1527  * This routine may not be called from an interrupt.
1528  */
1529 static void
1530 pmap_remove_all(vm_page_t m)
1531 {
1532         struct pmap_inval_info info;
1533         vpte_t *pte, tpte;
1534         pv_entry_t pv;
1535
1536 #if defined(PMAP_DIAGNOSTIC)
1537         /*
1538          * XXX this makes pmap_page_protect(NONE) illegal for non-managed
1539          * pages!
1540          */
1541         if (!pmap_initialized || (m->flags & PG_FICTITIOUS)) {
1542                 panic("pmap_page_protect: illegal for unmanaged page, va: 0x%08llx", (long long)VM_PAGE_TO_PHYS(m));
1543         }
1544 #endif
1545
1546         pmap_inval_init(&info);
1547         crit_enter();
1548         while ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
1549                 pv->pv_pmap->pm_stats.resident_count--;
1550
1551                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
1552                 KKASSERT(pte != NULL);
1553
1554                 tpte = loadandclear(pte);
1555                 /* See NOTE: PMAP_INVAL_ADD */
1556                 pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
1557                 if (tpte & VPTE_WIRED)
1558                         --pv->pv_pmap->pm_stats.wired_count;
1559                 KKASSERT(pv->pv_pmap->pm_stats.wired_count >= 0);
1560
1561                 if (tpte & VPTE_A)
1562                         vm_page_flag_set(m, PG_REFERENCED);
1563
1564                 /*
1565                  * Update the vm_page_t clean and reference bits.
1566                  */
1567                 if (tpte & VPTE_M) {
1568 #if defined(PMAP_DIAGNOSTIC)
1569                         if (pmap_nw_modified((pt_entry_t) tpte)) {
1570                                 kprintf(
1571         "pmap_remove_all: modified page not writable: va: 0x%x, pte: 0x%x\n",
1572                                     pv->pv_va, tpte);
1573                         }
1574 #endif
1575                         if (pmap_track_modified(pv->pv_pmap, pv->pv_va))
1576                                 vm_page_dirty(m);
1577                 }
1578                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
1579                 TAILQ_REMOVE(&pv->pv_pmap->pm_pvlist, pv, pv_plist);
1580                 ++pv->pv_pmap->pm_generation;
1581                 m->md.pv_list_count--;
1582                 pmap_unuse_pt(pv->pv_pmap, pv->pv_va, pv->pv_ptem, &info);
1583                 free_pv_entry(pv);
1584         }
1585
1586         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
1587         crit_exit();
1588         pmap_inval_flush(&info);
1589 }
1590
1591 /*
1592  * pmap_protect:
1593  *
1594  *      Set the physical protection on the specified range of this map
1595  *      as requested.
1596  *
1597  *      This function may not be called from an interrupt if the map is
1598  *      not the kernel_pmap.
1599  */
1600 void
1601 pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
1602 {
1603         vpte_t *ptbase;
1604         vm_offset_t pdnxt, ptpaddr;
1605         vm_pindex_t sindex, eindex;
1606         vm_pindex_t sbase;
1607         pmap_inval_info info;
1608
1609         if (pmap == NULL)
1610                 return;
1611
1612         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1613                 pmap_remove(pmap, sva, eva);
1614                 return;
1615         }
1616
1617         if (prot & VM_PROT_WRITE)
1618                 return;
1619
1620         pmap_inval_init(&info);
1621
1622         ptbase = get_ptbase(pmap, sva);
1623
1624         sindex = (sva >> PAGE_SHIFT);
1625         eindex = (eva >> PAGE_SHIFT);
1626         sbase = sindex;
1627
1628         for (; sindex < eindex; sindex = pdnxt) {
1629
1630                 unsigned pdirindex;
1631
1632                 pdnxt = ((sindex + NPTEPG) & ~(NPTEPG - 1));
1633
1634                 pdirindex = sindex / NPDEPG;
1635                 if (((ptpaddr = pmap->pm_pdir[pdirindex]) & VPTE_PS) != 0) {
1636                         pmap->pm_pdir[pdirindex] &= ~(VPTE_M|VPTE_W);
1637                         pmap->pm_stats.resident_count -= NBPDR / PAGE_SIZE;
1638                         inval_ptbase_pagedir(pmap, pdirindex);
1639                         continue;
1640                 }
1641
1642                 /*
1643                  * Weed out invalid mappings. Note: we assume that the page
1644                  * directory table is always allocated, and in kernel virtual.
1645                  */
1646                 if (ptpaddr == 0)
1647                         continue;
1648
1649                 if (pdnxt > eindex) {
1650                         pdnxt = eindex;
1651                 }
1652
1653                 for (; sindex != pdnxt; sindex++) {
1654                         vpte_t pbits;
1655                         vm_page_t m;
1656
1657                         pbits = ptbase[sindex - sbase];
1658
1659                         if (pbits & VPTE_MANAGED) {
1660                                 m = NULL;
1661                                 if (pbits & VPTE_A) {
1662                                         m = PHYS_TO_VM_PAGE(pbits);
1663                                         vm_page_flag_set(m, PG_REFERENCED);
1664                                         pbits &= ~VPTE_A;
1665                                 }
1666                                 if (pbits & VPTE_M) {
1667                                         if (pmap_track_modified(pmap, i386_ptob(sindex))) {
1668                                                 if (m == NULL)
1669                                                         m = PHYS_TO_VM_PAGE(pbits);
1670                                                 vm_page_dirty(m);
1671                                                 pbits &= ~VPTE_M;
1672                                         }
1673                                 }
1674                         }
1675
1676                         pbits &= ~VPTE_W;
1677
1678                         if (pbits != ptbase[sindex - sbase]) {
1679                                 ptbase[sindex - sbase] = pbits;
1680                                 /* See NOTE: PMAP_INVAL_ADD */
1681                                 pmap_inval_add(&info, pmap, i386_ptob(sindex));
1682                         }
1683                 }
1684         }
1685         pmap_inval_flush(&info);
1686 }
1687
1688 /*
1689  * Enter a managed page into a pmap.  If the page is not wired related pmap
1690  * data can be destroyed at any time for later demand-operation.
1691  *
1692  * Insert the vm_page (m) at virtual address (v) in (pmap), with the
1693  * specified protection, and wire the mapping if requested.
1694  *
1695  * NOTE: This routine may not lazy-evaluate or lose information.  The
1696  * page must actually be inserted into the given map NOW.
1697  *
1698  * NOTE: When entering a page at a KVA address, the pmap must be the
1699  * kernel_pmap.
1700  */
1701 void
1702 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1703            boolean_t wired)
1704 {
1705         vm_paddr_t pa;
1706         vpte_t *pte;
1707         vm_paddr_t opa;
1708         vm_offset_t origpte, newpte;
1709         vm_page_t mpte;
1710         pmap_inval_info info;
1711
1712         if (pmap == NULL)
1713                 return;
1714
1715         va &= VPTE_FRAME;
1716
1717         /*
1718          * Get the page table page.   The kernel_pmap's page table pages
1719          * are preallocated and have no associated vm_page_t.
1720          */
1721         if (pmap == &kernel_pmap)
1722                 mpte = NULL;
1723         else
1724                 mpte = pmap_allocpte(pmap, va);
1725
1726         pmap_inval_init(&info);
1727         pte = pmap_pte(pmap, va);
1728
1729         /*
1730          * Page Directory table entry not valid, we need a new PT page
1731          * and pmap_allocpte() didn't give us one.  Oops!
1732          */
1733         if (pte == NULL) {
1734                 panic("pmap_enter: invalid page directory pmap=%p, va=0x%p\n",
1735                       pmap, (void *)va);
1736         }
1737
1738         pa = VM_PAGE_TO_PHYS(m) & VPTE_FRAME;
1739         origpte = *pte;
1740         opa = origpte & VPTE_FRAME;
1741 #if 0
1742         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);
1743 #endif
1744
1745         if (origpte & VPTE_PS)
1746                 panic("pmap_enter: attempted pmap_enter on 4MB page");
1747
1748         /*
1749          * Mapping has not changed, must be protection or wiring change.
1750          */
1751         if (origpte && (opa == pa)) {
1752                 /*
1753                  * Wiring change, just update stats. We don't worry about
1754                  * wiring PT pages as they remain resident as long as there
1755                  * are valid mappings in them. Hence, if a user page is wired,
1756                  * the PT page will be also.
1757                  */
1758                 if (wired && ((origpte & VPTE_WIRED) == 0))
1759                         ++pmap->pm_stats.wired_count;
1760                 else if (!wired && (origpte & VPTE_WIRED))
1761                         --pmap->pm_stats.wired_count;
1762                 KKASSERT(pmap->pm_stats.wired_count >= 0);
1763
1764 #if defined(PMAP_DIAGNOSTIC)
1765                 if (pmap_nw_modified((pt_entry_t) origpte)) {
1766                         kprintf(
1767         "pmap_enter: modified page not writable: va: 0x%x, pte: 0x%x\n",
1768                             va, origpte);
1769                 }
1770 #endif
1771
1772                 /*
1773                  * Remove the extra pte reference.  Note that we cannot
1774                  * optimize the RO->RW case because we have adjusted the
1775                  * wiring count above and may need to adjust the wiring
1776                  * bits below.
1777                  */
1778                 if (mpte)
1779                         mpte->hold_count--;
1780
1781                 /*
1782                  * We might be turning off write access to the page,
1783                  * so we go ahead and sense modify status.
1784                  */
1785                 if (origpte & VPTE_MANAGED) {
1786                         if ((origpte & VPTE_M) && pmap_track_modified(pmap, va)) {
1787                                 vm_page_t om;
1788                                 om = PHYS_TO_VM_PAGE(opa);
1789                                 vm_page_dirty(om);
1790                         }
1791                         pa |= VPTE_MANAGED;
1792                 }
1793                 goto validate;
1794         } 
1795         /*
1796          * Mapping has changed, invalidate old range and fall through to
1797          * handle validating new mapping.
1798          */
1799         if (opa) {
1800                 int err;
1801                 err = pmap_remove_pte(pmap, pte, va, &info);
1802                 if (err)
1803                         panic("pmap_enter: pte vanished, va: 0x%x", va);
1804         }
1805
1806         /*
1807          * Enter on the PV list if part of our managed memory. Note that we
1808          * raise IPL while manipulating pv_table since pmap_enter can be
1809          * called at interrupt time.
1810          */
1811         if (pmap_initialized && 
1812             (m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0) {
1813                 pmap_insert_entry(pmap, va, mpte, m);
1814                 pa |= VPTE_MANAGED;
1815         }
1816
1817         /*
1818          * Increment counters
1819          */
1820         pmap->pm_stats.resident_count++;
1821         if (wired)
1822                 pmap->pm_stats.wired_count++;
1823
1824 validate:
1825         /*
1826          * Now validate mapping with desired protection/wiring.
1827          */
1828         newpte = (vm_offset_t) (pa | pte_prot(pmap, prot) | VPTE_V);
1829
1830         if (wired)
1831                 newpte |= VPTE_WIRED;
1832         newpte |= VPTE_U;
1833
1834         /*
1835          * if the mapping or permission bits are different, we need
1836          * to update the pte.
1837          */
1838         if ((origpte & ~(VPTE_M|VPTE_A)) != newpte) {
1839                 *pte = newpte | VPTE_A;
1840                 /* See NOTE: PMAP_INVAL_ADD */
1841                 pmap_inval_add(&info, pmap, va); /* XXX non-optimal */
1842         }
1843         pmap_inval_flush(&info);
1844 }
1845
1846 /*
1847  * This is a quick version of pmap_enter().  It is used only under the 
1848  * following conditions:
1849  *
1850  * (1) The pmap is not the kernel_pmap
1851  * (2) The page is not to be wired into the map
1852  * (3) The page is to mapped read-only in the pmap (initially that is)
1853  * (4) The calling procedure is responsible for flushing the TLB
1854  * (5) The page is always managed
1855  * (6) There is no prior mapping at the VA
1856  */
1857
1858 static vm_page_t
1859 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_page_t mpte)
1860 {
1861         vpte_t *pte;
1862         vm_paddr_t pa;
1863         pmap_inval_info info;
1864         unsigned ptepindex;
1865         vm_offset_t ptepa;
1866
1867         KKASSERT(pmap != &kernel_pmap);
1868         pmap_inval_init(&info);
1869
1870         KKASSERT(va >= VM_MIN_USER_ADDRESS && va < VM_MAX_USER_ADDRESS);
1871
1872         /*
1873          * Instantiate the page table page if required
1874          */
1875
1876         /*
1877          * Calculate pagetable page index
1878          */
1879         ptepindex = va >> PDRSHIFT;
1880         if (mpte && (mpte->pindex == ptepindex)) {
1881                 mpte->hold_count++;
1882         } else {
1883 retry:
1884                 /*
1885                  * Get the page directory entry
1886                  */
1887                 ptepa = (vm_offset_t) pmap->pm_pdir[ptepindex];
1888
1889                 /*
1890                  * If the page table page is mapped, we just increment
1891                  * the hold count, and activate it.
1892                  */
1893                 if (ptepa) {
1894                         if (ptepa & VPTE_PS)
1895                                 panic("pmap_enter_quick: unexpected mapping into 4MB page");
1896                         if (pmap->pm_ptphint &&
1897                                 (pmap->pm_ptphint->pindex == ptepindex)) {
1898                                 mpte = pmap->pm_ptphint;
1899                         } else {
1900                                 mpte = pmap_page_lookup( pmap->pm_pteobj, ptepindex);
1901                                 pmap->pm_ptphint = mpte;
1902                         }
1903                         if (mpte == NULL)
1904                                 goto retry;
1905                         mpte->hold_count++;
1906                 } else {
1907                         mpte = _pmap_allocpte(pmap, ptepindex);
1908                 }
1909         }
1910
1911         /*
1912          * Ok, now that the page table page has been validated, get the pte.
1913          * If the pte is already mapped undo mpte's hold_count and
1914          * just return.
1915          */
1916         pte = pmap_pte(pmap, va);
1917         if (*pte) {
1918                 if (mpte)
1919                         pmap_unwire_pte_hold(pmap, mpte, &info);
1920                 return 0;
1921         }
1922
1923         /*
1924          * Enter on the PV list if part of our managed memory. Note that we
1925          * raise IPL while manipulating pv_table since pmap_enter can be
1926          * called at interrupt time.
1927          */
1928         if ((m->flags & (PG_FICTITIOUS|PG_UNMANAGED)) == 0)
1929                 pmap_insert_entry(pmap, va, mpte, m);
1930
1931         /*
1932          * Increment counters
1933          */
1934         pmap->pm_stats.resident_count++;
1935
1936         pa = VM_PAGE_TO_PHYS(m);
1937
1938         /*
1939          * Now validate mapping with RO protection
1940          */
1941         if (m->flags & (PG_FICTITIOUS|PG_UNMANAGED))
1942                 *pte = pa | VPTE_V | VPTE_U;
1943         else
1944                 *pte = pa | VPTE_V | VPTE_U | VPTE_MANAGED;
1945
1946         return mpte;
1947 }
1948
1949 /*
1950  * Extract the physical address for the translation at the specified
1951  * virtual address in the pmap.
1952  */
1953 vm_paddr_t
1954 pmap_extract(pmap_t pmap, vm_offset_t va)
1955 {
1956         vm_paddr_t rtval;
1957         vpte_t pte;
1958
1959         if (pmap && (pte = pmap->pm_pdir[va >> SEG_SHIFT]) != 0) {
1960                 if (pte & VPTE_PS) {
1961                         rtval = pte & ~((vpte_t)(1 << SEG_SHIFT) - 1);
1962                         rtval |= va & SEG_MASK;
1963                 } else {
1964                         pte = *get_ptbase(pmap, va);
1965                         rtval = (pte & VPTE_FRAME) | (va & PAGE_MASK);
1966                 }
1967                 return(rtval);
1968         }
1969         return(0);
1970 }
1971
1972 #define MAX_INIT_PT (96)
1973
1974 /*
1975  * This routine preloads the ptes for a given object into the specified pmap.
1976  * This eliminates the blast of soft faults on process startup and
1977  * immediately after an mmap.
1978  */
1979 static int pmap_object_init_pt_callback(vm_page_t p, void *data);
1980
1981 void
1982 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_prot_t prot,
1983                     vm_object_t object, vm_pindex_t pindex, 
1984                     vm_size_t size, int limit)
1985 {
1986         struct rb_vm_page_scan_info info;
1987         int psize;
1988
1989         /*
1990          * We can't preinit if read access isn't set or there is no pmap
1991          * or object.
1992          */
1993         if ((prot & VM_PROT_READ) == 0 || pmap == NULL || object == NULL)
1994                 return;
1995
1996         /*
1997          * We can't preinit if the pmap is not the current pmap
1998          */
1999         if (curproc == NULL || pmap != vmspace_pmap(curproc->p_vmspace))
2000                 return;
2001
2002         psize = size >> PAGE_SHIFT;
2003
2004         if ((object->type != OBJT_VNODE) ||
2005                 ((limit & MAP_PREFAULT_PARTIAL) && (psize > MAX_INIT_PT) &&
2006                         (object->resident_page_count > MAX_INIT_PT))) {
2007                 return;
2008         }
2009
2010         if (psize + pindex > object->size) {
2011                 if (object->size < pindex)
2012                         return;           
2013                 psize = object->size - pindex;
2014         }
2015
2016         if (psize == 0)
2017                 return;
2018
2019         /*
2020          * Use a red-black scan to traverse the requested range and load
2021          * any valid pages found into the pmap.
2022          *
2023          * We cannot safely scan the object's memq unless we are in a
2024          * critical section since interrupts can remove pages from objects.
2025          */
2026         info.start_pindex = pindex;
2027         info.end_pindex = pindex + psize - 1;
2028         info.limit = limit;
2029         info.mpte = NULL;
2030         info.addr = addr;
2031         info.pmap = pmap;
2032
2033         crit_enter();
2034         vm_page_rb_tree_RB_SCAN(&object->rb_memq, rb_vm_page_scancmp,
2035                                 pmap_object_init_pt_callback, &info);
2036         crit_exit();
2037 }
2038
2039 static
2040 int
2041 pmap_object_init_pt_callback(vm_page_t p, void *data)
2042 {
2043         struct rb_vm_page_scan_info *info = data;
2044         vm_pindex_t rel_index;
2045         /*
2046          * don't allow an madvise to blow away our really
2047          * free pages allocating pv entries.
2048          */
2049         if ((info->limit & MAP_PREFAULT_MADVISE) &&
2050                 vmstats.v_free_count < vmstats.v_free_reserved) {
2051                     return(-1);
2052         }
2053         if (((p->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2054             (p->busy == 0) && (p->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2055                 if ((p->queue - p->pc) == PQ_CACHE)
2056                         vm_page_deactivate(p);
2057                 vm_page_busy(p);
2058                 rel_index = p->pindex - info->start_pindex;
2059                 info->mpte = pmap_enter_quick(info->pmap,
2060                                               info->addr + i386_ptob(rel_index),
2061                                               p, info->mpte);
2062                 vm_page_flag_set(p, PG_MAPPED);
2063                 vm_page_wakeup(p);
2064         }
2065         return(0);
2066 }
2067
2068 /*
2069  * pmap_prefault provides a quick way of clustering pagefaults into a
2070  * processes address space.  It is a "cousin" of pmap_object_init_pt, 
2071  * except it runs at page fault time instead of mmap time.
2072  */
2073 #define PFBAK 4
2074 #define PFFOR 4
2075 #define PAGEORDER_SIZE (PFBAK+PFFOR)
2076
2077 static int pmap_prefault_pageorder[] = {
2078         -PAGE_SIZE, PAGE_SIZE,
2079         -2 * PAGE_SIZE, 2 * PAGE_SIZE,
2080         -3 * PAGE_SIZE, 3 * PAGE_SIZE,
2081         -4 * PAGE_SIZE, 4 * PAGE_SIZE
2082 };
2083
2084 void
2085 pmap_prefault(pmap_t pmap, vm_offset_t addra, vm_map_entry_t entry)
2086 {
2087         int i;
2088         vm_offset_t starta;
2089         vm_offset_t addr;
2090         vm_pindex_t pindex;
2091         vm_page_t m, mpte;
2092         vm_object_t object;
2093
2094         /*
2095          * We do not currently prefault mappings that use virtual page
2096          * tables.  We do not prefault foreign pmaps.
2097          */
2098         if (entry->maptype == VM_MAPTYPE_VPAGETABLE)
2099                 return;
2100         if (curproc == NULL || (pmap != vmspace_pmap(curproc->p_vmspace)))
2101                 return;
2102
2103         object = entry->object.vm_object;
2104
2105         starta = addra - PFBAK * PAGE_SIZE;
2106         if (starta < entry->start)
2107                 starta = entry->start;
2108         else if (starta > addra)
2109                 starta = 0;
2110
2111         /*
2112          * critical section protection is required to maintain the 
2113          * page/object association, interrupts can free pages and remove 
2114          * them from their objects.
2115          */
2116         mpte = NULL;
2117         crit_enter();
2118         for (i = 0; i < PAGEORDER_SIZE; i++) {
2119                 vm_object_t lobject;
2120                 vpte_t *pte;
2121
2122                 addr = addra + pmap_prefault_pageorder[i];
2123                 if (addr > addra + (PFFOR * PAGE_SIZE))
2124                         addr = 0;
2125
2126                 if (addr < starta || addr >= entry->end)
2127                         continue;
2128
2129                 /*
2130                  * Make sure the page table page already exists
2131                  */
2132                 if ((*pmap_pde(pmap, addr)) == NULL) 
2133                         continue;
2134
2135                 /*
2136                  * Get a pointer to the pte and make sure that no valid page
2137                  * has been mapped.
2138                  */
2139                 pte = get_ptbase(pmap, addr);
2140                 if (*pte)
2141                         continue;
2142
2143                 /*
2144                  * Get the page to be mapped
2145                  */
2146                 pindex = ((addr - entry->start) + entry->offset) >> PAGE_SHIFT;
2147                 lobject = object;
2148
2149                 for (m = vm_page_lookup(lobject, pindex);
2150                     (!m && (lobject->type == OBJT_DEFAULT) &&
2151                      (lobject->backing_object));
2152                     lobject = lobject->backing_object
2153                 ) {
2154                         if (lobject->backing_object_offset & PAGE_MASK)
2155                                 break;
2156                         pindex += (lobject->backing_object_offset >> PAGE_SHIFT);
2157                         m = vm_page_lookup(lobject->backing_object, pindex);
2158                 }
2159
2160                 /*
2161                  * give-up when a page is not in memory
2162                  */
2163                 if (m == NULL)
2164                         break;
2165
2166                 /*
2167                  * If everything meets the requirements for pmap_enter_quick(),
2168                  * then enter the page.
2169                  */
2170
2171                 if (((m->valid & VM_PAGE_BITS_ALL) == VM_PAGE_BITS_ALL) &&
2172                         (m->busy == 0) &&
2173                     (m->flags & (PG_BUSY | PG_FICTITIOUS)) == 0) {
2174
2175                         if ((m->queue - m->pc) == PQ_CACHE) {
2176                                 vm_page_deactivate(m);
2177                         }
2178                         vm_page_busy(m);
2179                         mpte = pmap_enter_quick(pmap, addr, m, mpte);
2180                         vm_page_flag_set(m, PG_MAPPED);
2181                         vm_page_wakeup(m);
2182                 }
2183         }
2184         crit_exit();
2185 }
2186
2187 /*
2188  *      Routine:        pmap_change_wiring
2189  *      Function:       Change the wiring attribute for a map/virtual-address
2190  *                      pair.
2191  *      In/out conditions:
2192  *                      The mapping must already exist in the pmap.
2193  */
2194 void
2195 pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
2196 {
2197         vpte_t *pte;
2198
2199         if (pmap == NULL)
2200                 return;
2201
2202         pte = get_ptbase(pmap, va);
2203
2204         if (wired && (*pte & VPTE_WIRED) == 0)
2205                 ++pmap->pm_stats.wired_count;
2206         else if (!wired && (*pte & VPTE_WIRED))
2207                 --pmap->pm_stats.wired_count;
2208         KKASSERT(pmap->pm_stats.wired_count >= 0);
2209
2210         /*
2211          * Wiring is not a hardware characteristic so there is no need to
2212          * invalidate TLB.  However, in an SMP environment we must use
2213          * a locked bus cycle to update the pte (if we are not using 
2214          * the pmap_inval_*() API that is)... it's ok to do this for simple
2215          * wiring changes.
2216          */
2217         if (wired)
2218                 atomic_set_int(pte, VPTE_WIRED);
2219         else
2220                 atomic_clear_int(pte, VPTE_WIRED);
2221 }
2222
2223 /*
2224  *      Copy the range specified by src_addr/len
2225  *      from the source map to the range dst_addr/len
2226  *      in the destination map.
2227  *
2228  *      This routine is only advisory and need not do anything.
2229  */
2230 void
2231 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, 
2232         vm_size_t len, vm_offset_t src_addr)
2233 {
2234         pmap_inval_info info;
2235         vm_offset_t addr;
2236         vm_offset_t end_addr = src_addr + len;
2237         vm_offset_t pdnxt;
2238         vpte_t *src_frame;
2239         vpte_t *dst_frame;
2240         vm_page_t m;
2241
2242         if (dst_addr != src_addr)
2243                 return;
2244         if (dst_pmap->pm_pdir == NULL)
2245                 return;
2246         if (src_pmap->pm_pdir == NULL)
2247                 return;
2248
2249         src_frame = get_ptbase1(src_pmap, src_addr);
2250         dst_frame = get_ptbase2(dst_pmap, src_addr);
2251
2252         pmap_inval_init(&info);
2253 #if 0
2254         /* XXX */
2255         pmap_inval_add(&info, dst_pmap, -1);
2256         pmap_inval_add(&info, src_pmap, -1);
2257 #endif
2258
2259         /*
2260          * critical section protection is required to maintain the page/object
2261          * association, interrupts can free pages and remove them from 
2262          * their objects.
2263          */
2264         crit_enter();
2265         for (addr = src_addr; addr < end_addr; addr = pdnxt) {
2266                 vpte_t *src_pte, *dst_pte;
2267                 vm_page_t dstmpte, srcmpte;
2268                 vm_offset_t srcptepaddr;
2269                 unsigned ptepindex;
2270
2271                 if (addr >= VM_MAX_USER_ADDRESS)
2272                         panic("pmap_copy: invalid to pmap_copy page tables\n");
2273
2274                 /*
2275                  * Don't let optional prefaulting of pages make us go
2276                  * way below the low water mark of free pages or way
2277                  * above high water mark of used pv entries.
2278                  */
2279                 if (vmstats.v_free_count < vmstats.v_free_reserved ||
2280                     pv_entry_count > pv_entry_high_water)
2281                         break;
2282                 
2283                 pdnxt = ((addr + PAGE_SIZE*NPTEPG) & ~(PAGE_SIZE*NPTEPG - 1));
2284                 ptepindex = addr >> PDRSHIFT;
2285
2286                 srcptepaddr = (vm_offset_t) src_pmap->pm_pdir[ptepindex];
2287                 if (srcptepaddr == 0)
2288                         continue;
2289                         
2290                 if (srcptepaddr & VPTE_PS) {
2291                         if (dst_pmap->pm_pdir[ptepindex] == 0) {
2292                                 dst_pmap->pm_pdir[ptepindex] = (pd_entry_t) srcptepaddr;
2293                                 dst_pmap->pm_stats.resident_count += NBPDR / PAGE_SIZE;
2294                         }
2295                         continue;
2296                 }
2297
2298                 srcmpte = vm_page_lookup(src_pmap->pm_pteobj, ptepindex);
2299                 if ((srcmpte == NULL) ||
2300                         (srcmpte->hold_count == 0) || (srcmpte->flags & PG_BUSY))
2301                         continue;
2302
2303                 if (pdnxt > end_addr)
2304                         pdnxt = end_addr;
2305
2306                 src_pte = src_frame + ((addr - src_addr) >> PAGE_SHIFT);
2307                 dst_pte = dst_frame + ((addr - src_addr) >> PAGE_SHIFT);
2308                 while (addr < pdnxt) {
2309                         vpte_t ptetemp;
2310                         ptetemp = *src_pte;
2311                         /*
2312                          * we only virtual copy managed pages
2313                          */
2314                         if ((ptetemp & VPTE_MANAGED) != 0) {
2315                                 /*
2316                                  * We have to check after allocpte for the
2317                                  * pte still being around...  allocpte can
2318                                  * block.
2319                                  */
2320                                 dstmpte = pmap_allocpte(dst_pmap, addr);
2321                                 if ((*dst_pte == 0) && (ptetemp = *src_pte)) {
2322                                         /*
2323                                          * Clear the modified and accessed
2324                                          * (referenced) bits during the copy.
2325                                          *
2326                                          * We do not have to clear the write
2327                                          * bit to force a fault-on-modify
2328                                          * because the real kernel's target
2329                                          * pmap is empty and will fault anyway.
2330                                          */
2331                                         m = PHYS_TO_VM_PAGE(ptetemp);
2332                                         *dst_pte = ptetemp & ~(VPTE_M | VPTE_A);
2333                                         dst_pmap->pm_stats.resident_count++;
2334                                         pmap_insert_entry(dst_pmap, addr,
2335                                                 dstmpte, m);
2336                                 } else {
2337                                         pmap_unwire_pte_hold(dst_pmap, dstmpte, &info);
2338                                 }
2339                                 if (dstmpte->hold_count >= srcmpte->hold_count)
2340                                         break;
2341                         }
2342                         addr += PAGE_SIZE;
2343                         src_pte++;
2344                         dst_pte++;
2345                 }
2346         }
2347         crit_exit();
2348         pmap_inval_flush(&info);
2349 }       
2350
2351 /*
2352  * pmap_zero_page:
2353  *
2354  *      Zero the specified PA by mapping the page into KVM and clearing its
2355  *      contents.
2356  *
2357  *      This function may be called from an interrupt and no locking is
2358  *      required.
2359  */
2360 void
2361 pmap_zero_page(vm_paddr_t phys)
2362 {
2363         struct mdglobaldata *gd = mdcpu;
2364
2365         crit_enter();
2366         if (*gd->gd_CMAP3)
2367                 panic("pmap_zero_page: CMAP3 busy");
2368         *gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W | (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2369         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2370
2371         bzero(gd->gd_CADDR3, PAGE_SIZE);
2372         *gd->gd_CMAP3 = 0;
2373         crit_exit();
2374 }
2375
2376 /*
2377  * pmap_page_assertzero:
2378  *
2379  *      Assert that a page is empty, panic if it isn't.
2380  */
2381 void
2382 pmap_page_assertzero(vm_paddr_t phys)
2383 {
2384         struct mdglobaldata *gd = mdcpu;
2385         int i;
2386
2387         crit_enter();
2388         if (*gd->gd_CMAP3)
2389                 panic("pmap_zero_page: CMAP3 busy");
2390         *gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W |
2391                         (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2392         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2393         for (i = 0; i < PAGE_SIZE; i += 4) {
2394             if (*(int *)((char *)gd->gd_CADDR3 + i) != 0) {
2395                 panic("pmap_page_assertzero() @ %p not zero!\n",
2396                     (void *)gd->gd_CADDR3);
2397             }
2398         }
2399         *gd->gd_CMAP3 = 0;
2400         crit_exit();
2401 }
2402
2403 /*
2404  * pmap_zero_page:
2405  *
2406  *      Zero part of a physical page by mapping it into memory and clearing
2407  *      its contents with bzero.
2408  *
2409  *      off and size may not cover an area beyond a single hardware page.
2410  */
2411 void
2412 pmap_zero_page_area(vm_paddr_t phys, int off, int size)
2413 {
2414         struct mdglobaldata *gd = mdcpu;
2415
2416         crit_enter();
2417         if (*gd->gd_CMAP3)
2418                 panic("pmap_zero_page: CMAP3 busy");
2419         *gd->gd_CMAP3 = VPTE_V | VPTE_R | VPTE_W |
2420                         (phys & VPTE_FRAME) | VPTE_A | VPTE_M;
2421         madvise(gd->gd_CADDR3, PAGE_SIZE, MADV_INVAL);
2422
2423         bzero((char *)gd->gd_CADDR3 + off, size);
2424         *gd->gd_CMAP3 = 0;
2425         crit_exit();
2426 }
2427
2428 /*
2429  * pmap_copy_page:
2430  *
2431  *      Copy the physical page from the source PA to the target PA.
2432  *      This function may be called from an interrupt.  No locking
2433  *      is required.
2434  */
2435 void
2436 pmap_copy_page(vm_paddr_t src, vm_paddr_t dst)
2437 {
2438         struct mdglobaldata *gd = mdcpu;
2439
2440         crit_enter();
2441         if (*(int *) gd->gd_CMAP1)
2442                 panic("pmap_copy_page: CMAP1 busy");
2443         if (*(int *) gd->gd_CMAP2)
2444                 panic("pmap_copy_page: CMAP2 busy");
2445
2446         *(int *) gd->gd_CMAP1 = VPTE_V | VPTE_R | (src & PG_FRAME) | VPTE_A;
2447         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2448
2449         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2450         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2451
2452         bcopy(gd->gd_CADDR1, gd->gd_CADDR2, PAGE_SIZE);
2453
2454         *(int *) gd->gd_CMAP1 = 0;
2455         *(int *) gd->gd_CMAP2 = 0;
2456         crit_exit();
2457 }
2458
2459 /*
2460  * pmap_copy_page_frag:
2461  *
2462  *      Copy the physical page from the source PA to the target PA.
2463  *      This function may be called from an interrupt.  No locking
2464  *      is required.
2465  */
2466 void
2467 pmap_copy_page_frag(vm_paddr_t src, vm_paddr_t dst, size_t bytes)
2468 {
2469         struct mdglobaldata *gd = mdcpu;
2470
2471         crit_enter();
2472         if (*(int *) gd->gd_CMAP1)
2473                 panic("pmap_copy_page: CMAP1 busy");
2474         if (*(int *) gd->gd_CMAP2)
2475                 panic("pmap_copy_page: CMAP2 busy");
2476
2477         *(int *) gd->gd_CMAP1 = VPTE_V | (src & VPTE_FRAME) | VPTE_A;
2478         *(int *) gd->gd_CMAP2 = VPTE_V | VPTE_R | VPTE_W | (dst & VPTE_FRAME) | VPTE_A | VPTE_M;
2479
2480         madvise(gd->gd_CADDR1, PAGE_SIZE, MADV_INVAL);
2481         madvise(gd->gd_CADDR2, PAGE_SIZE, MADV_INVAL);
2482
2483         bcopy((char *)gd->gd_CADDR1 + (src & PAGE_MASK),
2484               (char *)gd->gd_CADDR2 + (dst & PAGE_MASK),
2485               bytes);
2486
2487         *(int *) gd->gd_CMAP1 = 0;
2488         *(int *) gd->gd_CMAP2 = 0;
2489         crit_exit();
2490 }
2491
2492 /*
2493  * Returns true if the pmap's pv is one of the first
2494  * 16 pvs linked to from this page.  This count may
2495  * be changed upwards or downwards in the future; it
2496  * is only necessary that true be returned for a small
2497  * subset of pmaps for proper page aging.
2498  */
2499 boolean_t
2500 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
2501 {
2502         pv_entry_t pv;
2503         int loops = 0;
2504
2505         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2506                 return FALSE;
2507
2508         crit_enter();
2509
2510         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2511                 if (pv->pv_pmap == pmap) {
2512                         crit_exit();
2513                         return TRUE;
2514                 }
2515                 loops++;
2516                 if (loops >= 16)
2517                         break;
2518         }
2519         crit_exit();
2520         return (FALSE);
2521 }
2522
2523 /*
2524  * Remove all pages from specified address space
2525  * this aids process exit speeds.  Also, this code
2526  * is special cased for current process only, but
2527  * can have the more generic (and slightly slower)
2528  * mode enabled.  This is much faster than pmap_remove
2529  * in the case of running down an entire address space.
2530  */
2531 void
2532 pmap_remove_pages(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
2533 {
2534         vpte_t *pte, tpte;
2535         pv_entry_t pv, npv;
2536         vm_page_t m;
2537         pmap_inval_info info;
2538         int iscurrentpmap;
2539         int32_t save_generation;
2540
2541         if (curproc && pmap == vmspace_pmap(curproc->p_vmspace))
2542                 iscurrentpmap = 1;
2543         else
2544                 iscurrentpmap = 0;
2545
2546         pmap_inval_init(&info);
2547         crit_enter();
2548         for (pv = TAILQ_FIRST(&pmap->pm_pvlist); pv; pv = npv) {
2549                 if (pv->pv_va >= eva || pv->pv_va < sva) {
2550                         npv = TAILQ_NEXT(pv, pv_plist);
2551                         continue;
2552                 }
2553
2554                 KKASSERT(pmap == pv->pv_pmap);
2555
2556                 pte = pmap_pte(pmap, pv->pv_va);
2557                 tpte = *pte;
2558
2559                 /*
2560                  * We cannot remove wired pages from a process' mapping
2561                  * at this time
2562                  */
2563                 if (tpte & VPTE_WIRED) {
2564                         npv = TAILQ_NEXT(pv, pv_plist);
2565                         continue;
2566                 }
2567                 *pte = 0;
2568                 /* See NOTE: PMAP_INVAL_ADD */
2569                 pmap_inval_add(&info, pmap, pv->pv_va);
2570
2571                 m = PHYS_TO_VM_PAGE(tpte);
2572
2573                 KASSERT(m < &vm_page_array[vm_page_array_size],
2574                         ("pmap_remove_pages: bad tpte %x", tpte));
2575
2576                 pmap->pm_stats.resident_count--;
2577
2578                 /*
2579                  * Update the vm_page_t clean and reference bits.
2580                  */
2581                 if (tpte & VPTE_M) {
2582                         vm_page_dirty(m);
2583                 }
2584
2585                 npv = TAILQ_NEXT(pv, pv_plist);
2586                 TAILQ_REMOVE(&pmap->pm_pvlist, pv, pv_plist);
2587                 save_generation = ++pmap->pm_generation;
2588
2589                 m->md.pv_list_count--;
2590                 TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2591                 if (TAILQ_FIRST(&m->md.pv_list) == NULL) {
2592                         vm_page_flag_clear(m, PG_MAPPED | PG_WRITEABLE);
2593                 }
2594
2595                 pmap_unuse_pt(pmap, pv->pv_va, pv->pv_ptem, &info);
2596                 free_pv_entry(pv);
2597
2598                 /*
2599                  * Restart the scan if we blocked during the unuse or free
2600                  * calls and other removals were made.
2601                  */
2602                 if (save_generation != pmap->pm_generation) {
2603                         kprintf("Warning: pmap_remove_pages race-A avoided\n");
2604                         pv = TAILQ_FIRST(&pmap->pm_pvlist);
2605                 }
2606         }
2607         pmap_inval_flush(&info);
2608         crit_exit();
2609 }
2610
2611 /*
2612  * pmap_testbit tests bits in pte's
2613  * note that the testbit/changebit routines are inline,
2614  * and a lot of things compile-time evaluate.
2615  */
2616 static boolean_t
2617 pmap_testbit(vm_page_t m, int bit)
2618 {
2619         pv_entry_t pv;
2620         vpte_t *pte;
2621
2622         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2623                 return FALSE;
2624
2625         if (TAILQ_FIRST(&m->md.pv_list) == NULL)
2626                 return FALSE;
2627
2628         crit_enter();
2629
2630         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2631                 /*
2632                  * if the bit being tested is the modified bit, then
2633                  * mark clean_map and ptes as never
2634                  * modified.
2635                  */
2636                 if (bit & (VPTE_A|VPTE_M)) {
2637                         if (!pmap_track_modified(pv->pv_pmap, pv->pv_va))
2638                                 continue;
2639                 }
2640
2641 #if defined(PMAP_DIAGNOSTIC)
2642                 if (!pv->pv_pmap) {
2643                         kprintf("Null pmap (tb) at va: 0x%x\n", pv->pv_va);
2644                         continue;
2645                 }
2646 #endif
2647                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2648                 if (*pte & bit) {
2649                         crit_exit();
2650                         return TRUE;
2651                 }
2652         }
2653         crit_exit();
2654         return (FALSE);
2655 }
2656
2657 /*
2658  * This routine is used to clear bits in ptes.  Certain bits require special
2659  * handling, in particular (on virtual kernels) the VPTE_M (modify) bit.
2660  */
2661 static __inline void
2662 pmap_clearbit(vm_page_t m, int bit)
2663 {
2664         struct pmap_inval_info info;
2665         pv_entry_t pv;
2666         vpte_t *pte;
2667         vpte_t pbits;
2668
2669         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2670                 return;
2671
2672         pmap_inval_init(&info);
2673         crit_enter();
2674
2675         /*
2676          * Loop over all current mappings setting/clearing as appropos If
2677          * setting RO do we need to clear the VAC?
2678          */
2679         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
2680                 /*
2681                  * don't write protect pager mappings
2682                  */
2683                 if (bit == VPTE_W) {
2684                         if (!pmap_track_modified(pv->pv_pmap, pv->pv_va))
2685                                 continue;
2686                 }
2687
2688 #if defined(PMAP_DIAGNOSTIC)
2689                 if (!pv->pv_pmap) {
2690                         kprintf("Null pmap (cb) at va: 0x%x\n", pv->pv_va);
2691                         continue;
2692                 }
2693 #endif
2694
2695                 /*
2696                  * Careful here.  We can use a locked bus instruction to
2697                  * clear VPTE_A or VPTE_M safely but we need to synchronize
2698                  * with the target cpus when we mess with VPTE_W.
2699                  *
2700                  * On virtual kernels we must force a new fault-on-write
2701                  * in the real kernel if we clear the Modify bit ourselves,
2702                  * otherwise the real kernel will not get a new fault and
2703                  * will never set our Modify bit again. 
2704                  */
2705                 pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2706                 if (bit & (VPTE_W|VPTE_M))
2707                         pmap_inval_add(&info, pv->pv_pmap, pv->pv_va);
2708
2709                 pbits = *pte;
2710                 if (pbits & bit) {
2711                         if (bit == VPTE_W) {
2712                                 if (pbits & VPTE_M) {
2713                                         vm_page_dirty(m);
2714                                 }
2715                                 atomic_clear_int(pte, VPTE_M|VPTE_W);
2716                         } else if (bit == VPTE_M) {
2717                                 /*
2718                                  * We do not have to make the page read-only
2719                                  * when clearing the Modify bit.  The real
2720                                  * kernel will make the real PTE read-only
2721                                  * or otherwise detect the write and set
2722                                  * our VPTE_M again simply by us invalidating
2723                                  * the real kernel VA for the pmap (as we did
2724                                  * above).  This allows the real kernel to
2725                                  * handle the write fault without forwarding
2726                                  * the fault to us.
2727                                  */
2728                                 atomic_clear_int(pte, VPTE_M);
2729                         } else {
2730                                 atomic_clear_int(pte, bit);
2731                         }
2732                 }
2733         }
2734         pmap_inval_flush(&info);
2735         crit_exit();
2736 }
2737
2738 /*
2739  *      pmap_page_protect:
2740  *
2741  *      Lower the permission for all mappings to a given page.
2742  */
2743 void
2744 pmap_page_protect(vm_page_t m, vm_prot_t prot)
2745 {
2746         if ((prot & VM_PROT_WRITE) == 0) {
2747                 if (prot & (VM_PROT_READ | VM_PROT_EXECUTE)) {
2748                         pmap_clearbit(m, VPTE_W);
2749                 } else {
2750                         pmap_remove_all(m);
2751                 }
2752         }
2753 }
2754
2755 vm_paddr_t
2756 pmap_phys_address(int ppn)
2757 {
2758         return (i386_ptob(ppn));
2759 }
2760
2761 /*
2762  *      pmap_ts_referenced:
2763  *
2764  *      Return a count of reference bits for a page, clearing those bits.
2765  *      It is not necessary for every reference bit to be cleared, but it
2766  *      is necessary that 0 only be returned when there are truly no
2767  *      reference bits set.
2768  *
2769  *      XXX: The exact number of bits to check and clear is a matter that
2770  *      should be tested and standardized at some point in the future for
2771  *      optimal aging of shared pages.
2772  */
2773 int
2774 pmap_ts_referenced(vm_page_t m)
2775 {
2776         pv_entry_t pv, pvf, pvn;
2777         vpte_t *pte;
2778         int rtval = 0;
2779
2780         if (!pmap_initialized || (m->flags & PG_FICTITIOUS))
2781                 return (rtval);
2782
2783         crit_enter();
2784
2785         if ((pv = TAILQ_FIRST(&m->md.pv_list)) != NULL) {
2786
2787                 pvf = pv;
2788
2789                 do {
2790                         pvn = TAILQ_NEXT(pv, pv_list);
2791
2792                         TAILQ_REMOVE(&m->md.pv_list, pv, pv_list);
2793
2794                         TAILQ_INSERT_TAIL(&m->md.pv_list, pv, pv_list);
2795
2796                         if (!pmap_track_modified(pv->pv_pmap, pv->pv_va))
2797                                 continue;
2798
2799                         pte = pmap_pte(pv->pv_pmap, pv->pv_va);
2800
2801                         if (pte && (*pte & VPTE_A)) {
2802 #ifdef SMP
2803                                 atomic_clear_int(pte, VPTE_A);
2804 #else
2805                                 atomic_clear_int_nonlocked(pte, VPTE_A);
2806 #endif
2807                                 rtval++;
2808                                 if (rtval > 4) {
2809                                         break;
2810                                 }
2811                         }
2812                 } while ((pv = pvn) != NULL && pv != pvf);
2813         }
2814         crit_exit();
2815
2816         return (rtval);
2817 }
2818
2819 /*
2820  *      pmap_is_modified:
2821  *
2822  *      Return whether or not the specified physical page was modified
2823  *      in any physical maps.
2824  */
2825 boolean_t
2826 pmap_is_modified(vm_page_t m)
2827 {
2828         return pmap_testbit(m, VPTE_M);
2829 }
2830
2831 /*
2832  *      Clear the modify bits on the specified physical page.
2833  */
2834 void
2835 pmap_clear_modify(vm_page_t m)
2836 {
2837         pmap_clearbit(m, VPTE_M);
2838 }
2839
2840 /*
2841  *      pmap_clear_reference:
2842  *
2843  *      Clear the reference bit on the specified physical page.
2844  */
2845 void
2846 pmap_clear_reference(vm_page_t m)
2847 {
2848         pmap_clearbit(m, VPTE_A);
2849 }
2850
2851 /*
2852  * Miscellaneous support routines follow
2853  */
2854
2855 static void
2856 i386_protection_init(void)
2857 {
2858         int *kp, prot;
2859
2860         kp = protection_codes;
2861         for (prot = 0; prot < 8; prot++) {
2862                 if (prot & VM_PROT_READ)
2863                         *kp |= VPTE_R;
2864                 if (prot & VM_PROT_WRITE)
2865                         *kp |= VPTE_W;
2866                 if (prot & VM_PROT_EXECUTE)
2867                         *kp |= VPTE_X;
2868                 ++kp;
2869         }
2870 }
2871
2872 /*
2873  * Map a set of physical memory pages into the kernel virtual
2874  * address space. Return a pointer to where it is mapped. This
2875  * routine is intended to be used for mapping device memory,
2876  * NOT real memory.
2877  *
2878  * NOTE: we can't use pgeflag unless we invalidate the pages one at
2879  * a time.
2880  */
2881 void *
2882 pmap_mapdev(vm_paddr_t pa, vm_size_t size)
2883 {
2884         vm_offset_t va, tmpva, offset;
2885         vpte_t *pte;
2886
2887         offset = pa & PAGE_MASK;
2888         size = roundup(offset + size, PAGE_SIZE);
2889
2890         va = kmem_alloc_nofault(&kernel_map, size);
2891         if (!va)
2892                 panic("pmap_mapdev: Couldn't alloc kernel virtual memory");
2893
2894         pa = pa & VPTE_FRAME;
2895         for (tmpva = va; size > 0;) {
2896                 pte = KernelPTA + (tmpva >> PAGE_SHIFT);
2897                 *pte = pa | VPTE_R | VPTE_W | VPTE_V; /* | pgeflag; */
2898                 size -= PAGE_SIZE;
2899                 tmpva += PAGE_SIZE;
2900                 pa += PAGE_SIZE;
2901         }
2902         cpu_invltlb();
2903         smp_invltlb();
2904
2905         return ((void *)(va + offset));
2906 }
2907
2908 void
2909 pmap_unmapdev(vm_offset_t va, vm_size_t size)
2910 {
2911         vm_offset_t base, offset;
2912
2913         base = va & VPTE_FRAME;
2914         offset = va & PAGE_MASK;
2915         size = roundup(offset + size, PAGE_SIZE);
2916         pmap_qremove(va, size >> PAGE_SHIFT);
2917         kmem_free(&kernel_map, base, size);
2918 }
2919
2920 /*
2921  * perform the pmap work for mincore
2922  */
2923 int
2924 pmap_mincore(pmap_t pmap, vm_offset_t addr)
2925 {
2926         vpte_t *ptep, pte;
2927         vm_page_t m;
2928         int val = 0;
2929         
2930         ptep = pmap_pte(pmap, addr);
2931         if (ptep == 0) {
2932                 return 0;
2933         }
2934
2935         if ((pte = *ptep) != 0) {
2936                 vm_offset_t pa;
2937
2938                 val = MINCORE_INCORE;
2939                 if ((pte & VPTE_MANAGED) == 0)
2940                         return val;
2941
2942                 pa = pte & VPTE_FRAME;
2943
2944                 m = PHYS_TO_VM_PAGE(pa);
2945
2946                 /*
2947                  * Modified by us
2948                  */
2949                 if (pte & VPTE_M)
2950                         val |= MINCORE_MODIFIED|MINCORE_MODIFIED_OTHER;
2951                 /*
2952                  * Modified by someone
2953                  */
2954                 else if (m->dirty || pmap_is_modified(m))
2955                         val |= MINCORE_MODIFIED_OTHER;
2956                 /*
2957                  * Referenced by us
2958                  */
2959                 if (pte & VPTE_A)
2960                         val |= MINCORE_REFERENCED|MINCORE_REFERENCED_OTHER;
2961
2962                 /*
2963                  * Referenced by someone
2964                  */
2965                 else if ((m->flags & PG_REFERENCED) || pmap_ts_referenced(m)) {
2966                         val |= MINCORE_REFERENCED_OTHER;
2967                         vm_page_flag_set(m, PG_REFERENCED);
2968                 }
2969         } 
2970         return val;
2971 }
2972
2973 void
2974 pmap_activate(struct proc *p)
2975 {
2976         pmap_t  pmap;
2977
2978         pmap = vmspace_pmap(p->p_vmspace);
2979 #if defined(SMP)
2980         atomic_set_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
2981 #else
2982         pmap->pm_active |= 1;
2983 #endif
2984 #if defined(SWTCH_OPTIM_STATS)
2985         tlb_flush_count++;
2986 #endif
2987 #if 0
2988         KKASSERT((p == curproc));
2989
2990         curthread->td_pcb->pcb_cr3 = vtophys(pmap->pm_pdir);
2991         load_cr3(curthread->td_pcb->pcb_cr3);
2992 #endif
2993 }
2994
2995 void
2996 pmap_deactivate(struct proc *p)
2997 {
2998         pmap_t  pmap;
2999
3000         pmap = vmspace_pmap(p->p_vmspace);
3001 #if defined(SMP)
3002         atomic_clear_int(&pmap->pm_active, 1 << mycpu->gd_cpuid);
3003 #else
3004         pmap->pm_active &= ~1;
3005 #endif
3006         /*
3007          * XXX - note we do not adjust %cr3.  The caller is expected to
3008          * activate a new pmap or do a thread-exit.
3009          */
3010 }
3011
3012 vm_offset_t
3013 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
3014 {
3015
3016         if ((obj == NULL) || (size < NBPDR) || (obj->type != OBJT_DEVICE)) {
3017                 return addr;
3018         }
3019
3020         addr = (addr + (NBPDR - 1)) & ~(NBPDR - 1);
3021         return addr;
3022 }
3023
3024
3025 #if defined(DEBUG)
3026
3027 static void     pads (pmap_t pm);
3028 void            pmap_pvdump (vm_paddr_t pa);
3029
3030 /* print address space of pmap*/
3031 static void
3032 pads(pmap_t pm)
3033 {
3034         vm_offset_t va;
3035         int i, j;
3036         vpte_t *ptep;
3037
3038         if (pm == &kernel_pmap)
3039                 return;
3040         for (i = 0; i < 1024; i++)
3041                 if (pm->pm_pdir[i])
3042                         for (j = 0; j < 1024; j++) {
3043                                 va = (i << PDRSHIFT) + (j << PAGE_SHIFT);
3044                                 if (pm == &kernel_pmap && va < KERNBASE)
3045                                         continue;
3046                                 if (pm != &kernel_pmap && va > UPT_MAX_ADDRESS)
3047                                         continue;
3048                                 ptep = pmap_pte(pm, va);
3049                                 if (ptep && (*ptep & VPTE_V)) {
3050                                         kprintf("%p:%x ",
3051                                                 (void *)va, (unsigned)*ptep);
3052                                 }
3053                         };
3054
3055 }
3056
3057 void
3058 pmap_pvdump(vm_paddr_t pa)
3059 {
3060         pv_entry_t pv;
3061         vm_page_t m;
3062
3063         kprintf("pa %08llx", (long long)pa);
3064         m = PHYS_TO_VM_PAGE(pa);
3065         TAILQ_FOREACH(pv, &m->md.pv_list, pv_list) {
3066 #ifdef used_to_be
3067                 kprintf(" -> pmap %p, va %x, flags %x",
3068                     (void *)pv->pv_pmap, pv->pv_va, pv->pv_flags);
3069 #endif
3070                 kprintf(" -> pmap %p, va %x", (void *)pv->pv_pmap, pv->pv_va);
3071                 pads(pv->pv_pmap);
3072         }
3073         kprintf(" ");
3074 }
3075 #endif
3076