source: mainline/kernel/generic/include/mm/as.h@ 5a5269d

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5a5269d was 5a5269d, checked in by GitHub <noreply@…>, 6 years ago

Change type of uspace pointers in kernel from pointer type to numeric (#170)

From kernel's perspective, userspace addresses are not valid pointers,
and can only be used in calls to copy_to/from_uspace().
Therefore, we change the type of those arguments and variables to
uspace_addr_t which is an alias for sysarg_t.

This allows the compiler to catch accidental direct accesses to
userspace addresses.

Additionally, to avoid losing the type information in code,
a macro uspace_ptr(type) is used that translates to uspace_addr_t.
I makes no functional difference, but allows keeping the type information
in code in case we implement some sort of static checking for it in the future.

However, ccheck doesn't like that, so instead of using uspace_ptr(char),
we use uspace_ptr_char which is defined as
#define uspace_ptr_char uspace_ptr(char).

  • Property mode set to 100644
File size: 10.7 KB
RevLine 
[f761f1eb]1/*
[9150781]2 * Copyright (c) 2010 Jakub Jermar
[f761f1eb]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
[174156fd]29/** @addtogroup kernel_generic_mm
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[06e1e95]35#ifndef KERN_AS_H_
36#define KERN_AS_H_
[f761f1eb]37
[c0699467]38#include <typedefs.h>
39#include <abi/mm/as.h>
[a1a03f9]40#include <arch/mm/page.h>
[20d50a1]41#include <arch/mm/as.h>
[1084a784]42#include <arch/mm/asid.h>
[27ba40f]43#include <arch/istate.h>
[f761f1eb]44#include <synch/spinlock.h>
[1068f6a]45#include <synch/mutex.h>
[5c9a08b]46#include <adt/list.h>
[88cc71c0]47#include <adt/odict.h>
[d4b5542]48#include <lib/elf.h>
[1066041]49#include <arch.h>
[78de83de]50#include <lib/refcount.h>
[1066041]51
[a6e55886]52#define AS CURRENT->as
[1066041]53
[80bcaed]54/**
55 * Defined to be true if user address space and kernel address space shadow each
56 * other.
[da1bafb]57 *
[80bcaed]58 */
[da1bafb]59#define KERNEL_ADDRESS_SPACE_SHADOWED KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
[5a7d9d1]60
[84176f3]61/**
62 * Defined to be true if user address space and kernel address space do not
63 * share the same page table.
64 */
65#define KERNEL_SEPARATE_PTL0 KERNEL_SEPARATE_PTL0_ARCH
66
[da1bafb]67#define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
68#define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
69#define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
70#define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
[f761f1eb]71
[80bcaed]72/** Kernel address space. */
[da1bafb]73#define FLAG_AS_KERNEL (1 << 0)
[4512d7e]74
[80bcaed]75/* Address space area attributes. */
[da1bafb]76#define AS_AREA_ATTR_NONE 0
77#define AS_AREA_ATTR_PARTIAL 1 /**< Not fully initialized area. */
[8182031]78
[80bcaed]79/** The page fault was resolved by as_page_fault(). */
[1b20da0]80#define AS_PF_OK 0
[da1bafb]81
[80bcaed]82/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
[908bb96]83#define AS_PF_DEFER 1
84
85/** The page fault was not resolved by as_page_fault(). */
86#define AS_PF_FAULT 2
87
88/** The page fault was not resolved by as_page_fault(). Non-verbose version. */
89#define AS_PF_SILENT 3
[80bcaed]90
91/** Address space structure.
92 *
93 * as_t contains the list of as_areas of userspace accessible
94 * pages for one or more tasks. Ranges of kernel memory pages are not
95 * supposed to figure in the list as they are shared by all tasks and
96 * set up during system initialization.
[da1bafb]97 *
[80bcaed]98 */
99typedef struct as {
100 /** Protected by asidlock. */
101 link_t inactive_as_with_asid_link;
[a35b458]102
[879585a3]103 /**
[fc47885]104 * Number of processors on which this
105 * address space is active. Protected by
106 * asidlock.
[879585a3]107 */
[98000fb]108 size_t cpu_refcount;
[a35b458]109
[fc47885]110 /** Address space identifier.
111 *
112 * Constant on architectures that do not
113 * support ASIDs. Protected by asidlock.
114 *
[879585a3]115 */
116 asid_t asid;
[a35b458]117
[fc47885]118 /** Number of references (i.e. tasks that reference this as). */
[78de83de]119 atomic_refcount_t refcount;
[a35b458]120
[31d8e10]121 mutex_t lock;
[a35b458]122
[88cc71c0]123 /** Address space areas in this address space by base address.
124 *
125 * Members are of type as_area_t.
126 */
127 odict_t as_areas;
[a35b458]128
[80bcaed]129 /** Non-generic content. */
130 as_genarch_t genarch;
[a35b458]131
[80bcaed]132 /** Architecture specific content. */
133 as_arch_t arch;
134} as_t;
[b3f8fb7]135
136typedef struct {
[1433ecda]137 pte_t *(*page_table_create)(unsigned int);
138 void (*page_table_destroy)(pte_t *);
139 void (*page_table_lock)(as_t *, bool);
140 void (*page_table_unlock)(as_t *, bool);
141 bool (*page_table_locked)(as_t *);
[b3f8fb7]142} as_operations_t;
[8182031]143
[de0af3a]144/** Single anonymous page mapping. */
145typedef struct {
146 /** Containing pagemap structure */
147 struct as_pagemap *pagemap;
148 /** Link to @c shinfo->pagemap ordered dictionary */
149 odlink_t lpagemap;
150 /** Virtual address */
151 uintptr_t vaddr;
152 /** Physical frame address */
153 uintptr_t frame;
154} as_page_mapping_t;
155
156/** Map of anonymous pages in a shared area. */
157typedef struct as_pagemap {
158 /**
159 * Dictionary ordered by virtual address. Members are of type
160 * as_page_mapping_t
161 */
162 odict_t map;
163} as_pagemap_t;
164
[2fc3b2d]165/** Used space interval */
166typedef struct {
167 /** Containing used_space structure */
168 struct used_space *used_space;
169 /** Link to @c used_space->ivals */
170 odlink_t lused_space;
171 /** First page address */
172 uintptr_t page;
173 /** Count of pages */
174 size_t count;
175} used_space_ival_t;
176
177/** Map of used space in an address space area */
178typedef struct used_space {
179 /**
180 * Dictionary of intervals by start address.
181 * Members are of type @c used_space_ival_t.
182 */
183 odict_t ivals;
184 /** Total number of used pages. */
185 size_t pages;
186} used_space_t;
187
[80bcaed]188/**
189 * This structure contains information associated with the shared address space
190 * area.
[da1bafb]191 *
[80bcaed]192 */
[0ee077ee]193typedef struct {
[80bcaed]194 /** This lock must be acquired only when the as_area lock is held. */
[da1bafb]195 mutex_t lock;
[80bcaed]196 /** This structure can be deallocated if refcount drops to 0. */
[98000fb]197 size_t refcount;
[83b6ba9f]198 /** True if the area has been ever shared. */
199 bool shared;
200
[de0af3a]201 /** Complete map of anonymous pages of the shared area. */
202 as_pagemap_t pagemap;
[83b6ba9f]203
204 /** Address space area backend. */
205 struct mem_backend *backend;
206 /** Address space area shared data. */
207 void *backend_shared_data;
[0ee077ee]208} share_info_t;
209
[b3f8fb7]210/** Page fault access type. */
211typedef enum {
212 PF_ACCESS_READ,
213 PF_ACCESS_WRITE,
[c15b374]214 PF_ACCESS_EXEC,
215 PF_ACCESS_UNKNOWN
[b3f8fb7]216} pf_access_t;
217
218struct mem_backend;
[0ee077ee]219
220/** Backend data stored in address space area. */
[b3f8fb7]221typedef union mem_backend_data {
[75b139f]222 /* anon_backend members */
223 struct {
224 };
225
[da1bafb]226 /** elf_backend members */
227 struct {
[d91488d]228 uintptr_t elf_base;
[127c957b]229 elf_header_t *elf;
230 elf_segment_header_t *segment;
231 };
[a35b458]232
[da1bafb]233 /** phys_backend members */
234 struct {
[7f1c620]235 uintptr_t base;
[98000fb]236 size_t frames;
[c101dc0]237 bool anonymous;
[127c957b]238 };
[75b139f]239
240 /** user_backend members */
241 struct {
[ae6021d]242 as_area_pager_info_t pager_info;
[75b139f]243 };
244
[0ee077ee]245} mem_backend_data_t;
[8182031]246
247/** Address space area structure.
248 *
249 * Each as_area_t structure describes one contiguous area of virtual memory.
[da1bafb]250 *
[8182031]251 */
[b3f8fb7]252typedef struct {
[8182031]253 mutex_t lock;
[a35b458]254
[80bcaed]255 /** Containing address space. */
[da1bafb]256 as_t *as;
[a35b458]257
[88cc71c0]258 /** Link to @c as->as_areas */
259 odlink_t las_areas;
260
[fc47885]261 /** Memory flags. */
[da1bafb]262 unsigned int flags;
[a35b458]263
[fc47885]264 /** Address space area attributes. */
[da1bafb]265 unsigned int attributes;
[a35b458]266
[fc47885]267 /** Number of pages in the area. */
[98000fb]268 size_t pages;
[a35b458]269
[80bcaed]270 /** Base address of this area. */
271 uintptr_t base;
[a35b458]272
[80bcaed]273 /** Map of used space. */
[2fc3b2d]274 used_space_t used_space;
[a35b458]275
[80bcaed]276 /**
[fc47885]277 * If the address space area is shared. this is
278 * a reference to the share info structure.
[80bcaed]279 */
280 share_info_t *sh_info;
[a35b458]281
[80bcaed]282 /** Memory backend backing this address space area. */
283 struct mem_backend *backend;
[a35b458]284
[0ee077ee]285 /** Data to be used by the backend. */
286 mem_backend_data_t backend_data;
[b3f8fb7]287} as_area_t;
288
289/** Address space area backend structure. */
290typedef struct mem_backend {
[1433ecda]291 bool (*create)(as_area_t *);
292 bool (*resize)(as_area_t *, size_t);
293 void (*share)(as_area_t *);
294 void (*destroy)(as_area_t *);
[03523dc]295
[1433ecda]296 bool (*is_resizable)(as_area_t *);
297 bool (*is_shareable)(as_area_t *);
[01029fc]298
[1433ecda]299 int (*page_fault)(as_area_t *, uintptr_t, pf_access_t);
300 void (*frame_free)(as_area_t *, uintptr_t, uintptr_t);
[83b6ba9f]301
[1433ecda]302 bool (*create_shared_data)(as_area_t *);
303 void (*destroy_shared_data)(void *);
[b3f8fb7]304} mem_backend_t;
[8182031]305
[fc1e4f6]306extern as_t *AS_KERNEL;
[bd1deed]307
[ef67bab]308extern as_operations_t *as_operations;
[55b77d9]309extern list_t inactive_as_with_asid_list;
[7e4e532]310
[ef67bab]311extern void as_init(void);
[482826d]312
[da1bafb]313extern as_t *as_create(unsigned int);
[0321109]314extern void as_hold(as_t *);
315extern void as_release(as_t *);
[9150781]316extern void as_switch(as_t *, as_t *);
317extern int as_page_fault(uintptr_t, pf_access_t, istate_t *);
[482826d]318
[fbcdeb8]319extern as_area_t *as_area_create(as_t *, unsigned int, size_t, unsigned int,
320 mem_backend_t *, mem_backend_data_t *, uintptr_t *, uintptr_t);
[b7fd2a0]321extern errno_t as_area_destroy(as_t *, uintptr_t);
322extern errno_t as_area_resize(as_t *, uintptr_t, size_t, unsigned int);
323extern errno_t as_area_share(as_t *, uintptr_t, size_t, as_t *, unsigned int,
[fbcdeb8]324 uintptr_t *, uintptr_t);
[b7fd2a0]325extern errno_t as_area_change_flags(as_t *, unsigned int, uintptr_t);
[88cc71c0]326extern as_area_t *as_area_first(as_t *);
327extern as_area_t *as_area_next(as_area_t *);
[482826d]328
[de0af3a]329extern void as_pagemap_initialize(as_pagemap_t *);
330extern void as_pagemap_finalize(as_pagemap_t *);
331extern as_page_mapping_t *as_pagemap_first(as_pagemap_t *);
332extern as_page_mapping_t *as_pagemap_next(as_page_mapping_t *);
333extern errno_t as_pagemap_find(as_pagemap_t *, uintptr_t, uintptr_t *);
334extern void as_pagemap_insert(as_pagemap_t *, uintptr_t, uintptr_t);
335extern void as_pagemap_remove(as_page_mapping_t *);
336
[da1bafb]337extern unsigned int as_area_get_flags(as_area_t *);
[9150781]338extern bool as_area_check_access(as_area_t *, pf_access_t);
339extern size_t as_area_get_size(uintptr_t);
[2fc3b2d]340extern used_space_ival_t *used_space_first(used_space_t *);
341extern used_space_ival_t *used_space_next(used_space_ival_t *);
342extern used_space_ival_t *used_space_find_gteq(used_space_t *, uintptr_t);
343extern bool used_space_insert(used_space_t *, uintptr_t, size_t);
[29b2bbf]344
[4512d7e]345/* Interface to be implemented by architectures. */
[da1bafb]346
[29b2bbf]347#ifndef as_constructor_arch
[b7fd2a0]348extern errno_t as_constructor_arch(as_t *, unsigned int);
[29b2bbf]349#endif /* !def as_constructor_arch */
[da1bafb]350
[29b2bbf]351#ifndef as_destructor_arch
[9150781]352extern int as_destructor_arch(as_t *);
[29b2bbf]353#endif /* !def as_destructor_arch */
[da1bafb]354
[29b2bbf]355#ifndef as_create_arch
[b7fd2a0]356extern errno_t as_create_arch(as_t *, unsigned int);
[29b2bbf]357#endif /* !def as_create_arch */
[da1bafb]358
[20d50a1]359#ifndef as_install_arch
[9150781]360extern void as_install_arch(as_t *);
[20d50a1]361#endif /* !def as_install_arch */
[da1bafb]362
[57da95c]363#ifndef as_deinstall_arch
[9150781]364extern void as_deinstall_arch(as_t *);
[57da95c]365#endif /* !def as_deinstall_arch */
[f761f1eb]366
[b3f8fb7]367/* Backend declarations and functions. */
[8182031]368extern mem_backend_t anon_backend;
369extern mem_backend_t elf_backend;
[0ee077ee]370extern mem_backend_t phys_backend;
[75b139f]371extern mem_backend_t user_backend;
[8182031]372
[df0103f7]373/* Address space area related syscalls. */
[6aeca0d]374extern sysarg_t sys_as_area_create(uintptr_t, size_t, unsigned int, uintptr_t,
[5a5269d]375 uspace_ptr_as_area_pager_info_t);
[b7fd2a0]376extern sys_errno_t sys_as_area_resize(uintptr_t, size_t, unsigned int);
377extern sys_errno_t sys_as_area_change_flags(uintptr_t, unsigned int);
[5a5269d]378extern sys_errno_t sys_as_area_get_info(uintptr_t, uspace_ptr_as_area_info_t);
[b7fd2a0]379extern sys_errno_t sys_as_area_destroy(uintptr_t);
[7c23af9]380
[64c2ad5]381/* Introspection functions. */
[b389f95]382extern as_area_info_t *as_get_area_info(as_t *, size_t *);
[9150781]383extern void as_print(as_t *);
[64c2ad5]384
[f761f1eb]385#endif
[b45c443]386
[f47fd19]387/** @}
[b45c443]388 */
Note: See TracBrowser for help on using the repository browser.