xref: /openbsd/sys/uvm/uvm_init.c (revision 52887a38)
1*52887a38Smpi /*	$OpenBSD: uvm_init.c,v 1.42 2021/03/20 10:24:21 mpi Exp $	*/
23a40dae1Sart /*	$NetBSD: uvm_init.c,v 1.14 2000/06/27 17:29:23 mrg Exp $	*/
3cd7ee8acSart 
4cd7ee8acSart /*
5cd7ee8acSart  * Copyright (c) 1997 Charles D. Cranor and Washington University.
6cd7ee8acSart  * All rights reserved.
7cd7ee8acSart  *
8cd7ee8acSart  * Redistribution and use in source and binary forms, with or without
9cd7ee8acSart  * modification, are permitted provided that the following conditions
10cd7ee8acSart  * are met:
11cd7ee8acSart  * 1. Redistributions of source code must retain the above copyright
12cd7ee8acSart  *    notice, this list of conditions and the following disclaimer.
13cd7ee8acSart  * 2. Redistributions in binary form must reproduce the above copyright
14cd7ee8acSart  *    notice, this list of conditions and the following disclaimer in the
15cd7ee8acSart  *    documentation and/or other materials provided with the distribution.
16cd7ee8acSart  *
17cd7ee8acSart  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18cd7ee8acSart  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19cd7ee8acSart  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20cd7ee8acSart  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21cd7ee8acSart  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22cd7ee8acSart  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23cd7ee8acSart  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24cd7ee8acSart  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25cd7ee8acSart  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26cd7ee8acSart  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27cd7ee8acSart  *
28cd7ee8acSart  * from: Id: uvm_init.c,v 1.1.2.3 1998/02/06 05:15:27 chs Exp
29cd7ee8acSart  */
30cd7ee8acSart 
31cd7ee8acSart /*
32cd7ee8acSart  * uvm_init.c: init the vm system.
33cd7ee8acSart  */
34cd7ee8acSart 
35cd7ee8acSart #include <sys/param.h>
36cd7ee8acSart #include <sys/systm.h>
37cd7ee8acSart #include <sys/filedesc.h>
38627a59d1Smpi #include <sys/percpu.h>
39cd7ee8acSart #include <sys/resourcevar.h>
40cd7ee8acSart #include <sys/mman.h>
41cd7ee8acSart #include <sys/malloc.h>
42cd7ee8acSart #include <sys/vnode.h>
437cfce8f0Sderaadt #include <sys/pool.h>
44cd7ee8acSart 
45cd7ee8acSart #include <uvm/uvm.h>
46181c6205Sariane #include <uvm/uvm_addr.h>
47cd7ee8acSart 
48cd7ee8acSart /*
49cd7ee8acSart  * struct uvm: we store all global vars in this structure to make them
50cd7ee8acSart  * easier to spot...
51cd7ee8acSart  */
52cd7ee8acSart 
53cd7ee8acSart struct uvm uvm;		/* decl */
54cd7ee8acSart struct uvmexp uvmexp;	/* decl */
55cd7ee8acSart 
56627a59d1Smpi COUNTERS_BOOT_MEMORY(uvmexp_countersboot, exp_ncounters);
57627a59d1Smpi struct cpumem *uvmexp_counters = COUNTERS_BOOT_INITIALIZER(uvmexp_countersboot);
58627a59d1Smpi 
595de1d0f0Smiod #if defined(VM_MIN_KERNEL_ADDRESS)
605de1d0f0Smiod vaddr_t vm_min_kernel_address = VM_MIN_KERNEL_ADDRESS;
615de1d0f0Smiod #else
625de1d0f0Smiod vaddr_t vm_min_kernel_address;
635de1d0f0Smiod #endif
645de1d0f0Smiod 
65cd7ee8acSart /*
66cd7ee8acSart  * local prototypes
67cd7ee8acSart  */
68cd7ee8acSart 
69cd7ee8acSart /*
70cd7ee8acSart  * uvm_init: init the VM system.   called from kern/init_main.c.
71cd7ee8acSart  */
72*52887a38Smpi 
73cd7ee8acSart void
uvm_init(void)742023d591Soga uvm_init(void)
75cd7ee8acSart {
76cd7ee8acSart 	vaddr_t kvm_start, kvm_end;
77cd7ee8acSart 
78*52887a38Smpi 	/*
79*52887a38Smpi 	 * Ensure that the hardware set the page size.
80*52887a38Smpi 	 */
81cd7ee8acSart 	if (uvmexp.pagesize == 0) {
82cd7ee8acSart 		panic("uvm_init: page size not set");
83cd7ee8acSart 	}
84cd7ee8acSart 	averunnable.fscale = FSCALE;
85cd7ee8acSart 
86cd7ee8acSart 	/*
87*52887a38Smpi 	 * Init the page sub-system.  This includes allocating the vm_page
88*52887a38Smpi 	 * structures, and setting up all the page queues (and locks).
89*52887a38Smpi 	 * Available memory will be put in the "free" queue, kvm_start and
90*52887a38Smpi 	 * kvm_end will be set to the area of kernel virtual memory which
91*52887a38Smpi 	 * is available for general use.
92cd7ee8acSart 	 */
93cd7ee8acSart 	uvm_page_init(&kvm_start, &kvm_end);
94cd7ee8acSart 
95cd7ee8acSart 	/*
96*52887a38Smpi 	 * Init the map sub-system.
97*52887a38Smpi 	 *
98*52887a38Smpi 	 * Allocates the static pool of vm_map_entry structures that are
99*52887a38Smpi 	 * used for "special" kernel maps (e.g. kernel_map, kmem_map, etc...).
100cd7ee8acSart 	 */
101cd7ee8acSart 	uvm_map_init();
102cd7ee8acSart 
103cd7ee8acSart 	/*
104*52887a38Smpi 	 * Setup the kernel's virtual memory data structures.  This includes
105*52887a38Smpi 	 * setting up the kernel_map/kernel_object.
106cd7ee8acSart 	 */
1075de1d0f0Smiod 	uvm_km_init(vm_min_kernel_address, kvm_start, kvm_end);
108cd7ee8acSart 
109cd7ee8acSart 	/*
1101c7ad6bdSmiod 	 * step 4.5: init (tune) the fault recovery code.
1111c7ad6bdSmiod 	 */
1121c7ad6bdSmiod 	uvmfault_init();
1131c7ad6bdSmiod 
1141c7ad6bdSmiod 	/*
115*52887a38Smpi 	 * Init the pmap module.  The pmap module is free to allocate
116cd7ee8acSart 	 * memory for its private use (e.g. pvlists).
117cd7ee8acSart 	 */
118cd7ee8acSart 	pmap_init();
119cd7ee8acSart 
120cd7ee8acSart 	/*
12118b79dc7Sdlg 	 * step 6: init uvm_km_page allocator memory.
12218b79dc7Sdlg 	 */
12318b79dc7Sdlg 	uvm_km_page_init();
12418b79dc7Sdlg 
12518b79dc7Sdlg 	/*
126*52887a38Smpi 	 * Make kernel memory allocators ready for use.
127*52887a38Smpi 	 * After this call the malloc memory allocator can be used.
128cd7ee8acSart 	 */
129cd7ee8acSart 	kmeminit();
130cd7ee8acSart 
131cd7ee8acSart 	/*
13218b79dc7Sdlg 	 * step 7.5: init the dma allocator, which is backed by pools.
13372570117Sderaadt 	 */
13472570117Sderaadt 	dma_alloc_init();
13572570117Sderaadt 
13672570117Sderaadt 	/*
137*52887a38Smpi 	 * Init all pagers and the pager_map.
138cd7ee8acSart 	 */
139cd7ee8acSart 	uvm_pager_init();
140cd7ee8acSart 
141cd7ee8acSart 	/*
14218b79dc7Sdlg 	 * step 9: init anonymous memory system
143cd7ee8acSart 	 */
14435164244Stedu 	amap_init();
145cd7ee8acSart 
146cd7ee8acSart 	/*
14718b79dc7Sdlg 	 * step 10: start uvm_km_page allocator thread.
1485aad79a8Skurt 	 */
14918b79dc7Sdlg 	uvm_km_page_lateinit();
1505aad79a8Skurt 
1515aad79a8Skurt 	/*
1527bcb8cc6Soga 	 * the VM system is now up!  now that malloc is up we can
1537bcb8cc6Soga 	 * enable paging of kernel objects.
154cd7ee8acSart 	 */
1555de1d0f0Smiod 	uao_create(VM_KERNEL_SPACE_SIZE, UAO_FLAG_KERNSWAP);
156cd7ee8acSart 
157cd7ee8acSart 	/*
15897bf7b32Smiod 	 * reserve some unmapped space for malloc/pool use after free usage
15997bf7b32Smiod 	 */
16097bf7b32Smiod #ifdef DEADBEEF0
1615ce612feSart 	kvm_start = trunc_page(DEADBEEF0) - PAGE_SIZE;
16297bf7b32Smiod 	if (uvm_map(kernel_map, &kvm_start, 3 * PAGE_SIZE,
1631e8cdc2eSderaadt 	    NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(PROT_NONE,
16415cd8707Sguenther 	    PROT_NONE, MAP_INHERIT_NONE, MADV_RANDOM, UVM_FLAG_FIXED)))
165859d5ed4Skrw 		panic("uvm_init: cannot reserve dead beef @0x%x", DEADBEEF0);
16697bf7b32Smiod #endif
16797bf7b32Smiod #ifdef DEADBEEF1
1685ce612feSart 	kvm_start = trunc_page(DEADBEEF1) - PAGE_SIZE;
16997bf7b32Smiod 	if (uvm_map(kernel_map, &kvm_start, 3 * PAGE_SIZE,
1701e8cdc2eSderaadt 	    NULL, UVM_UNKNOWN_OFFSET, 0, UVM_MAPFLAG(PROT_NONE,
17115cd8707Sguenther 	    PROT_NONE, MAP_INHERIT_NONE, MADV_RANDOM, UVM_FLAG_FIXED)))
172859d5ed4Skrw 		panic("uvm_init: cannot reserve dead beef @0x%x", DEADBEEF1);
17397bf7b32Smiod #endif
17497bf7b32Smiod 	/*
175*52887a38Smpi 	 * Init anonymous memory systems.
176cd7ee8acSart 	 */
1778d0b5bafSpedro 	uvm_anon_init();
178181c6205Sariane 
17959399f65Sariane #ifndef SMALL_KERNEL
180181c6205Sariane 	/*
181181c6205Sariane 	 * Switch kernel and kmem_map over to a best-fit allocator,
182181c6205Sariane 	 * instead of walking the tree.
183181c6205Sariane 	 */
184181c6205Sariane 	uvm_map_set_uaddr(kernel_map, &kernel_map->uaddr_any[3],
185181c6205Sariane 	    uaddr_bestfit_create(vm_map_min(kernel_map),
186181c6205Sariane 	    vm_map_max(kernel_map)));
187181c6205Sariane 	uvm_map_set_uaddr(kmem_map, &kmem_map->uaddr_any[3],
188181c6205Sariane 	    uaddr_bestfit_create(vm_map_min(kmem_map),
189181c6205Sariane 	    vm_map_max(kmem_map)));
19059399f65Sariane #endif /* !SMALL_KERNEL */
191cd7ee8acSart }
192627a59d1Smpi 
193627a59d1Smpi void
uvm_init_percpu(void)194627a59d1Smpi uvm_init_percpu(void)
195627a59d1Smpi {
196627a59d1Smpi 	uvmexp_counters = counters_alloc_ncpus(uvmexp_counters, exp_ncounters);
197627a59d1Smpi }
198