diff options
| author | thorpej <thorpej@NetBSD.org> | 2003-05-10 21:10:23 +0000 |
|---|---|---|
| committer | thorpej <thorpej@NetBSD.org> | 2003-05-10 21:10:23 +0000 |
| commit | 36da248c07b1480452b301e2bdda5e5d9d488387 (patch) | |
| tree | 235632187429e3924cb6b65048f2ae80bfce7c42 /sys | |
| parent | a760954e6f097b06d57735ad91d94cf58fdea08c (diff) | |
Back out the following chagne:
http://mail-index.netbsd.org/source-changes/2003/05/08/0068.html
There were some side-effects that I didn't anticipate, and fixing them
is proving to be more difficult than I thought, do just eject for now.
Maybe one day we can look at this again.
Fixes PR kern/21517.
Diffstat (limited to 'sys')
39 files changed, 825 insertions, 369 deletions
diff --git a/sys/arch/acorn26/acorn26/pmap.c b/sys/arch/acorn26/acorn26/pmap.c index 894d9853a8d..4faa0b7be91 100644 --- a/sys/arch/acorn26/acorn26/pmap.c +++ b/sys/arch/acorn26/acorn26/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.8 2003/05/08 18:13:12 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.9 2003/05/10 21:10:25 thorpej Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 Ben Harris * All rights reserved. @@ -102,7 +102,7 @@ #include <sys/param.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.8 2003/05/08 18:13:12 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.9 2003/05/10 21:10:25 thorpej Exp $"); #include <sys/kernel.h> /* for cold */ #include <sys/malloc.h> @@ -237,8 +237,9 @@ update_memc(register_t mask, register_t value) * pmap_bootstrap: first-stage pmap initialisation * * This is called very early, and has to get the pmap system into a - * state where pmap_kenter_pa at least will work. If we need memory - * here, we have to work out how to get it ourselves. + * state where pmap_virtual_space and pmap_kenter_pa at least will + * work. If we need memory here, we have to work out how to get it + * ourselves. */ void pmap_bootstrap(int npages, paddr_t zp_physaddr) @@ -260,15 +261,6 @@ pmap_bootstrap(int npages, paddr_t zp_physaddr) pv_table[i].pv_pflags |= PV_MODIFIED; #endif - /* - * Define the boundaries of the managed kernel virtual address - * space. Since NetBSD/acorn26 runs the kernel from physically- - * mapped space, we just return all of kernel vm. Oh, except for - * the single page at the end where we map otherwise-unmapped pages. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; - virtual_end = VM_MAX_KERNEL_ADDRESS - PAGE_SIZE; - /* Set up the kernel's pmap */ pmap = pmap_kernel(); bzero(pmap, sizeof(*pmap)); @@ -296,7 +288,7 @@ pmap_bootstrap(int npages, paddr_t zp_physaddr) } vaddr_t -pmap_steal_memory(vsize_t size) +pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp) { int i; vaddr_t addr; @@ -1105,6 +1097,25 @@ pmap_md4_page(unsigned char digest[16], paddr_t pa) } #endif +/* + * This is meant to return the range of kernel vm that is available + * after loading the kernel. Since NetBSD/acorn26 runs the kernel from + * physically-mapped space, we just return all of kernel vm. Oh, + * except for the single page at the end where we map + * otherwise-unmapped pages. + */ +void +pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) +{ + UVMHIST_FUNC("pmap_virtual_space"); + + UVMHIST_CALLED(pmaphist); + if (vstartp != NULL) + *vstartp = VM_MIN_KERNEL_ADDRESS; + if (vendp != NULL) + *vendp = VM_MAX_KERNEL_ADDRESS - PAGE_SIZE; +} + #ifdef DDB #include <ddb/db_output.h> diff --git a/sys/arch/alpha/alpha/machdep.c b/sys/arch/alpha/alpha/machdep.c index c3c005b95e3..2b4e0fa2373 100644 --- a/sys/arch/alpha/alpha/machdep.c +++ b/sys/arch/alpha/alpha/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.267 2003/05/09 05:33:52 enami Exp $ */ +/* $NetBSD: machdep.c,v 1.268 2003/05/10 21:10:25 thorpej Exp $ */ /*- * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. @@ -75,7 +75,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.267 2003/05/09 05:33:52 enami Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.268 2003/05/10 21:10:25 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -635,13 +635,20 @@ nobootinfo: if (sz != reqsz) printf("WARNING: %ld bytes not available for msgbuf " "in last cluster (%ld used)\n", reqsz, sz); + } /* + * NOTE: It is safe to use uvm_pageboot_alloc() before + * pmap_bootstrap() because our pmap_virtual_space() + * returns compile-time constants. + */ + + /* * Init mapping for u page(s) for proc 0 */ lwp0.l_addr = proc0paddr = - (struct user *)pmap_steal_memory(UPAGES * PAGE_SIZE); + (struct user *)uvm_pageboot_alloc(UPAGES * PAGE_SIZE); /* * Allocate space for system data structures. These data structures @@ -650,7 +657,7 @@ nobootinfo: * virtual address space. */ size = (vsize_t)allocsys(NULL, NULL); - v = (caddr_t)pmap_steal_memory(size); + v = (caddr_t)uvm_pageboot_alloc(size); if ((allocsys(v, NULL) - v) != size) panic("alpha_init: table size inconsistency"); diff --git a/sys/arch/alpha/alpha/pmap.c b/sys/arch/alpha/alpha/pmap.c index f1d0f09f840..cb7159cb998 100644 --- a/sys/arch/alpha/alpha/pmap.c +++ b/sys/arch/alpha/alpha/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.199 2003/05/09 05:33:53 enami Exp $ */ +/* $NetBSD: pmap.c,v 1.200 2003/05/10 21:10:26 thorpej Exp $ */ /*- * Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc. @@ -149,7 +149,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.199 2003/05/09 05:33:53 enami Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.200 2003/05/10 21:10:26 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -232,7 +232,7 @@ u_long kernel_pmap_store[PMAP_SIZEOF(ALPHA_MAXPROCS) / sizeof(u_long)]; paddr_t avail_start; /* PA of first available physical page */ paddr_t avail_end; /* PA of last available physical page */ -static vaddr_t pmap_max_kva; /* VA of last mappable page */ +static vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ boolean_t pmap_initialized; /* Has pmap_init completed? */ @@ -365,7 +365,7 @@ struct pmap_asn_info pmap_asn_info[ALPHA_MAXPROCS]; * lock is held. * * * pmap_growkernel_slock - This lock protects pmap_growkernel() - * and the pmap_max_kva variable. + * and the virtual_end variable. * * There is a lock ordering constraint for pmap_growkernel_slock. * pmap_growkernel() acquires the locks in the following order: @@ -830,19 +830,12 @@ pmap_bootstrap(paddr_t ptaddr, u_int maxasn, u_long ncpuids) */ avail_start = ptoa(vm_physmem[0].start); avail_end = ptoa(vm_physmem[vm_nphysseg - 1].end); - pmap_max_kva = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE; - - /* - * Define the boundaries of the managed kernel virtual address - * space. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ - virtual_end = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */ + virtual_end = VM_MIN_KERNEL_ADDRESS + lev3mapsize * PAGE_SIZE; #if 0 printf("avail_start = 0x%lx\n", avail_start); printf("avail_end = 0x%lx\n", avail_end); - printf("pmap_max_kva = 0x%lx\n", pmap_max_kva); + printf("virtual_end = 0x%lx\n", virtual_end); #endif /* @@ -1017,6 +1010,19 @@ pmap_uses_prom_console(void) #endif /* _PMAP_MAY_USE_PROM_CONSOLE */ /* + * pmap_virtual_space: [ INTERFACE ] + * + * Define the initial bounds of the kernel virtual address space. + */ +void +pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) +{ + + *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ + *vendp = VM_MAX_KERNEL_ADDRESS; /* we use pmap_growkernel */ +} + +/* * pmap_steal_memory: [ INTERFACE ] * * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()). @@ -1034,10 +1040,13 @@ pmap_uses_prom_console(void) * Note that this memory will never be freed, and in essence it is wired * down. * + * We must adjust *vstartp and/or *vendp iff we use address space + * from the kernel virtual address range defined by pmap_virtual_space(). + * * Note: no locking is necessary in this function. */ vaddr_t -pmap_steal_memory(vsize_t size) +pmap_steal_memory(vsize_t size, vaddr_t *vstartp, vaddr_t *vendp) { int bank, npgs, x; vaddr_t va; @@ -3132,12 +3141,12 @@ pmap_growkernel(vaddr_t maxkvaddr) vaddr_t va; int l1idx; - if (maxkvaddr <= pmap_max_kva) + if (maxkvaddr <= virtual_end) goto out; /* we are OK */ simple_lock(&pmap_growkernel_slock); - va = pmap_max_kva; + va = virtual_end; while (va < maxkvaddr) { /* @@ -3157,7 +3166,7 @@ pmap_growkernel(vaddr_t maxkvaddr) * be handled a little differently. */ ptaddr = ALPHA_K0SEG_TO_PHYS( - pmap_steal_memory(PAGE_SIZE)); + pmap_steal_memory(PAGE_SIZE, NULL, NULL)); } else if (pmap_physpage_alloc(PGU_NORMAL, &ptaddr) == FALSE) goto die; @@ -3196,7 +3205,7 @@ pmap_growkernel(vaddr_t maxkvaddr) * See above. */ ptaddr = ALPHA_K0SEG_TO_PHYS( - pmap_steal_memory(PAGE_SIZE)); + pmap_steal_memory(PAGE_SIZE, NULL, NULL)); } else if (pmap_physpage_alloc(PGU_NORMAL, &ptaddr) == FALSE) goto die; *l2pte = (atop(ptaddr) << PG_SHIFT) | @@ -3207,12 +3216,12 @@ pmap_growkernel(vaddr_t maxkvaddr) /* Invalidate the L1 PT cache. */ pool_cache_invalidate(&pmap_l1pt_cache); - pmap_max_kva = va; + virtual_end = va; simple_unlock(&pmap_growkernel_slock); out: - return (pmap_max_kva); + return (virtual_end); die: panic("pmap_growkernel: out of memory"); diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c index e5b482d0e96..98e3a255865 100644 --- a/sys/arch/amd64/amd64/pmap.c +++ b/sys/arch/amd64/amd64/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.3 2003/05/08 18:13:13 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.4 2003/05/10 21:10:26 thorpej Exp $ */ /* * @@ -405,6 +405,17 @@ static pt_entry_t protection_codes[8]; /* maps MI prot to i386 prot code */ static boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ /* + * the following two vaddr_t's are used during system startup + * to keep track of how much of the kernel's VM space we have used. + * once the system is started, the management of the remaining kernel + * VM space is turned over to the kernel_map vm_map. + */ + +static vaddr_t virtual_avail; /* VA of first free KVA */ +static vaddr_t virtual_end; /* VA of last free KVA */ + + +/* * pv_page management structures: locked by pvalloc_lock */ @@ -885,8 +896,8 @@ pmap_bootstrap(kva_start) unsigned long p1i; /* - * define the voundaries of the managed kernel virtual address - * space. + * set up our local static global vars that keep track of the + * usage of KVM before kernel_map is set up */ virtual_avail = kva_start; /* first free KVA */ @@ -2244,6 +2255,20 @@ vtophys(va) /* + * pmap_virtual_space: used during bootup [pmap_steal_memory] to + * determine the bounds of the kernel virtual addess space. + */ + +void +pmap_virtual_space(startp, endp) + vaddr_t *startp; + vaddr_t *endp; +{ + *startp = virtual_avail; + *endp = virtual_end; +} + +/* * pmap_map: map a range of PAs into kvm * * => used during crash dump diff --git a/sys/arch/amiga/amiga/pmap.c b/sys/arch/amiga/amiga/pmap.c index 4c413943bbc..1ee437d228d 100644 --- a/sys/arch/amiga/amiga/pmap.c +++ b/sys/arch/amiga/amiga/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.105 2003/05/08 18:13:13 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.106 2003/05/10 21:10:27 thorpej Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -111,7 +111,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.105 2003/05/08 18:13:13 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.106 2003/05/10 21:10:27 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -286,6 +286,8 @@ struct vm_map *pt_map; struct vm_map pt_map_store; vsize_t mem_size; /* memory size in bytes */ +vaddr_t virtual_avail; /* VA of first avail page (after kernel bss)*/ +vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ int page_cnt; /* number of pages managed by the VM system */ boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ char *pmap_attributes; /* reference and modify bits */ @@ -550,6 +552,56 @@ pmap_init() #endif /* + * Allocate memory for random pmap data structures. Includes the + * initial segment table, pv_head_table and pmap_attributes. + */ + for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++) { + page_cnt += vm_physmem[bank].end - vm_physmem[bank].start; +#ifdef DEBUG + printf("pmap_init: %2d: %08lx - %08lx (%10d)\n", bank, + vm_physmem[bank].start << PGSHIFT, + vm_physmem[bank].end << PGSHIFT, page_cnt << PGSHIFT); +#endif + } + s = AMIGA_STSIZE; /* Segtabzero */ + s += page_cnt * sizeof(struct pv_entry); /* pv table */ + s += page_cnt * sizeof(char); /* attribute table */ + s = round_page(s); + + addr = uvm_km_zalloc(kernel_map, s); + if (addr == 0) + panic("pmap_init: can't allocate data structures"); + Segtabzero = (u_int *) addr; + (void) pmap_extract(pmap_kernel(), addr, (paddr_t *)&Segtabzeropa); + addr += AMIGA_STSIZE; + + pv_table = (pv_entry_t) addr; + addr += page_cnt * sizeof(struct pv_entry); + + pmap_attributes = (char *) addr; +#ifdef DEBUG + if (pmapdebug & PDB_INIT) + printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) " + "tbl %p atr %p\n", + s, page_cnt, Segtabzero, Segtabzeropa, + pv_table, pmap_attributes); +#endif + + /* + * Now that the pv and attribute tables have been allocated, + * assign them to the memory segments. + */ + pv = pv_table; + attr = pmap_attributes; + for (bank = 0; bank < vm_nphysseg; bank++) { + npg = vm_physmem[bank].end - vm_physmem[bank].start; + vm_physmem[bank].pmseg.pvent = pv; + vm_physmem[bank].pmseg.attrs = attr; + pv += npg; + attr += npg; + } + + /* * Allocate physical memory for kernel PT pages and their management. * we need enough pages to map the page tables for each process * plus some slop. @@ -570,8 +622,7 @@ pmap_init() * Verify that space will be allocated in region for which * we already have kernel PT pages. */ - addr = vm_map_min(kernel_map); - kernel_map->first_free = &kernel_map->header; /* XXX */ + addr = 0; rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)); @@ -583,7 +634,6 @@ pmap_init() * Now allocate the space and link the pages together to * form the KPT free list. */ - kernel_map->first_free = &kernel_map->header; /* XXX */ addr = uvm_km_zalloc(kernel_map, s); if (addr == 0) panic("pmap_init: cannot allocate KPT free list"); @@ -608,57 +658,6 @@ pmap_init() #endif /* - * Allocate memory for random pmap data structures. Includes the - * initial segment table, pv_head_table and pmap_attributes. - */ - for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++) { - page_cnt += vm_physmem[bank].end - vm_physmem[bank].start; -#ifdef DEBUG - printf("pmap_init: %2d: %08lx - %08lx (%10d)\n", bank, - vm_physmem[bank].start << PGSHIFT, - vm_physmem[bank].end << PGSHIFT, page_cnt << PGSHIFT); -#endif - } - s = AMIGA_STSIZE; /* Segtabzero */ - s += page_cnt * sizeof(struct pv_entry); /* pv table */ - s += page_cnt * sizeof(char); /* attribute table */ - s = round_page(s); - - kernel_map->first_free = &kernel_map->header; /* XXX */ - addr = uvm_km_zalloc(kernel_map, s); - if (addr == 0) - panic("pmap_init: can't allocate data structures"); - Segtabzero = (u_int *) addr; - (void) pmap_extract(pmap_kernel(), addr, (paddr_t *)&Segtabzeropa); - addr += AMIGA_STSIZE; - - pv_table = (pv_entry_t) addr; - addr += page_cnt * sizeof(struct pv_entry); - - pmap_attributes = (char *) addr; -#ifdef DEBUG - if (pmapdebug & PDB_INIT) - printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) " - "tbl %p atr %p\n", - s, page_cnt, Segtabzero, Segtabzeropa, - pv_table, pmap_attributes); -#endif - - /* - * Now that the pv and attribute tables have been allocated, - * assign them to the memory segments. - */ - pv = pv_table; - attr = pmap_attributes; - for (bank = 0; bank < vm_nphysseg; bank++) { - npg = vm_physmem[bank].end - vm_physmem[bank].start; - vm_physmem[bank].pmseg.pvent = pv; - vm_physmem[bank].pmseg.attrs = attr; - pv += npg; - attr += npg; - } - - /* * Allocate the segment table map and the page table map. */ addr = amiga_uptbase; @@ -675,7 +674,6 @@ pmap_init() } else s = maxproc * AMIGA_UPTSIZE; - kernel_map->first_free = &kernel_map->header; /* XXX */ pt_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, 0, TRUE, &pt_map_store); @@ -2749,6 +2747,23 @@ pmap_check_wiring(str, va) #endif /* + * Routine: pmap_virtual_space + * + * Function: + * Report the range of available kernel virtual address + * space to the VM system during bootstrap. Called by + * vm_bootstrap_steal_memory(). + */ +void +pmap_virtual_space(vstartp, vendp) + vaddr_t *vstartp, *vendp; +{ + + *vstartp = virtual_avail; + *vendp = virtual_end; +} + +/* * Routine: pmap_procwr * * Function: diff --git a/sys/arch/arm/arm32/pmap.c b/sys/arch/arm/arm32/pmap.c index 5e86ebbedec..f470e247e38 100644 --- a/sys/arch/arm/arm32/pmap.c +++ b/sys/arch/arm/arm32/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.132 2003/05/08 18:13:14 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.133 2003/05/10 21:10:27 thorpej Exp $ */ /* * Copyright (c) 2002 Wasabi Systems, Inc. @@ -144,7 +144,7 @@ #include <machine/param.h> #include <arm/arm32/katelib.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.132 2003/05/08 18:13:14 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.133 2003/05/10 21:10:27 thorpej Exp $"); #ifdef PMAP_DEBUG #define PDEBUG(_lev_,_stat_) \ @@ -312,6 +312,8 @@ extern paddr_t physical_start; extern paddr_t physical_end; extern int max_processes; +vaddr_t virtual_avail; +vaddr_t virtual_end; vaddr_t pmap_curmaxkvaddr; vaddr_t avail_start; @@ -1011,10 +1013,6 @@ pmap_bootstrap(pd_entry_t *kernel_l1pt, pv_addr_t kernel_ptpt) pmap_kernel()->pm_obj.uo_npages = 0; pmap_kernel()->pm_obj.uo_refs = 1; - /* - * Define the boundaries of the managed kernel virtual address - * space. - */ virtual_avail = KERNEL_VM_BASE; virtual_end = KERNEL_VM_BASE + KERNEL_VM_SIZE; @@ -1644,6 +1642,21 @@ pmap_reference(struct pmap *pmap) } /* + * void pmap_virtual_space(vaddr_t *start, vaddr_t *end) + * + * Return the start and end addresses of the kernel's virtual space. + * These values are setup in pmap_bootstrap and are updated as pages + * are allocated. + */ + +void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + *start = virtual_avail; + *end = virtual_end; +} + +/* * Activate the address space for the specified process. If the process * is the current process, load the new MMU context. */ diff --git a/sys/arch/arm/arm32/pmap_new.c b/sys/arch/arm/arm32/pmap_new.c index fbf9a75f68f..e6421b830bf 100644 --- a/sys/arch/arm/arm32/pmap_new.c +++ b/sys/arch/arm/arm32/pmap_new.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap_new.c,v 1.11 2003/05/08 18:13:14 thorpej Exp $ */ +/* $NetBSD: pmap_new.c,v 1.12 2003/05/10 21:10:28 thorpej Exp $ */ /* * Copyright 2003 Wasabi Systems, Inc. @@ -210,7 +210,7 @@ #include <machine/param.h> #include <arm/arm32/katelib.h> -__KERNEL_RCSID(0, "$NetBSD: pmap_new.c,v 1.11 2003/05/08 18:13:14 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap_new.c,v 1.12 2003/05/10 21:10:28 thorpej Exp $"); #ifdef PMAP_DEBUG #define PDEBUG(_lev_,_stat_) \ @@ -527,6 +527,8 @@ extern void bcopy_page(vaddr_t, vaddr_t); /* * Misc variables */ +vaddr_t virtual_avail; +vaddr_t virtual_end; vaddr_t pmap_curmaxkvaddr; vaddr_t avail_start; @@ -3443,6 +3445,20 @@ pmap_copy_page_xscale(paddr_t src, paddr_t dst) #endif /* ARM_MMU_XSCALE == 1 */ /* + * void pmap_virtual_space(vaddr_t *start, vaddr_t *end) + * + * Return the start and end addresses of the kernel's virtual space. + * These values are setup in pmap_bootstrap and are updated as pages + * are allocated. + */ +void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + *start = virtual_avail; + *end = virtual_end; +} + +/* * Helper function for pmap_grow_l2_bucket() */ static __inline int @@ -3897,9 +3913,6 @@ pmap_bootstrap(pd_entry_t *kernel_l1pt, vaddr_t vstart, vaddr_t vend) * virtual_avail (note that there are no pages mapped at these VAs). * * Managed KVM space start from wherever initarm() tells us. - * - * Note that virtual_avail and virtual_end define the boundaries - * of the managed kernel virtual address space. */ virtual_avail = vstart; virtual_end = vend; diff --git a/sys/arch/atari/atari/machdep.c b/sys/arch/atari/atari/machdep.c index 76ca5ba661b..5a287e43dce 100644 --- a/sys/arch/atari/atari/machdep.c +++ b/sys/arch/atari/atari/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.123 2003/05/08 18:13:14 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.124 2003/05/10 21:10:28 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -190,6 +190,7 @@ consinit() void cpu_startup() { + extern void etext __P((void)); extern int iomem_malloc_safe; caddr_t v; u_int i, base, residual; @@ -293,6 +294,26 @@ cpu_startup() nmbclusters * mclbytes, VM_MAP_INTRSAFE, FALSE, NULL); + /* + * Tell the VM system that page 0 isn't mapped. + * + * XXX This is bogus; should just fix KERNBASE and + * XXX VM_MIN_KERNEL_ADDRESS, but not right now. + */ + if (uvm_map_protect(kernel_map, 0, PAGE_SIZE, UVM_PROT_NONE, TRUE) != 0) + panic("can't mark page 0 off-limits"); + + /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + * + * XXX Should be m68k_trunc_page(&kernel_text) instead + * XXX of PAGE_SIZE. + */ + if (uvm_map_protect(kernel_map, PAGE_SIZE, m68k_round_page(&etext), + UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) + panic("can't protect kernel text"); + #ifdef DEBUG pmapdebug = opmapdebug; #endif diff --git a/sys/arch/atari/atari/pmap.c b/sys/arch/atari/atari/pmap.c index a36384a666c..e3794a934d5 100644 --- a/sys/arch/atari/atari/pmap.c +++ b/sys/arch/atari/atari/pmap.c @@ -1,4 +1,3 @@ -/* $NetBSD: pmap.c,v 1.82 2003/05/08 18:13:15 thorpej Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -283,6 +282,8 @@ struct vm_map pt_map_store; vsize_t mem_size; /* memory size in bytes */ paddr_t avail_end; /* PA of last available physical page */ +vaddr_t virtual_avail; /* VA of first avail page (after kernel bss)*/ +vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ int page_cnt; /* number of pages managed by the VM system */ boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ char *pmap_attributes; /* reference and modify bits */ @@ -504,6 +505,55 @@ pmap_init() #endif /* + * Allocate memory for random pmap data structures. Includes the + * initial segment table, pv_head_table and pmap_attributes. + */ + for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++) { + page_cnt += vm_physmem[bank].end - vm_physmem[bank].start; +#ifdef DEBUG + printf("pmap_init: %2d: %08lx - %08lx (%10d)\n", bank, + vm_physmem[bank].start << PGSHIFT, + vm_physmem[bank].end << PGSHIFT, page_cnt << PGSHIFT); +#endif + } + s = ATARI_STSIZE; /* Segtabzero */ + s += page_cnt * sizeof(struct pv_entry); /* pv table */ + s += page_cnt * sizeof(char); /* attribute table */ + s = round_page(s); + + addr = uvm_km_zalloc(kernel_map, s); + if (addr == 0) + panic("pmap_init: can't allocate data structures"); + Segtabzero = (u_int *) addr; + (void) pmap_extract(pmap_kernel(), addr, (paddr_t *)&Segtabzeropa); + addr += ATARI_STSIZE; + pv_table = (pv_entry_t) addr; + addr += page_cnt * sizeof(struct pv_entry); + + pmap_attributes = (char *) addr; +#ifdef DEBUG + if (pmapdebug & PDB_INIT) + printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) " + "tbl %p atr %p\n", + s, page_cnt, Segtabzero, Segtabzeropa, + pv_table, pmap_attributes); +#endif + + /* + * Now that the pv and attribute tables have been allocated, + * assign them to the memory segments. + */ + pv = pv_table; + attr = pmap_attributes; + for (bank = 0; bank < vm_nphysseg; bank++) { + npg = vm_physmem[bank].end - vm_physmem[bank].start; + vm_physmem[bank].pmseg.pvent = pv; + vm_physmem[bank].pmseg.attrs = attr; + pv += npg; + attr += npg; + } + + /* * Allocate physical memory for kernel PT pages and their management. * we need enough pages to map the page tables for each process * plus some slop. @@ -524,8 +574,7 @@ pmap_init() * Verify that space will be allocated in region for which * we already have kernel PT pages. */ - addr = vm_map_min(kernel_map); - kernel_map->first_free = &kernel_map->header; /* XXX */ + addr = 0; rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)); @@ -561,56 +610,6 @@ pmap_init() #endif /* - * Allocate memory for random pmap data structures. Includes the - * initial segment table, pv_head_table and pmap_attributes. - */ - for (page_cnt = 0, bank = 0; bank < vm_nphysseg; bank++) { - page_cnt += vm_physmem[bank].end - vm_physmem[bank].start; -#ifdef DEBUG - printf("pmap_init: %2d: %08lx - %08lx (%10d)\n", bank, - vm_physmem[bank].start << PGSHIFT, - vm_physmem[bank].end << PGSHIFT, page_cnt << PGSHIFT); -#endif - } - s = ATARI_STSIZE; /* Segtabzero */ - s += page_cnt * sizeof(struct pv_entry); /* pv table */ - s += page_cnt * sizeof(char); /* attribute table */ - s = round_page(s); - - kernel_map->first_free = &kernel_map->header; - addr = uvm_km_zalloc(kernel_map, s); - if (addr == 0) - panic("pmap_init: can't allocate data structures"); - Segtabzero = (u_int *) addr; - (void) pmap_extract(pmap_kernel(), addr, (paddr_t *)&Segtabzeropa); - addr += ATARI_STSIZE; - pv_table = (pv_entry_t) addr; - addr += page_cnt * sizeof(struct pv_entry); - - pmap_attributes = (char *) addr; -#ifdef DEBUG - if (pmapdebug & PDB_INIT) - printf("pmap_init: %lx bytes: page_cnt %x s0 %p(%p) " - "tbl %p atr %p\n", - s, page_cnt, Segtabzero, Segtabzeropa, - pv_table, pmap_attributes); -#endif - - /* - * Now that the pv and attribute tables have been allocated, - * assign them to the memory segments. - */ - pv = pv_table; - attr = pmap_attributes; - for (bank = 0; bank < vm_nphysseg; bank++) { - npg = vm_physmem[bank].end - vm_physmem[bank].start; - vm_physmem[bank].pmseg.pvent = pv; - vm_physmem[bank].pmseg.attrs = attr; - pv += npg; - attr += npg; - } - - /* * Slightly modified version of kmem_suballoc() to get page table * map where we want it. */ @@ -628,7 +627,6 @@ pmap_init() } else s = maxproc * ATARI_UPTSIZE; - kernel_map->first_free = &kernel_map->header; pt_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, 0, TRUE, &pt_map_store); @@ -2638,6 +2636,23 @@ pmap_enter_ptpage(pmap, va) } /* + * Routine: pmap_virtual_space + * + * Function: + * Report the range of available kernel virtual address + * space to the VM system during bootstrap. Called by + * vm_bootstrap_steal_memory(). + */ +void +pmap_virtual_space(vstartp, vendp) + vaddr_t *vstartp, *vendp; +{ + + *vstartp = virtual_avail; + *vendp = virtual_end; +} + +/* * Routine: pmap_procwr * * Function: diff --git a/sys/arch/cesfic/cesfic/machdep.c b/sys/arch/cesfic/cesfic/machdep.c index 20efbf90e35..908ef2fcfab 100644 --- a/sys/arch/cesfic/cesfic/machdep.c +++ b/sys/arch/cesfic/cesfic/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.16 2003/05/08 18:13:15 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.17 2003/05/10 21:10:29 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -255,6 +255,7 @@ consinit() void cpu_startup() { + extern char *etext; caddr_t v; int i, base, residual; vaddr_t minaddr, maxaddr; @@ -354,6 +355,14 @@ cpu_startup() nbuf, bufpages * PAGE_SIZE); /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, KERNBASE, m68k_round_page(&etext), + UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) + panic("can't protect kernel text"); + + /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); diff --git a/sys/arch/hp300/hp300/machdep.c b/sys/arch/hp300/hp300/machdep.c index 7acd40e4f86..8271a052527 100644 --- a/sys/arch/hp300/hp300/machdep.c +++ b/sys/arch/hp300/hp300/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.167 2003/05/08 18:13:15 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.168 2003/05/10 21:10:29 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -43,7 +43,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.167 2003/05/08 18:13:15 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.168 2003/05/10 21:10:29 thorpej Exp $"); #include "opt_ddb.h" #include "opt_compat_hpux.h" @@ -285,6 +285,7 @@ consinit() void cpu_startup() { + extern char *etext; caddr_t v; u_int i, base, residual; vaddr_t minaddr, maxaddr; @@ -392,6 +393,26 @@ cpu_startup() printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that page 0 isn't mapped. + * + * XXX This is bogus; should just fix KERNBASE and + * XXX VM_MIN_KERNEL_ADDRESS, but not right now. + */ + if (uvm_map_protect(kernel_map, 0, PAGE_SIZE, UVM_PROT_NONE, TRUE) != 0) + panic("can't mark page 0 off-limits"); + + /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + * + * XXX Should be m68k_trunc_page(&kernel_text) instead + * XXX of PAGE_SIZE. + */ + if (uvm_map_protect(kernel_map, PAGE_SIZE, m68k_round_page(&etext), + UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) + panic("can't protect kernel text"); + + /* * Set up CPU-specific registers, cache, etc. */ initcpu(); diff --git a/sys/arch/hppa/hppa/pmap.c b/sys/arch/hppa/hppa/pmap.c index dcf7b51be10..85ccaaf2ed6 100644 --- a/sys/arch/hppa/hppa/pmap.c +++ b/sys/arch/hppa/hppa/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.7 2003/05/08 18:13:16 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.8 2003/05/10 21:10:30 thorpej Exp $ */ /*- * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -235,7 +235,7 @@ int pmapdebug = 0 #endif #define PMAP_PRINTF(v,x) PMAP_PRINTF_MASK(v,v,x) -vaddr_t virtual_steal; +vaddr_t virtual_steal, virtual_start, virtual_end; /* These two virtual pages are available for copying and zeroing. */ static vaddr_t tmp_vpages[2]; @@ -1054,7 +1054,7 @@ pmap_bootstrap(vstart, vend) * virtual space. */ *vstart = btlb_entry_start[btlb_j - 1] + btlb_entry_size[btlb_j - 1]; - virtual_avail = *vstart; + virtual_start = *vstart; /* * Finally, load physical pages into UVM. There are @@ -1106,19 +1106,27 @@ pmap_bootstrap(vstart, vend) * directly mapped cannot be grown dynamically once allocated. */ vaddr_t -pmap_steal_memory(size) +pmap_steal_memory(size, startp, endp) vsize_t size; + vaddr_t *startp; + vaddr_t *endp; { vaddr_t va; int lcv; PMAP_PRINTF(PDB_STEAL, ("(%lx, %p, %p)\n", size, startp, endp)); + /* Remind the caller of the start and end of virtual space. */ + if (startp) + *startp = virtual_start; + if (endp) + *endp = virtual_end; + /* Round the allocation up to a page. */ size = hppa_round_page(size); /* We must panic if we cannot steal the memory. */ - if (size > virtual_avail - virtual_steal) + if (size > virtual_start - virtual_steal) panic("pmap_steal_memory: out of memory"); /* Steal the memory. */ @@ -1137,6 +1145,17 @@ pmap_steal_memory(size) return va; } +/* + * How much virtual space does this kernel have? + * (After mapping kernel text, data, etc.) + */ +void +pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) +{ + *vstartp = virtual_start; + *vendp = virtual_end; +} + /* * Finishes the initialization of the pmap module. * This procedure is called from vm_mem_init() in vm/vm_init.c diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c index 76e0e8db884..a2be939071a 100644 --- a/sys/arch/i386/i386/pmap.c +++ b/sys/arch/i386/i386/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.153 2003/05/08 18:13:17 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.154 2003/05/10 21:10:31 thorpej Exp $ */ /* * @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.153 2003/05/08 18:13:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.154 2003/05/10 21:10:31 thorpej Exp $"); #include "opt_cputype.h" #include "opt_user_ldt.h" @@ -361,6 +361,17 @@ static pt_entry_t protection_codes[8]; /* maps MI prot to i386 prot code */ static boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ /* + * the following two vaddr_t's are used during system startup + * to keep track of how much of the kernel's VM space we have used. + * once the system is started, the management of the remaining kernel + * VM space is turned over to the kernel_map vm_map. + */ + +static vaddr_t virtual_avail; /* VA of first free KVA */ +static vaddr_t virtual_end; /* VA of last free KVA */ + + +/* * pv_page management structures: locked by pvalloc_lock */ @@ -809,8 +820,8 @@ pmap_bootstrap(kva_start) int i; /* - * define the boundaries of the managed kernel virtual address - * space. + * set up our local static global vars that keep track of the + * usage of KVM before kernel_map is set up */ virtual_avail = kva_start; /* first free KVA */ @@ -947,7 +958,7 @@ pmap_bootstrap(kva_start) pte += X86_MAXPROCS * NPTECL; #else csrcp = (caddr_t) virtual_avail; csrc_pte = pte; /* allocate */ - virtual_avail += PAGE_SIZE; pte++; /* advance */ + virtual_avail += PAGE_SIZE; pte++; /* advance */ cdstp = (caddr_t) virtual_avail; cdst_pte = pte; virtual_avail += PAGE_SIZE; pte++; @@ -1969,6 +1980,20 @@ vtophys(va) /* + * pmap_virtual_space: used during bootup [pmap_steal_memory] to + * determine the bounds of the kernel virtual addess space. + */ + +void +pmap_virtual_space(startp, endp) + vaddr_t *startp; + vaddr_t *endp; +{ + *startp = virtual_avail; + *endp = virtual_end; +} + +/* * pmap_map: map a range of PAs into kvm * * => used during crash dump diff --git a/sys/arch/luna68k/luna68k/machdep.c b/sys/arch/luna68k/luna68k/machdep.c index ab6398d8d08..599367c2dec 100644 --- a/sys/arch/luna68k/luna68k/machdep.c +++ b/sys/arch/luna68k/luna68k/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.29 2003/05/08 18:13:17 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.30 2003/05/10 21:10:32 thorpej Exp $ */ /*- * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ -__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.29 2003/05/08 18:13:17 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.30 2003/05/10 21:10:32 thorpej Exp $"); #include "opt_ddb.h" #include "opt_kgdb.h" @@ -101,6 +101,7 @@ char cpu_model[60]; struct cpu_info cpu_info_store; extern char kernel_text[]; +extern char etext[]; struct vm_map *exec_map = NULL; struct vm_map *mb_map = NULL; @@ -348,6 +349,26 @@ cpu_startup() printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that the area before the text segment + * is invalid. + * + * XXX Should just change KERNBASE and VM_MIN_KERNEL_ADDRESS, + * XXX but not right now. + */ + if (uvm_map_protect(kernel_map, 0, round_page((vaddr_t)&kernel_text), + UVM_PROT_NONE, TRUE) != 0) + panic("can't mark pre-text pages off-limits"); + + /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, trunc_page((vaddr_t)&kernel_text), + trunc_page((vaddr_t)&etext), UVM_PROT_READ|UVM_PROT_EXEC, TRUE) + != 0) + panic("can't protect kernel text"); + + /* * Set up buffers, so they can be used to read disk labels. */ bufinit(); diff --git a/sys/arch/m68k/m68k/pmap_motorola.c b/sys/arch/m68k/m68k/pmap_motorola.c index 013bb58bce0..1066f89b94f 100644 --- a/sys/arch/m68k/m68k/pmap_motorola.c +++ b/sys/arch/m68k/m68k/pmap_motorola.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap_motorola.c,v 1.4 2003/05/08 18:13:18 thorpej Exp $ */ +/* $NetBSD: pmap_motorola.c,v 1.5 2003/05/10 21:10:32 thorpej Exp $ */ /*- * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -128,7 +128,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.4 2003/05/08 18:13:18 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap_motorola.c,v 1.5 2003/05/10 21:10:32 thorpej Exp $"); #include "opt_compat_hpux.h" @@ -256,6 +256,8 @@ struct vm_map st_map_store, pt_map_store; paddr_t avail_start; /* PA of first available physical page */ paddr_t avail_end; /* PA of last available physical page */ vsize_t mem_size; /* memory size in bytes */ +vaddr_t virtual_avail; /* VA of first avail page (after kernel bss)*/ +vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ int page_cnt; /* number of pages managed by VM system */ boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */ @@ -329,6 +331,26 @@ void pmap_check_wiring __P((char *, vaddr_t)); #define PRM_KEEPPTPAGE 0x04 /* + * pmap_virtual_space: [ INTERFACE ] + * + * Report the range of available kernel virtual address + * space to the VM system during bootstrap. + * + * This is only an interface function if we do not use + * pmap_steal_memory()! + * + * Note: no locking is necessary in this function. + */ +void +pmap_virtual_space(vstartp, vendp) + vaddr_t *vstartp, *vendp; +{ + + *vstartp = virtual_avail; + *vendp = virtual_end; +} + +/* * pmap_init: [ INTERFACE ] * * Initialize the pmap module. Called by vm_init(), to initialize any @@ -385,53 +407,6 @@ pmap_init() avail_start, avail_end, virtual_avail, virtual_end)); /* - * Allocate physical memory for kernel PT pages and their management. - * We need 1 PT page per possible task plus some slop. - */ - npages = min(atop(M68K_MAX_KPTSIZE), maxproc+16); - s = ptoa(npages) + round_page(npages * sizeof(struct kpt_page)); - - /* - * Verify that space will be allocated in region for which - * we already have kernel PT pages. - */ - addr = vm_map_min(kernel_map); - kernel_map->first_free = &kernel_map->header; /* XXX */ - rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET, 0, - UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, - UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)); - if (rv != 0) - panic("pmap_init: uvm_map of KPT array failed: %d", rv); - if ((addr + s) >= (vaddr_t)Sysmap) - panic("pmap_init: initial kernel PT too small for KPT array " - "(0x%lx - 0x%lx)", addr, s); - uvm_unmap(kernel_map, addr, addr + s); - - /* - * Now allocate the space and link the pages together to - * form the KPT free list. - */ - kernel_map->first_free = &kernel_map->header; /* XXX */ - addr = uvm_km_zalloc(kernel_map, s); - if (addr == 0) - panic("pmap_init: cannot allocate KPT free list"); - s = ptoa(npages); - addr2 = addr + s; - kpt_pages = &((struct kpt_page *)addr2)[npages]; - kpt_free_list = NULL; - do { - addr2 -= PAGE_SIZE; - (--kpt_pages)->kpt_next = kpt_free_list; - kpt_free_list = kpt_pages; - kpt_pages->kpt_va = addr2; - (void) pmap_extract(pmap_kernel(), addr2, - (paddr_t *)&kpt_pages->kpt_pa); - } while (addr != addr2); - - PMAP_DPRINTF(PDB_INIT, ("pmap_init: KPT: %ld pages from %lx to %lx\n", - atop(s), addr, addr + s)); - - /* * Allocate memory for random pmap data structures. Includes the * initial segment table, pv_head_table and pmap_attributes. */ @@ -441,7 +416,6 @@ pmap_init() s += page_cnt * sizeof(struct pv_entry); /* pv table */ s += page_cnt * sizeof(char); /* attribute table */ s = round_page(s); - kernel_map->first_free = &kernel_map->header; /* XXX */ addr = uvm_km_zalloc(kernel_map, s); if (addr == 0) panic("pmap_init: can't allocate data structures"); @@ -475,10 +449,51 @@ pmap_init() } /* + * Allocate physical memory for kernel PT pages and their management. + * We need 1 PT page per possible task plus some slop. + */ + npages = min(atop(M68K_MAX_KPTSIZE), maxproc+16); + s = ptoa(npages) + round_page(npages * sizeof(struct kpt_page)); + + /* + * Verify that space will be allocated in region for which + * we already have kernel PT pages. + */ + addr = 0; + rv = uvm_map(kernel_map, &addr, s, NULL, UVM_UNKNOWN_OFFSET, 0, + UVM_MAPFLAG(UVM_PROT_NONE, UVM_PROT_NONE, UVM_INH_NONE, + UVM_ADV_RANDOM, UVM_FLAG_NOMERGE)); + if (rv != 0 || (addr + s) >= (vaddr_t)Sysmap) + panic("pmap_init: kernel PT too small"); + uvm_unmap(kernel_map, addr, addr + s); + + /* + * Now allocate the space and link the pages together to + * form the KPT free list. + */ + addr = uvm_km_zalloc(kernel_map, s); + if (addr == 0) + panic("pmap_init: cannot allocate KPT free list"); + s = ptoa(npages); + addr2 = addr + s; + kpt_pages = &((struct kpt_page *)addr2)[npages]; + kpt_free_list = NULL; + do { + addr2 -= PAGE_SIZE; + (--kpt_pages)->kpt_next = kpt_free_list; + kpt_free_list = kpt_pages; + kpt_pages->kpt_va = addr2; + (void) pmap_extract(pmap_kernel(), addr2, + (paddr_t *)&kpt_pages->kpt_pa); + } while (addr != addr2); + + PMAP_DPRINTF(PDB_INIT, ("pmap_init: KPT: %ld pages from %lx to %lx\n", + atop(s), addr, addr + s)); + + /* * Allocate the segment table map and the page table map. */ s = maxproc * M68K_STSIZE; - kernel_map->first_free = &kernel_map->header; /* XXX */ st_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, 0, FALSE, &st_map_store); @@ -494,7 +509,6 @@ pmap_init() maxproc = (M68K_PTMAXSIZE / M68K_MAX_PTSIZE); } else s = (maxproc * M68K_MAX_PTSIZE); - kernel_map->first_free = &kernel_map->header; /* XXX */ pt_map = uvm_km_suballoc(kernel_map, &addr, &addr2, s, 0, TRUE, &pt_map_store); diff --git a/sys/arch/mac68k/mac68k/machdep.c b/sys/arch/mac68k/mac68k/machdep.c index 34dd3fb2b70..dd5ea13d643 100644 --- a/sys/arch/mac68k/mac68k/machdep.c +++ b/sys/arch/mac68k/mac68k/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.287 2003/05/08 18:13:18 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.288 2003/05/10 21:10:32 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -382,6 +382,8 @@ consinit(void) void cpu_startup(void) { + extern char *start; + extern char *etext; caddr_t v; int vers; u_int i, base, residual; @@ -495,6 +497,19 @@ cpu_startup(void) printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + * + * XXX I'd like this to be m68k_trunc_page(&kernel_text) instead + * XXX of the reference to &start, but we have to keep the + * XXX interrupt vectors and such writable for the Mac toolbox. + */ + if (uvm_map_protect(kernel_map, + m68k_trunc_page(&start + (PAGE_SIZE - 1)), m68k_round_page(&etext), + (UVM_PROT_READ | UVM_PROT_EXEC), TRUE) != 0) + panic("can't protect kernel text"); + + /* * Set up CPU-specific registers, cache, etc. */ initcpu(); diff --git a/sys/arch/mips/mips/pmap.c b/sys/arch/mips/mips/pmap.c index 36794adb492..f4405ea950b 100644 --- a/sys/arch/mips/mips/pmap.c +++ b/sys/arch/mips/mips/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.147 2003/05/08 18:13:19 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.148 2003/05/10 21:10:33 thorpej Exp $ */ /*- * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. @@ -78,7 +78,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.147 2003/05/08 18:13:19 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.148 2003/05/10 21:10:33 thorpej Exp $"); /* * Manages physical address maps. @@ -190,6 +190,7 @@ struct pmap kernel_pmap_store; paddr_t avail_start; /* PA of first available physical page */ paddr_t avail_end; /* PA of last available physical page */ +vaddr_t virtual_end; /* VA of last avail page (end of kernel AS) */ struct pv_entry *pv_table; int pv_table_npages; @@ -330,13 +331,6 @@ pmap_bootstrap() */ avail_start = ptoa(vm_physmem[0].start); avail_end = ptoa(vm_physmem[vm_nphysseg - 1].end); - - /* - * Note: we can't grow the kernel pmap, so the end of the - * managed kernel virtual address space is defined by how - * large we make the initial sysmap. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; virtual_end = VM_MIN_KERNEL_ADDRESS + Sysmapsize * NBPG; /* @@ -400,6 +394,17 @@ pmap_bootstrap() } /* + * Define the initial bounds of the kernel virtual address space. + */ +void +pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) +{ + + *vstartp = VM_MIN_KERNEL_ADDRESS; /* kernel is in K0SEG */ + *vendp = trunc_page(virtual_end); /* XXX need pmap_growkernel() */ +} + +/* * Bootstrap memory allocator (alternative to vm_bootstrap_steal_memory()). * This function allows for early dynamic memory allocation until the virtual * memory system has been bootstrapped. After that point, either kmem_alloc @@ -414,10 +419,14 @@ pmap_bootstrap() * * Note that this memory will never be freed, and in essence it is wired * down. + * + * We must adjust *vstartp and/or *vendp iff we use address space + * from the kernel virtual address range defined by pmap_virtual_space(). */ vaddr_t -pmap_steal_memory(size) +pmap_steal_memory(size, vstartp, vendp) vsize_t size; + vaddr_t *vstartp, *vendp; { int bank, x; u_int npgs; diff --git a/sys/arch/mvme68k/mvme68k/machdep.c b/sys/arch/mvme68k/mvme68k/machdep.c index fe7be7206d2..6d2d3815451 100644 --- a/sys/arch/mvme68k/mvme68k/machdep.c +++ b/sys/arch/mvme68k/mvme68k/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.99 2003/05/08 18:13:19 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.100 2003/05/10 21:10:34 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -430,6 +430,7 @@ consinit() void cpu_startup() { + extern char *kernel_text, *etext; caddr_t v; u_int i, base, residual; u_quad_t vmememsize; @@ -552,6 +553,26 @@ cpu_startup() printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that the area before the text segment + * is invalid. + * + * XXX Should just change KERNBASE and VM_MIN_KERNEL_ADDRESS, + * XXX but not right now. + */ + if (uvm_map_protect(kernel_map, 0, round_page((vaddr_t)&kernel_text), + UVM_PROT_NONE, TRUE) != 0) + panic("can't mark pre-text pages off-limits"); + + /* + * Tell the VM system that writing to the kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, trunc_page((vaddr_t)&kernel_text), + round_page((vaddr_t)&etext), UVM_PROT_READ|UVM_PROT_EXEC, TRUE) + != 0) + panic("can't protect kernel text"); + + /* * Set up CPU-specific registers, cache, etc. */ initcpu(); diff --git a/sys/arch/news68k/news68k/machdep.c b/sys/arch/news68k/news68k/machdep.c index 329474a48f7..87f58defed5 100644 --- a/sys/arch/news68k/news68k/machdep.c +++ b/sys/arch/news68k/news68k/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.39 2003/05/08 18:13:20 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.40 2003/05/10 21:10:34 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -117,6 +117,7 @@ int physmem = MAXMEM; /* max supported memory, changes to actual */ int safepri = PSL_LOWIPL; extern paddr_t avail_start, avail_end; +extern char *kernel_text, *etext; extern int end, *esym; extern u_int lowram; @@ -314,6 +315,25 @@ cpu_startup() printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that the area before the text segment + * is invalid. + * + * XXX This is bogus; should just fix KERNBASE and + * XXX VM_MIN_KERNEL_ADDRESS, but not right now. + */ + if (uvm_map_protect(kernel_map, 0, m68k_round_page(&kernel_text), + UVM_PROT_NONE, TRUE) != 0) + panic("can't mark pre-text pages off-limits"); + + /* + * Tell the VM system that writing to the kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, m68k_trunc_page(&kernel_text), + m68k_round_page(&etext), UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) + panic("can't protect kernel text"); + + /* * Set up CPU-specific registers, cache, etc. */ initcpu(); diff --git a/sys/arch/next68k/next68k/machdep.c b/sys/arch/next68k/next68k/machdep.c index 7ebc191e1fd..7856d30aac9 100644 --- a/sys/arch/next68k/next68k/machdep.c +++ b/sys/arch/next68k/next68k/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.58 2003/05/08 18:13:20 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.59 2003/05/10 21:10:35 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -283,6 +283,7 @@ consinit() void cpu_startup() { + extern char *kernel_text, *etext; caddr_t v; u_int i, base, residual; vaddr_t minaddr, maxaddr; @@ -390,6 +391,26 @@ cpu_startup() printf("using %u buffers containing %s of memory\n", nbuf, pbuf); /* + * Tell the VM system that the area before the text segment + * is invalid. + * + * XXX Should just change KERNBASE and VM_MIN_KERNEL_ADDRESS, + * XXX but not right now. + */ + if (uvm_map_protect(kernel_map, 0, round_page((vaddr_t)&kernel_text), + UVM_PROT_NONE, TRUE) != 0) + panic("can't mark pre-text pages off-limits"); + + /* + * Tell the VM system that writing to the kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, trunc_page((vaddr_t)&kernel_text), + round_page((vaddr_t)&etext), UVM_PROT_READ|UVM_PROT_EXEC, TRUE) + != 0) + panic("can't protect kernel text"); + + /* * Set up CPU-specific registers, cache, etc. */ initcpu(); diff --git a/sys/arch/pc532/pc532/machdep.c b/sys/arch/pc532/pc532/machdep.c index 08da93a83ac..aa78bfb583d 100644 --- a/sys/arch/pc532/pc532/machdep.c +++ b/sys/arch/pc532/pc532/machdep.c @@ -1,4 +1,4 @@ -/* $NetBSD: machdep.c,v 1.139 2003/05/08 18:13:20 thorpej Exp $ */ +/* $NetBSD: machdep.c,v 1.140 2003/05/10 21:10:35 thorpej Exp $ */ /*- * Copyright (c) 1996 Matthias Pfaller. @@ -148,6 +148,7 @@ static void map __P((pd_entry_t *, vaddr_t, paddr_t, int, int)); void cpu_startup() { + extern char kernel_text[]; caddr_t v; int sz; u_int i, base, residual; @@ -247,6 +248,16 @@ cpu_startup() mb_map = uvm_km_suballoc(kernel_map, &minaddr, &maxaddr, nmbclusters * mclbytes, VM_MAP_INTRSAFE, FALSE, NULL); + /* + * Tell the VM system that writing to kernel text isn't allowed. + * If we don't, we might end up COW'ing the text segment! + */ + if (uvm_map_protect(kernel_map, + ns532_round_page(&kernel_text), + ns532_round_page(&etext), + UVM_PROT_READ|UVM_PROT_EXEC, TRUE) != 0) + panic("can't protect kernel text"); + format_bytes(pbuf, sizeof(pbuf), ptoa(uvmexp.free)); printf("avail memory = %s\n", pbuf); format_bytes(pbuf, sizeof(pbuf), bufpages * PAGE_SIZE); diff --git a/sys/arch/pc532/pc532/pmap.c b/sys/arch/pc532/pc532/pmap.c index 21eb78462dd..75c744a845c 100644 --- a/sys/arch/pc532/pc532/pmap.c +++ b/sys/arch/pc532/pc532/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.71 2003/05/08 18:13:21 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.72 2003/05/10 21:10:36 thorpej Exp $ */ /* * @@ -281,6 +281,17 @@ static pt_entry_t protection_codes[8]; /* maps MI prot to ns532 prot code */ static boolean_t pmap_initialized = FALSE; /* pmap_init done yet? */ /* + * the following two vaddr_t's are used during system startup + * to keep track of how much of the kernel's VM space we have used. + * once the system is started, the management of the remaining kernel + * VM space is turned over to the kernel_map vm_map. + */ + +static vaddr_t virtual_avail; /* VA of first free KVA */ +static vaddr_t virtual_end; /* VA of last free KVA */ + + +/* * pv_page management structures: locked by pvalloc_lock */ @@ -634,8 +645,8 @@ pmap_bootstrap(kva_start) msgbuf_paddr = avail_end; /* - * define the boundaries of the managed kernel virtual address - * space. + * set up our local static global vars that keep track of the + * usage of KVM before kernel_map is set up */ virtual_avail = kva_start; /* first free KVA */ @@ -1557,6 +1568,20 @@ vtophys(va) /* + * pmap_virtual_space: used during bootup [pmap_steal_memory] to + * determine the bounds of the kernel virtual addess space. + */ + +void +pmap_virtual_space(startp, endp) + vaddr_t *startp; + vaddr_t *endp; +{ + *startp = virtual_avail; + *endp = virtual_end; +} + +/* * pmap_map: map a range of PAs into kvm * * => used during crash dump diff --git a/sys/arch/powerpc/ibm4xx/pmap.c b/sys/arch/powerpc/ibm4xx/pmap.c index ead681c7d08..11fb1f9bf46 100644 --- a/sys/arch/powerpc/ibm4xx/pmap.c +++ b/sys/arch/powerpc/ibm4xx/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.20 2003/05/08 18:13:21 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.21 2003/05/10 21:10:36 thorpej Exp $ */ /* * Copyright 2001 Wasabi Systems, Inc. @@ -386,12 +386,6 @@ pmap_bootstrap(u_int kernelstart, u_int kernelend) pmap_kernel()->pm_ctx = KERNEL_PID; nextavail = avail->start; - /* - * Define the boundaries of the managed kernel virtual - * address space. - */ - virtual_avail = (vaddr_t) VM_MIN_KERNEL_ADDRESS; - virtual_end = (vaddr_t) VM_MAX_KERNEL_ADDRESS; evcnt_attach_static(&tlbhit_ev); evcnt_attach_static(&tlbmiss_ev); @@ -466,6 +460,25 @@ pmap_init(void) pool_init(&pv_pool, sizeof(struct pv_entry), 0, 0, 0, "pv_entry", NULL); } +/* + * How much virtual space is available to the kernel? + */ +void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + +#if 0 + /* + * Reserve one segment for kernel virtual memory + */ + *start = (vaddr_t)(KERNEL_SR << ADDR_SR_SHFT); + *end = *start + SEGMENT_LENGTH; +#else + *start = (vaddr_t) VM_MIN_KERNEL_ADDRESS; + *end = (vaddr_t) VM_MAX_KERNEL_ADDRESS; +#endif +} + #ifdef PMAP_GROWKERNEL /* * Preallocate kernel page tables to a specified VA. diff --git a/sys/arch/powerpc/oea/pmap.c b/sys/arch/powerpc/oea/pmap.c index 5e889b59da7..e0489730cc3 100644 --- a/sys/arch/powerpc/oea/pmap.c +++ b/sys/arch/powerpc/oea/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.9 2003/05/08 18:13:22 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.10 2003/05/10 21:10:37 thorpej Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -1020,6 +1020,20 @@ pmap_init(void) } /* + * How much virtual space does the kernel get? + */ +void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + /* + * For now, reserve one segment (minus some overhead) for kernel + * virtual memory + */ + *start = VM_MIN_KERNEL_ADDRESS; + *end = VM_MAX_KERNEL_ADDRESS; +} + +/* * Allocate, initialize, and return a new physical map. */ pmap_t @@ -2531,7 +2545,7 @@ pmap_pool_mfree(struct pool *pp, void *va) * pmap needs and above 256MB for other stuff. */ vaddr_t -pmap_steal_memory(vsize_t vsize) +pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp) { vsize_t size; vaddr_t va; @@ -2542,6 +2556,9 @@ pmap_steal_memory(vsize_t vsize) if (uvm.page_init_done == TRUE) panic("pmap_steal_memory: called _after_ bootstrap"); + *vstartp = VM_MIN_KERNEL_ADDRESS; + *vendp = VM_MAX_KERNEL_ADDRESS; + size = round_page(vsize); npgs = atop(size); @@ -2719,14 +2736,6 @@ pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend) int i, j; /* - * Define the boundaries of the managed kernel virtual address - * space. For now, reserve one segment (minus some overhead) - * for kernel virtual memory. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; - virtual_end = VM_MAX_KERNEL_ADDRESS; - - /* * Get memory. */ mem_regions(&mem, &avail); diff --git a/sys/arch/sh3/sh3/pmap.c b/sys/arch/sh3/sh3/pmap.c index 9f1e47b668a..aebeecc67af 100644 --- a/sys/arch/sh3/sh3/pmap.c +++ b/sys/arch/sh3/sh3/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.44 2003/05/08 18:13:22 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.45 2003/05/10 21:10:37 thorpej Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -105,13 +105,6 @@ pmap_bootstrap() size_t sz; caddr_t v; - /* - * Define the boundaries of the kernel virtual address - * space. - */ - virtual_avail = VM_MIN_KERNEL_ADDRESS; - virtual_end = VM_MAX_KERNEL_ADDRESS; - /* Steal msgbuf area */ initmsgbuf((caddr_t)uvm_pageboot_alloc(MSGBUFSIZE), MSGBUFSIZE); @@ -138,7 +131,7 @@ pmap_bootstrap() } vaddr_t -pmap_steal_memory(vsize_t size) +pmap_steal_memory(vsize_t size, vaddr_t *vstart, vaddr_t *vend) { struct vm_physseg *bank; int i, j, npage; @@ -215,6 +208,14 @@ pmap_growkernel(vaddr_t maxkvaddr) } void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + + *start = VM_MIN_KERNEL_ADDRESS; + *end = VM_MAX_KERNEL_ADDRESS; +} + +void pmap_init() { diff --git a/sys/arch/sh5/sh5/pmap.c b/sys/arch/sh5/sh5/pmap.c index 1fc2d637cda..048b97f86c9 100644 --- a/sys/arch/sh5/sh5/pmap.c +++ b/sys/arch/sh5/sh5/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.32 2003/05/08 18:13:23 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.33 2003/05/10 21:10:38 thorpej Exp $ */ /* * Copyright 2002 Wasabi Systems, Inc. @@ -218,8 +218,7 @@ PMSTR(pmap_t pm) * * E0000000 - FFFFFFFF (KSEG1) * KSEG1 is basically the `managed' kernel virtual address space - * as reported to uvm(9) by the setting of virtual_avail and - * virtual_end in pmap_bootstrap(). + * as reported to uvm(9) by pmap_virtual_space(). * * It uses regular TLB mappings, but backed by a dedicated IPT * with 1-1 V2Phys PTELs. The IPT will be up to 512KB (for NEFF=32) @@ -1146,12 +1145,6 @@ pmap_bootstrap(vaddr_t avail, paddr_t kseg0base, struct mem_region *mr) pmap_kva_avail_start = pmap_device_kva_start + PMAP_BOOTSTRAP_DEVICE_KVA; - /* - * Define the bounaries of the kernel virtual address space. - */ - virtual_avail = pmap_kva_avail_start; - virtual_end = SH5_KSEG1_BASE + ((KERNEL_IPT_SIZE - 1) * PAGE_SIZE); - pmap_asid_next = PMAP_ASID_USER_START; pmap_asid_max = SH5_PTEH_ASID_MASK; /* XXX Should be cpu specific */ @@ -1267,6 +1260,17 @@ pmap_init(void) } /* + * How much virtual space does the kernel get? + */ +void +pmap_virtual_space(vaddr_t *start, vaddr_t *end) +{ + + *start = pmap_kva_avail_start; + *end = SH5_KSEG1_BASE + ((KERNEL_IPT_SIZE - 1) * PAGE_SIZE); +} + +/* * Allocate, initialize, and return a new physical map. */ pmap_t @@ -2952,7 +2956,7 @@ pmap_pool_ufree(struct pool *pp, void *va) } vaddr_t -pmap_steal_memory(vsize_t vsize) +pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp) { vsize_t size; vaddr_t va; diff --git a/sys/arch/sparc/include/pmap.h b/sys/arch/sparc/include/pmap.h index 29040382273..c06cb89035b 100644 --- a/sys/arch/sparc/include/pmap.h +++ b/sys/arch/sparc/include/pmap.h @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.h,v 1.67 2003/05/08 18:13:23 thorpej Exp $ */ +/* $NetBSD: pmap.h,v 1.68 2003/05/10 21:10:40 thorpej Exp $ */ /* * Copyright (c) 1996 @@ -264,6 +264,7 @@ paddr_t pmap_phys_address __P((int)); void pmap_reference __P((pmap_t)); void pmap_remove __P((pmap_t, vaddr_t, vaddr_t)); #define pmap_update(pmap) /* nothing (yet) */ +void pmap_virtual_space __P((vaddr_t *, vaddr_t *)); void pmap_redzone __P((void)); void kvm_uncache __P((caddr_t, int)); struct user; diff --git a/sys/arch/sparc/sparc/pmap.c b/sys/arch/sparc/sparc/pmap.c index 5ede4bcf191..49963055fdc 100644 --- a/sys/arch/sparc/sparc/pmap.c +++ b/sys/arch/sparc/sparc/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.252 2003/05/08 18:13:24 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.253 2003/05/10 21:10:40 thorpej Exp $ */ /* * Copyright (c) 1996 @@ -405,6 +405,8 @@ static paddr_t avail_start; /* first available physical page, other than the `etext gap' defined below */ static vaddr_t etext_gap_start;/* start of gap between text & data */ static vaddr_t etext_gap_end; /* end of gap between text & data */ +static vaddr_t virtual_avail; /* first free kernel virtual address */ +static vaddr_t virtual_end; /* last free kernel virtual address */ static void pmap_page_upload(void); @@ -1009,6 +1011,19 @@ get_phys_mem(caddr_t *top) */ /* + * How much virtual space does this kernel have? + * (After mapping kernel text, data, etc.) + */ +void +pmap_virtual_space(v_start, v_end) + vaddr_t *v_start; + vaddr_t *v_end; +{ + *v_start = virtual_avail; + *v_end = virtual_end; +} + +/* * Helper routine that hands off available physical pages to the VM system. */ static void @@ -3120,9 +3135,6 @@ pmap_bootstrap4_4c(top, nctx, nregion, nsegment) vmmap = p, p += NBPG; p = reserve_dumppages(p); - /* - * Define the bounds of the managed kernel virtual address space. - */ virtual_avail = (vaddr_t)p; virtual_end = VM_MAX_KERNEL_ADDRESS; @@ -3578,9 +3590,6 @@ pmap_bootstrap4m(top) &sp->sg_pte[VA_SUN4M_VPG(cpuinfo.vpage[i])]; } - /* - * Define the bounds of the managed kernel virtual address space. - */ virtual_avail = (vaddr_t)p; virtual_end = VM_MAX_KERNEL_ADDRESS; diff --git a/sys/arch/sun2/sun2/pmap.c b/sys/arch/sun2/sun2/pmap.c index b0a4267e106..075f92596d2 100644 --- a/sys/arch/sun2/sun2/pmap.c +++ b/sys/arch/sun2/sun2/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.21 2003/05/08 18:13:25 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.22 2003/05/10 21:10:41 thorpej Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -197,6 +197,7 @@ int pmap_db_watchpmeg = -1; * These are set in pmap_bootstrap() and used in * pmap_next_page(). */ +vaddr_t virtual_avail, virtual_end; paddr_t avail_start, avail_end; #define managed(pa) (((pa) >= avail_start) && ((pa) < avail_end)) @@ -1783,6 +1784,19 @@ pmap_kernel_init(pmap) * Support functions for vm_page_bootstrap(). */ +/* + * How much virtual space does this kernel have? + * (After mapping kernel text, data, etc.) + */ +void +pmap_virtual_space(v_start, v_end) + vaddr_t *v_start; + vaddr_t *v_end; +{ + *v_start = virtual_avail; + *v_end = virtual_end; +} + /* Provide memory to the VM system. */ static void pmap_page_upload() diff --git a/sys/arch/sun3/sun3/pmap.c b/sys/arch/sun3/sun3/pmap.c index 89798d7dec4..f18200c5865 100644 --- a/sys/arch/sun3/sun3/pmap.c +++ b/sys/arch/sun3/sun3/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.141 2003/05/08 18:13:25 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.142 2003/05/10 21:10:41 thorpej Exp $ */ /*- * Copyright (c) 1996 The NetBSD Foundation, Inc. @@ -206,6 +206,7 @@ int pmap_db_watchpmeg = -1; * These are set in pmap_bootstrap() and used in * pmap_next_page(). */ +vaddr_t virtual_avail, virtual_end; paddr_t avail_start, avail_end; #define managed(pa) (((pa) >= avail_start) && ((pa) < avail_end)) @@ -1812,6 +1813,19 @@ pmap_kernel_init(pmap) * Support functions for vm_page_bootstrap(). */ +/* + * How much virtual space does this kernel have? + * (After mapping kernel text, data, etc.) + */ +void +pmap_virtual_space(v_start, v_end) + vaddr_t *v_start; + vaddr_t *v_end; +{ + *v_start = virtual_avail; + *v_end = virtual_end; +} + /* Provide memory to the VM system. */ static void pmap_page_upload() diff --git a/sys/arch/sun3/sun3x/pmap.c b/sys/arch/sun3/sun3x/pmap.c index d1aca6a20dd..96241747800 100644 --- a/sys/arch/sun3/sun3x/pmap.c +++ b/sys/arch/sun3/sun3x/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.80 2003/05/08 18:13:26 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.81 2003/05/10 21:10:42 thorpej Exp $ */ /*- * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc. @@ -272,6 +272,8 @@ int tmp_vpages_inuse; /* Temporary virtual pages are in use */ * XXX: For now, retain the traditional variables that were * used in the old pmap/vm interface (without NONCONTIG). */ +/* Kernel virtual address space available: */ +vaddr_t virtual_avail, virtual_end; /* Physical address space available: */ paddr_t avail_start, avail_end; @@ -3511,6 +3513,19 @@ pmap_kcore_hdr(sh) } +/* pmap_virtual_space INTERFACE + ** + * Return the current available range of virtual addresses in the + * arguuments provided. Only really called once. + */ +void +pmap_virtual_space(vstart, vend) + vaddr_t *vstart, *vend; +{ + *vstart = virtual_avail; + *vend = virtual_end; +} + /* * Provide memory to the VM system. * diff --git a/sys/arch/vax/vax/pmap.c b/sys/arch/vax/vax/pmap.c index 25f78042a5c..4e5b5af4b64 100644 --- a/sys/arch/vax/vax/pmap.c +++ b/sys/arch/vax/vax/pmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: pmap.c,v 1.126 2003/05/08 18:13:27 thorpej Exp $ */ +/* $NetBSD: pmap.c,v 1.127 2003/05/10 21:10:43 thorpej Exp $ */ /* * Copyright (c) 1994, 1998, 1999, 2003 Ludd, University of Lule}, Sweden. * All rights reserved. @@ -179,6 +179,7 @@ int startpmapdebug = 0; #endif paddr_t avail_start, avail_end; +vaddr_t virtual_avail, virtual_end; /* Available virtual memory */ struct pv_entry *get_pventry(void); void free_pventry(struct pv_entry *); @@ -288,9 +289,6 @@ pmap_bootstrap() * amount of physical memory also, therefore sysptsize is * a variable here that is changed dependent of the physical * memory size. - * - * Note that setting virtual_avail/virtual_end defines the - * boundaries of the managed kernel virtual address space. */ virtual_avail = avail_end + KERNBASE; virtual_end = KERNBASE + sysptsize * VAX_NBPG; @@ -419,17 +417,30 @@ pmap_bootstrap() } /* + * Define the initial bounds of the kernel virtual address space. + */ +void +pmap_virtual_space(vaddr_t *vstartp, vaddr_t *vendp) +{ + + *vstartp = virtual_avail; + *vendp = virtual_end; +} + +/* * Let the VM system do early memory allocation from the direct-mapped * physical memory instead. */ vaddr_t -pmap_steal_memory(size) +pmap_steal_memory(size, vstartp, vendp) vsize_t size; + vaddr_t *vstartp, *vendp; { vaddr_t v; int npgs; - PMDEBUG(("pmap_steal_memory: size 0x%lx\n", size)); + PMDEBUG(("pmap_steal_memory: size 0x%lx start %p end %p\n", + size, vstartp, vendp)); size = round_page(size); npgs = btoc(size); diff --git a/sys/uvm/uvm_extern.h b/sys/uvm/uvm_extern.h index 1d8d8f3289f..7648a51bb26 100644 --- a/sys/uvm/uvm_extern.h +++ b/sys/uvm/uvm_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_extern.h,v 1.79 2003/05/08 18:13:27 thorpej Exp $ */ +/* $NetBSD: uvm_extern.h,v 1.80 2003/05/10 21:10:23 thorpej Exp $ */ /* * @@ -504,16 +504,6 @@ extern struct vm_map *mb_map; extern struct vm_map *phys_map; /* - * these variables define the boundaries of the managed kernel virtual - * address space. they are initialized by machine-dependent code during - * bootstrap. note that before kernel virtual memory is initialized, - * some address space might be "stolen" during bootstrap. anything that - * steals address space must update these variables accordingly. - */ -extern vaddr_t virtual_avail; -extern vaddr_t virtual_end; - -/* * macros */ diff --git a/sys/uvm/uvm_init.c b/sys/uvm/uvm_init.c index 75703704bc2..7e2f8092723 100644 --- a/sys/uvm/uvm_init.c +++ b/sys/uvm/uvm_init.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_init.c,v 1.17 2003/05/08 18:13:28 thorpej Exp $ */ +/* $NetBSD: uvm_init.c,v 1.18 2003/05/10 21:10:23 thorpej Exp $ */ /* * @@ -39,7 +39,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_init.c,v 1.17 2003/05/08 18:13:28 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_init.c,v 1.18 2003/05/10 21:10:23 thorpej Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -72,6 +72,7 @@ struct uvmexp uvmexp; /* decl */ void uvm_init() { + vaddr_t kvm_start, kvm_end; /* * step 0: ensure that the hardware set the page size @@ -92,9 +93,11 @@ uvm_init() * step 2: init the page sub-system. this includes allocating the * vm_page structures, and setting up all the page queues (and * locks). available memory will be put in the "free" queue. + * kvm_start and kvm_end will be set to the area of kernel virtual + * memory which is available for general use. */ - uvm_page_init(); + uvm_page_init(&kvm_start, &kvm_end); /* * step 3: init the map sub-system. allocates the static pool of @@ -110,7 +113,7 @@ uvm_init() * kmem_object. */ - uvm_km_init(); + uvm_km_init(kvm_start, kvm_end); /* * step 5: init the pmap module. the pmap module is free to allocate @@ -152,7 +155,8 @@ uvm_init() */ uvm_page_rehash(); - uao_create(virtual_end - virtual_avail, UAO_FLAG_KERNSWAP); + uao_create(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS, + UAO_FLAG_KERNSWAP); /* * done! diff --git a/sys/uvm/uvm_km.c b/sys/uvm/uvm_km.c index fc202b18dd5..d902633f6d7 100644 --- a/sys/uvm/uvm_km.c +++ b/sys/uvm/uvm_km.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_km.c,v 1.61 2003/05/08 18:13:28 thorpej Exp $ */ +/* $NetBSD: uvm_km.c,v 1.62 2003/05/10 21:10:23 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -74,8 +74,8 @@ * overview of kernel memory management: * * the kernel virtual address space is mapped by "kernel_map." kernel_map - * starts at virtual_avail and goes to virtual_end. note that virtual_avail - * is equal to vm_map_min(kernel_map). + * starts at VM_MIN_KERNEL_ADDRESS and goes to VM_MAX_KERNEL_ADDRESS. + * note that VM_MIN_KERNEL_ADDRESS is equal to vm_map_min(kernel_map). * * the kernel_map has several "submaps." submaps can only appear in * the kernel_map (user processes can't use them). submaps "take over" @@ -102,8 +102,8 @@ * reference count is set to UVM_OBJ_KERN (thus indicating that the objects * are "special" and never die). all kernel objects should be thought of * as large, fixed-sized, sparsely populated uvm_objects. each kernel - * object is equal to the size of managed kernel virtual address space (i.e. - * the value "virtual_end - virtual_avail"). + * object is equal to the size of kernel virtual address space (i.e. the + * value "VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS"). * * most kernel private memory lives in kernel_object. the only exception * to this is for memory that belongs to submaps that must be protected @@ -118,9 +118,9 @@ * offsets that are managed by the submap. * * note that the "offset" in a kernel object is always the kernel virtual - * address minus virtual_avail (aka vm_map_min(kernel_map)). + * address minus the VM_MIN_KERNEL_ADDRESS (aka vm_map_min(kernel_map)). * example: - * suppose virtual_avail is 0xf8000000 and the kernel does a + * suppose VM_MIN_KERNEL_ADDRESS is 0xf8000000 and the kernel does a * uvm_km_alloc(kernel_map, PAGE_SIZE) [allocate 1 wired down page in the * kernel map]. if uvm_km_alloc returns virtual address 0xf8235000, * then that means that the page at offset 0x235000 in kernel_object is @@ -134,7 +134,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.61 2003/05/08 18:13:28 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.62 2003/05/10 21:10:23 thorpej Exp $"); #include "opt_uvmhist.h" @@ -148,9 +148,6 @@ __KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.61 2003/05/08 18:13:28 thorpej Exp $"); * global data structures */ -vaddr_t virtual_avail; /* start of managed kernel virtual memory */ -vaddr_t virtual_end; /* end of managed kernel virtual memory */ - struct vm_map *kernel_map = NULL; /* @@ -163,22 +160,16 @@ static struct vm_map kernel_map_store; * uvm_km_init: init kernel maps and objects to reflect reality (i.e. * KVM already allocated for text, data, bss, and static data structures). * - * => KVM is defined by virtual_avail/virtual_end. - * we assume that any regions that have already been allocated from - * the total kernel address space have already been accounted for in - * the values of virtual_avail and virtual_end. + * => KVM is defined by VM_MIN_KERNEL_ADDRESS/VM_MAX_KERNEL_ADDRESS. + * we assume that [min -> start] has already been allocated and that + * "end" is the end. */ void -uvm_km_init(void) +uvm_km_init(start, end) + vaddr_t start, end; { - - /* - * virtual_avail and virtual_end should already be page-aligned. - */ - - KASSERT((virtual_avail & PAGE_MASK) == 0); - KASSERT((virtual_end & PAGE_MASK) == 0); + vaddr_t base = VM_MIN_KERNEL_ADDRESS; /* * next, init kernel memory objects. @@ -186,17 +177,22 @@ uvm_km_init(void) /* kernel_object: for pageable anonymous kernel memory */ uao_init(); - uvm.kernel_object = uao_create(virtual_end - virtual_avail, - UAO_FLAG_KERNOBJ); + uvm.kernel_object = uao_create(VM_MAX_KERNEL_ADDRESS - + VM_MIN_KERNEL_ADDRESS, UAO_FLAG_KERNOBJ); /* * init the map and reserve any space that might already * have been allocated kernel space before installing. */ - uvm_map_setup(&kernel_map_store, virtual_avail, virtual_end, - VM_MAP_PAGEABLE); + uvm_map_setup(&kernel_map_store, base, end, VM_MAP_PAGEABLE); kernel_map_store.pmap = pmap_kernel(); + if (start != base && + uvm_map(&kernel_map_store, &base, start - base, NULL, + UVM_UNKNOWN_OFFSET, 0, + UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_NONE, + UVM_ADV_RANDOM, UVM_FLAG_FIXED)) != 0) + panic("uvm_km_init: could not reserve space for kernel"); /* * install! diff --git a/sys/uvm/uvm_km.h b/sys/uvm/uvm_km.h index 3fba97e9c48..6b93f1a10bb 100644 --- a/sys/uvm/uvm_km.h +++ b/sys/uvm/uvm_km.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_km.h,v 1.11 2003/05/08 18:13:28 thorpej Exp $ */ +/* $NetBSD: uvm_km.h,v 1.12 2003/05/10 21:10:23 thorpej Exp $ */ /* * @@ -47,7 +47,7 @@ * prototypes */ -void uvm_km_init __P((void)); +void uvm_km_init __P((vaddr_t, vaddr_t)); void uvm_km_pgremove __P((struct uvm_object *, vaddr_t, vaddr_t)); void uvm_km_pgremove_intrsafe __P((vaddr_t, vaddr_t)); diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 871b99f7f49..6b10b084b71 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.c,v 1.87 2003/05/08 18:13:28 thorpej Exp $ */ +/* $NetBSD: uvm_page.c,v 1.88 2003/05/10 21:10:23 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.87 2003/05/08 18:13:28 thorpej Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_page.c,v 1.88 2003/05/10 21:10:23 thorpej Exp $"); #include "opt_uvmhist.h" @@ -113,6 +113,15 @@ boolean_t vm_page_zero_enable = FALSE; */ /* + * these variables record the values returned by vm_page_bootstrap, + * for debugging purposes. The implementation of uvm_pageboot_alloc + * and pmap_startup here also uses them internally. + */ + +static vaddr_t virtual_space_start; +static vaddr_t virtual_space_end; + +/* * we use a hash table with only one bucket during bootup. we will * later rehash (resize) the hash table once the allocator is ready. * we static allocate the one bootstrap bucket below... @@ -233,7 +242,8 @@ uvm_page_init_buckets(struct pgfreelist *pgfl) */ void -uvm_page_init(void) +uvm_page_init(kvm_startp, kvm_endp) + vaddr_t *kvm_startp, *kvm_endp; { vsize_t freepages, pagecount, bucketcount, n; struct pgflbucket *bucketarray; @@ -355,6 +365,15 @@ uvm_page_init(void) } /* + * pass up the values of virtual_space_start and + * virtual_space_end (obtained by uvm_pageboot_alloc) to the upper + * layers of the VM. + */ + + *kvm_startp = round_page(virtual_space_start); + *kvm_endp = trunc_page(virtual_space_end); + + /* * init locks for kernel threads */ @@ -439,17 +458,11 @@ uvm_pageboot_alloc(size) * on first call to this function, initialize ourselves. */ if (initialized == FALSE) { - /* - * make sure machine-dependent code has initialized our - * virtual address space boundaries properly. - */ - if (virtual_end <= virtual_avail) - panic("uvm_pageboot_alloc: MD code did not init " - "KVA boundaries"); + pmap_virtual_space(&virtual_space_start, &virtual_space_end); /* round it the way we like it */ - virtual_avail = round_page(virtual_avail); - virtual_end = trunc_page(virtual_end); + virtual_space_start = round_page(virtual_space_start); + virtual_space_end = trunc_page(virtual_space_end); initialized = TRUE; } @@ -462,10 +475,11 @@ uvm_pageboot_alloc(size) /* * defer bootstrap allocation to MD code (it may want to allocate * from a direct-mapped segment). pmap_steal_memory should adjust - * virtual_avail/virtual_end if necessary. + * virtual_space_start/virtual_space_end if necessary. */ - addr = pmap_steal_memory(size); + addr = pmap_steal_memory(size, &virtual_space_start, + &virtual_space_end); return(addr); @@ -474,11 +488,11 @@ uvm_pageboot_alloc(size) /* * allocate virtual memory for this request */ - if (virtual_avail == virtual_end || - (virtual_end - virtual_avail) < size) + if (virtual_space_start == virtual_space_end || + (virtual_space_end - virtual_space_start) < size) panic("uvm_pageboot_alloc: out of virtual space"); - addr = virtual_avail; + addr = virtual_space_start; #ifdef PMAP_GROWKERNEL /* @@ -492,7 +506,7 @@ uvm_pageboot_alloc(size) } #endif - virtual_avail += size; + virtual_space_start += size; /* * allocate and mapin physical pages to back new virtual pages diff --git a/sys/uvm/uvm_page.h b/sys/uvm/uvm_page.h index 251bc3eb809..e5eaac76146 100644 --- a/sys/uvm/uvm_page.h +++ b/sys/uvm/uvm_page.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_page.h,v 1.33 2003/05/08 18:13:29 thorpej Exp $ */ +/* $NetBSD: uvm_page.h,v 1.34 2003/05/10 21:10:24 thorpej Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -263,7 +263,7 @@ extern int vm_nphysseg; * prototypes: the following prototypes define the interface to pages */ -void uvm_page_init __P((void)); +void uvm_page_init __P((vaddr_t *, vaddr_t *)); #if defined(UVM_PAGE_TRKOWN) void uvm_page_own __P((struct vm_page *, char *)); #endif diff --git a/sys/uvm/uvm_pmap.h b/sys/uvm/uvm_pmap.h index 777be5f31e8..f8cdf1f7fe8 100644 --- a/sys/uvm/uvm_pmap.h +++ b/sys/uvm/uvm_pmap.h @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_pmap.h,v 1.13 2003/05/08 18:13:29 thorpej Exp $ */ +/* $NetBSD: uvm_pmap.h,v 1.14 2003/05/10 21:10:24 thorpej Exp $ */ /* * Copyright (c) 1991, 1993 @@ -163,8 +163,9 @@ long pmap_wired_count __P((pmap_t)); void pmap_zero_page __P((paddr_t)); #endif +void pmap_virtual_space __P((vaddr_t *, vaddr_t *)); #if defined(PMAP_STEAL_MEMORY) -vaddr_t pmap_steal_memory __P((vsize_t)); +vaddr_t pmap_steal_memory __P((vsize_t, vaddr_t *, vaddr_t *)); #endif #if defined(PMAP_FORK) |
