source: mainline/kernel/generic/include/mm/as.h@ 17aca1c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 17aca1c was 0b37882, checked in by Martin Decky <martin@…>, 15 years ago

memory management work

  • implement as_get_mappable_page() as a new syscall (SYS_AS_GET_UNMAPPED_AREA), the kernel has a full knowledge of the address space areas, there is no need to duplicate this management in uspace)
  • make sure all address space/address space area manipulating functions use proper page alignment on base addresses and sizes (discrepancy with respect to this caused inconsistent behaviour, although no fatal bugs were probably present)
  • add forgotten tests (area != avoid) to check_area_conflicts()
  • unify size/page conversions (use always use bitwise shifts by PAGE_WIDTH)
  • new uspace heap allocator
    • basic next fit algorithm for better scalability (there is still space for optimizations)
    • support for multiple discontinuous heap areas (inspired by Jiri Tlach's implementation in lp:~jiri-tlach/helenos/nommu, but independent)
    • the "_heap" linker script symbol has been removed, the initial heap area is allocated according to as_get_mappable_page() (which uses the address of entry as the lower bound of the address space area base)
    • the hardwired 1 GB (4 GB respectivelly) heap size limit has been removed
    • the heap areas can be freely intermixed with other address space areas (e.g. mapped physical memory of devices, shared memory, etc.), the address space holes can be reused later (but still merging of adjunct address space areas is missing)
  • minor cstyle changes
  • Property mode set to 100644
File size: 8.6 KB
Line 
1/*
2 * Copyright (c) 2010 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup genericmm
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_AS_H_
36#define KERN_AS_H_
37
38#ifdef KERNEL
39 #include <typedefs.h>
40#else
41 #include <sys/types.h>
42#endif
43
44/** Address space area flags. */
45#define AS_AREA_READ 1
46#define AS_AREA_WRITE 2
47#define AS_AREA_EXEC 4
48#define AS_AREA_CACHEABLE 8
49
50/** Address space area info exported to userspace. */
51typedef struct {
52 /** Starting address */
53 uintptr_t start_addr;
54
55 /** Area size */
56 size_t size;
57
58 /** Area flags */
59 unsigned int flags;
60} as_area_info_t;
61
62#ifdef KERNEL
63
64#include <arch/mm/page.h>
65#include <arch/mm/as.h>
66#include <arch/mm/asid.h>
67#include <typedefs.h>
68#include <synch/spinlock.h>
69#include <synch/mutex.h>
70#include <adt/list.h>
71#include <adt/btree.h>
72#include <lib/elf.h>
73
74/**
75 * Defined to be true if user address space and kernel address space shadow each
76 * other.
77 *
78 */
79#define KERNEL_ADDRESS_SPACE_SHADOWED KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
80
81#define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
82#define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
83#define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
84#define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
85
86#define USTACK_ADDRESS USTACK_ADDRESS_ARCH
87
88/** Kernel address space. */
89#define FLAG_AS_KERNEL (1 << 0)
90
91/* Address space area attributes. */
92#define AS_AREA_ATTR_NONE 0
93#define AS_AREA_ATTR_PARTIAL 1 /**< Not fully initialized area. */
94
95/** The page fault was not resolved by as_page_fault(). */
96#define AS_PF_FAULT 0
97
98/** The page fault was resolved by as_page_fault(). */
99#define AS_PF_OK 1
100
101/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
102#define AS_PF_DEFER 2
103
104/** Address space structure.
105 *
106 * as_t contains the list of as_areas of userspace accessible
107 * pages for one or more tasks. Ranges of kernel memory pages are not
108 * supposed to figure in the list as they are shared by all tasks and
109 * set up during system initialization.
110 *
111 */
112typedef struct as {
113 /** Protected by asidlock. */
114 link_t inactive_as_with_asid_link;
115
116 /**
117 * Number of processors on which this
118 * address space is active. Protected by
119 * asidlock.
120 */
121 size_t cpu_refcount;
122
123 /** Address space identifier.
124 *
125 * Constant on architectures that do not
126 * support ASIDs. Protected by asidlock.
127 *
128 */
129 asid_t asid;
130
131 /** Number of references (i.e. tasks that reference this as). */
132 atomic_t refcount;
133
134 mutex_t lock;
135
136 /** B+tree of address space areas. */
137 btree_t as_area_btree;
138
139 /** Non-generic content. */
140 as_genarch_t genarch;
141
142 /** Architecture specific content. */
143 as_arch_t arch;
144} as_t;
145
146typedef struct {
147 pte_t *(* page_table_create)(unsigned int);
148 void (* page_table_destroy)(pte_t *);
149 void (* page_table_lock)(as_t *, bool);
150 void (* page_table_unlock)(as_t *, bool);
151 bool (* page_table_locked)(as_t *);
152} as_operations_t;
153
154/**
155 * This structure contains information associated with the shared address space
156 * area.
157 *
158 */
159typedef struct {
160 /** This lock must be acquired only when the as_area lock is held. */
161 mutex_t lock;
162 /** This structure can be deallocated if refcount drops to 0. */
163 size_t refcount;
164
165 /**
166 * B+tree containing complete map of anonymous pages of the shared area.
167 */
168 btree_t pagemap;
169} share_info_t;
170
171/** Page fault access type. */
172typedef enum {
173 PF_ACCESS_READ,
174 PF_ACCESS_WRITE,
175 PF_ACCESS_EXEC,
176 PF_ACCESS_UNKNOWN
177} pf_access_t;
178
179struct mem_backend;
180
181/** Backend data stored in address space area. */
182typedef union mem_backend_data {
183 /** elf_backend members */
184 struct {
185 elf_header_t *elf;
186 elf_segment_header_t *segment;
187 };
188
189 /** phys_backend members */
190 struct {
191 uintptr_t base;
192 size_t frames;
193 };
194} mem_backend_data_t;
195
196/** Address space area structure.
197 *
198 * Each as_area_t structure describes one contiguous area of virtual memory.
199 *
200 */
201typedef struct {
202 mutex_t lock;
203
204 /** Containing address space. */
205 as_t *as;
206
207 /** Memory flags. */
208 unsigned int flags;
209
210 /** Address space area attributes. */
211 unsigned int attributes;
212
213 /** Number of pages in the area. */
214 size_t pages;
215
216 /** Number of resident pages in the area. */
217 size_t resident;
218
219 /** Base address of this area. */
220 uintptr_t base;
221
222 /** Map of used space. */
223 btree_t used_space;
224
225 /**
226 * If the address space area is shared. this is
227 * a reference to the share info structure.
228 */
229 share_info_t *sh_info;
230
231 /** Memory backend backing this address space area. */
232 struct mem_backend *backend;
233
234 /** Data to be used by the backend. */
235 mem_backend_data_t backend_data;
236} as_area_t;
237
238/** Address space area backend structure. */
239typedef struct mem_backend {
240 int (* page_fault)(as_area_t *, uintptr_t, pf_access_t);
241 void (* frame_free)(as_area_t *, uintptr_t, uintptr_t);
242 void (* share)(as_area_t *);
243} mem_backend_t;
244
245extern as_t *AS_KERNEL;
246
247extern as_operations_t *as_operations;
248extern link_t inactive_as_with_asid_head;
249
250extern void as_init(void);
251
252extern as_t *as_create(unsigned int);
253extern void as_destroy(as_t *);
254extern void as_hold(as_t *);
255extern void as_release(as_t *);
256extern void as_switch(as_t *, as_t *);
257extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
258
259extern as_area_t *as_area_create(as_t *, unsigned int, size_t, uintptr_t,
260 unsigned int, mem_backend_t *, mem_backend_data_t *);
261extern int as_area_destroy(as_t *, uintptr_t);
262extern int as_area_resize(as_t *, uintptr_t, size_t, unsigned int);
263extern int as_area_share(as_t *, uintptr_t, size_t, as_t *, uintptr_t,
264 unsigned int);
265extern int as_area_change_flags(as_t *, unsigned int, uintptr_t);
266
267extern unsigned int as_area_get_flags(as_area_t *);
268extern bool as_area_check_access(as_area_t *, pf_access_t);
269extern size_t as_area_get_size(uintptr_t);
270extern bool used_space_insert(as_area_t *, uintptr_t, size_t);
271extern bool used_space_remove(as_area_t *, uintptr_t, size_t);
272
273/* Interface to be implemented by architectures. */
274
275#ifndef as_constructor_arch
276extern int as_constructor_arch(as_t *, unsigned int);
277#endif /* !def as_constructor_arch */
278
279#ifndef as_destructor_arch
280extern int as_destructor_arch(as_t *);
281#endif /* !def as_destructor_arch */
282
283#ifndef as_create_arch
284extern int as_create_arch(as_t *, unsigned int);
285#endif /* !def as_create_arch */
286
287#ifndef as_install_arch
288extern void as_install_arch(as_t *);
289#endif /* !def as_install_arch */
290
291#ifndef as_deinstall_arch
292extern void as_deinstall_arch(as_t *);
293#endif /* !def as_deinstall_arch */
294
295/* Backend declarations and functions. */
296extern mem_backend_t anon_backend;
297extern mem_backend_t elf_backend;
298extern mem_backend_t phys_backend;
299
300/**
301 * This flags is passed when running the loader, otherwise elf_load()
302 * would return with a EE_LOADER error code.
303 *
304 */
305#define ELD_F_NONE 0
306#define ELD_F_LOADER 1
307
308extern unsigned int elf_load(elf_header_t *, as_t *, unsigned int);
309
310/* Address space area related syscalls. */
311extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int);
312extern sysarg_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
313extern sysarg_t sys_as_area_change_flags(uintptr_t, unsigned int);
314extern sysarg_t sys_as_area_destroy(uintptr_t);
315extern sysarg_t sys_as_get_unmapped_area(uintptr_t, size_t);
316
317/* Introspection functions. */
318extern void as_get_area_info(as_t *, as_area_info_t **, size_t *);
319extern void as_print(as_t *);
320
321#endif /* KERNEL */
322
323#endif
324
325/** @}
326 */
Note: See TracBrowser for help on using the repository browser.