source: mainline/kernel/generic/include/mm/as.h@ 879585a3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 879585a3 was 879585a3, checked in by Jakub Jermar <jakub@…>, 18 years ago

Simplify synchronization in as_switch().
The function was oversynchronized, which
was causing deadlocks on the address
space mutex.

Now, address spaces can only be switched
when the asidlock is held. This also protects
stealing of ASIDs. No other synchronization
is necessary.

  • Property mode set to 100644
File size: 8.9 KB
Line 
1/*
2 * Copyright (c) 2001-2004 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/** Address space area flags. */
39#define AS_AREA_READ 1
40#define AS_AREA_WRITE 2
41#define AS_AREA_EXEC 4
42#define AS_AREA_CACHEABLE 8
43
44#ifdef KERNEL
45
46#include <arch/mm/page.h>
47#include <arch/mm/as.h>
48#include <arch/mm/asid.h>
49#include <arch/types.h>
50#include <synch/spinlock.h>
51#include <synch/mutex.h>
52#include <adt/list.h>
53#include <adt/btree.h>
54#include <lib/elf.h>
55
56#ifdef __OBJC__
57#include <lib/objc.h>
58#endif
59
60/**
61 * Defined to be true if user address space and kernel address space shadow each
62 * other.
63 */
64#define KERNEL_ADDRESS_SPACE_SHADOWED KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
65
66#define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
67#define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
68#define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
69#define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
70
71#define USTACK_ADDRESS USTACK_ADDRESS_ARCH
72
73/** Kernel address space. */
74#define FLAG_AS_KERNEL (1 << 0)
75
76/* Address space area attributes. */
77#define AS_AREA_ATTR_NONE 0
78#define AS_AREA_ATTR_PARTIAL 1 /**< Not fully initialized area. */
79
80/** The page fault was not resolved by as_page_fault(). */
81#define AS_PF_FAULT 0
82/** The page fault was resolved by as_page_fault(). */
83#define AS_PF_OK 1
84/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
85#define AS_PF_DEFER 2
86
87#ifdef __OBJC__
88@interface as_t : base_t {
89 @public
90 /** Protected by asidlock. */
91 link_t inactive_as_with_asid_link;
92 /**
93 * Number of processors on wich is this address space active.
94 * Protected by asidlock.
95 */
96 count_t cpu_refcount;
97 /**
98 * Address space identifier.
99 * Constant on architectures that do not support ASIDs.
100 * Protected by asidlock.
101 */
102 asid_t asid;
103
104 mutex_t lock;
105
106 /** Number of references (i.e tasks that reference this as). */
107 count_t refcount;
108
109 /** B+tree of address space areas. */
110 btree_t as_area_btree;
111
112 /** Non-generic content. */
113 as_genarch_t genarch;
114
115 /** Architecture specific content. */
116 as_arch_t arch;
117}
118
119+ (pte_t *) page_table_create: (int) flags;
120+ (void) page_table_destroy: (pte_t *) page_table;
121- (void) page_table_lock: (bool) _lock;
122- (void) page_table_unlock: (bool) unlock;
123
124@end
125
126#else
127
128/** Address space structure.
129 *
130 * as_t contains the list of as_areas of userspace accessible
131 * pages for one or more tasks. Ranges of kernel memory pages are not
132 * supposed to figure in the list as they are shared by all tasks and
133 * set up during system initialization.
134 */
135typedef struct as {
136 /** Protected by asidlock. */
137 link_t inactive_as_with_asid_link;
138 /**
139 * Number of processors on wich is this address space active.
140 * Protected by asidlock.
141 */
142 count_t cpu_refcount;
143 /**
144 * Address space identifier.
145 * Constant on architectures that do not support ASIDs.
146 * Protected by asidlock.
147 */
148 asid_t asid;
149
150 mutex_t lock;
151
152 /** Number of references (i.e tasks that reference this as). */
153 count_t refcount;
154
155 /** B+tree of address space areas. */
156 btree_t as_area_btree;
157
158 /** Non-generic content. */
159 as_genarch_t genarch;
160
161 /** Architecture specific content. */
162 as_arch_t arch;
163} as_t;
164
165typedef struct {
166 pte_t *(* page_table_create)(int flags);
167 void (* page_table_destroy)(pte_t *page_table);
168 void (* page_table_lock)(as_t *as, bool lock);
169 void (* page_table_unlock)(as_t *as, bool unlock);
170} as_operations_t;
171#endif
172
173/**
174 * This structure contains information associated with the shared address space
175 * area.
176 */
177typedef struct {
178 /** This lock must be acquired only when the as_area lock is held. */
179 mutex_t lock;
180 /** This structure can be deallocated if refcount drops to 0. */
181 count_t refcount;
182 /**
183 * B+tree containing complete map of anonymous pages of the shared area.
184 */
185 btree_t pagemap;
186} share_info_t;
187
188/** Page fault access type. */
189typedef enum {
190 PF_ACCESS_READ,
191 PF_ACCESS_WRITE,
192 PF_ACCESS_EXEC
193} pf_access_t;
194
195struct mem_backend;
196
197/** Backend data stored in address space area. */
198typedef union mem_backend_data {
199 struct { /**< elf_backend members */
200 elf_header_t *elf;
201 elf_segment_header_t *segment;
202 };
203 struct { /**< phys_backend members */
204 uintptr_t base;
205 count_t frames;
206 };
207} mem_backend_data_t;
208
209/** Address space area structure.
210 *
211 * Each as_area_t structure describes one contiguous area of virtual memory.
212 */
213typedef struct {
214 mutex_t lock;
215 /** Containing address space. */
216 as_t *as;
217 /**
218 * Flags related to the memory represented by the address space area.
219 */
220 int flags;
221 /** Attributes related to the address space area itself. */
222 int attributes;
223 /** Size of this area in multiples of PAGE_SIZE. */
224 count_t pages;
225 /** Base address of this area. */
226 uintptr_t base;
227 /** Map of used space. */
228 btree_t used_space;
229
230 /**
231 * If the address space area has been shared, this pointer will
232 * reference the share info structure.
233 */
234 share_info_t *sh_info;
235
236 /** Memory backend backing this address space area. */
237 struct mem_backend *backend;
238
239 /** Data to be used by the backend. */
240 mem_backend_data_t backend_data;
241} as_area_t;
242
243/** Address space area backend structure. */
244typedef struct mem_backend {
245 int (* page_fault)(as_area_t *area, uintptr_t addr, pf_access_t access);
246 void (* frame_free)(as_area_t *area, uintptr_t page, uintptr_t frame);
247 void (* share)(as_area_t *area);
248} mem_backend_t;
249
250extern as_t *AS_KERNEL;
251
252#ifndef __OBJC__
253extern as_operations_t *as_operations;
254#endif
255
256extern link_t inactive_as_with_asid_head;
257
258extern void as_init(void);
259
260extern as_t *as_create(int flags);
261extern void as_destroy(as_t *as);
262extern void as_switch(as_t *old_as, as_t *new_as);
263extern int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate);
264
265extern as_area_t *as_area_create(as_t *as, int flags, size_t size,
266 uintptr_t base, int attrs, mem_backend_t *backend,
267 mem_backend_data_t *backend_data);
268extern int as_area_destroy(as_t *as, uintptr_t address);
269extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags);
270int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size,
271 as_t *dst_as, uintptr_t dst_base, int dst_flags_mask);
272
273extern int as_area_get_flags(as_area_t *area);
274extern bool as_area_check_access(as_area_t *area, pf_access_t access);
275extern size_t as_get_size(uintptr_t base);
276extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
277extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
278
279
280/* Interface to be implemented by architectures. */
281#ifndef as_constructor_arch
282extern int as_constructor_arch(as_t *as, int flags);
283#endif /* !def as_constructor_arch */
284#ifndef as_destructor_arch
285extern int as_destructor_arch(as_t *as);
286#endif /* !def as_destructor_arch */
287#ifndef as_create_arch
288extern int as_create_arch(as_t *as, int flags);
289#endif /* !def as_create_arch */
290#ifndef as_install_arch
291extern void as_install_arch(as_t *as);
292#endif /* !def as_install_arch */
293#ifndef as_deinstall_arch
294extern void as_deinstall_arch(as_t *as);
295#endif /* !def as_deinstall_arch */
296
297/* Backend declarations and functions. */
298extern mem_backend_t anon_backend;
299extern mem_backend_t elf_backend;
300extern mem_backend_t phys_backend;
301
302extern int elf_load(elf_header_t *header, as_t *as);
303
304/* Address space area related syscalls. */
305extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags);
306extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags);
307extern unative_t sys_as_area_destroy(uintptr_t address);
308
309/* Introspection functions. */
310extern void as_print(as_t *as);
311
312#endif /* KERNEL */
313
314#endif
315
316/** @}
317 */
Note: See TracBrowser for help on using the repository browser.