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