|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2005 David Decotigny !! 001 /* Copyright (C) 2005,2006 David Decotigny 002 002 003 This program is free software; you can redi 003 This program is free software; you can redistribute it and/or 004 modify it under the terms of the GNU Genera 004 modify it under the terms of the GNU General Public License 005 as published by the Free Software Foundatio 005 as published by the Free Software Foundation; either version 2 006 of the License, or (at your option) any lat 006 of the License, or (at your option) any later version. 007 007 008 This program is distributed in the hope tha 008 This program is distributed in the hope that it will be useful, 009 but WITHOUT ANY WARRANTY; without even the 009 but WITHOUT ANY WARRANTY; without even the implied warranty of 010 MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 011 GNU General Public License for more details 011 GNU General Public License for more details. 012 012 013 You should have received a copy of the GNU 013 You should have received a copy of the GNU General Public License 014 along with this program; if not, write to t 014 along with this program; if not, write to the Free Software 015 Foundation, Inc., 59 Temple Place - Suite 3 015 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 016 USA. 016 USA. 017 */ 017 */ 018 #ifndef _SOS_UMEM_VMM_H_ 018 #ifndef _SOS_UMEM_VMM_H_ 019 #define _SOS_UMEM_VMM_H_ 019 #define _SOS_UMEM_VMM_H_ 020 020 021 /** 021 /** 022 * @file umem_vmm.h 022 * @file umem_vmm.h 023 * 023 * 024 * Management of the address space of a proces 024 * Management of the address space of a process in SOS. The so-called 025 * "address space" of a process consists in th 025 * "address space" of a process consists in the description of the 026 * virtual addresses that are valid in the use 026 * virtual addresses that are valid in the user space of a process (in 027 * SOS: addresses 1G-4G). The kernel-space of 027 * SOS: addresses 1G-4G). The kernel-space of a process is managed by 028 * the "kmem" subsystem, and is kept identical 028 * the "kmem" subsystem, and is kept identical accross all the 029 * processes in the system. 029 * processes in the system. 030 * 030 * 031 * The umem_vmm subsystem handles the followin 031 * The umem_vmm subsystem handles the following features: 032 * - demand-mapping of resourcs (files: mmap) 032 * - demand-mapping of resourcs (files: mmap): mapping in physical RAM 033 * will be delayed as much as possible, unt 033 * will be delayed as much as possible, until the process really 034 * need to access the mapped addresses 034 * need to access the mapped addresses 035 * - mprotect/mremap support 035 * - mprotect/mremap support 036 * - private and shared mappings 036 * - private and shared mappings 037 * - Copy-On-Write (COW) of the private mappi 037 * - Copy-On-Write (COW) of the private mappings upon fork() to favour 038 * shared physical memory as much as possib 038 * shared physical memory as much as possible 039 * - "heap" management (brk/sbrk) 039 * - "heap" management (brk/sbrk) 040 * 040 * 041 * Swap is NOT supported (yet), which means th 041 * Swap is NOT supported (yet), which means that the following is NOT 042 * supported: 042 * supported: 043 * - locked/reserved I/O pages (everything is 043 * - locked/reserved I/O pages (everything is locked in RAM) 044 * - "safe" demand-mapping of anonymous pages 044 * - "safe" demand-mapping of anonymous pages, ie conservative VMM 045 * allocation (alloc of anonymous pages on 045 * allocation (alloc of anonymous pages on the swap) 046 * Other unsupported features: 046 * Other unsupported features: 047 * - dynamically-resizable regions (Linux's G 047 * - dynamically-resizable regions (Linux's GROWUP/GROWDOWN vma): the 048 * user stack is expected to have a suitabl 048 * user stack is expected to have a suitable virtual size from the 049 * beginning, or sos_umem_vmm_resize() must 049 * beginning, or sos_umem_vmm_resize() must be used explicitely to 050 * resize it 050 * resize it 051 * - no provision of "stack size" accounting, 051 * - no provision of "stack size" accounting, since there are 052 * multiple stacks (ie user threads) in a p 052 * multiple stacks (ie user threads) in a process: which stack to 053 * consider ??? 053 * consider ??? 054 * 054 * 055 * The address space is divided into "virtual 055 * The address space is divided into "virtual regions" (aka "VR") that 056 * describe a single mapping, aka a segment of 056 * describe a single mapping, aka a segment of contiguous pages in 057 * user-space virtual memory. Each such virtua 057 * user-space virtual memory. Each such virtual region "maps" a 058 * "resource" and is characterised by: 058 * "resource" and is characterised by: 059 * - its base address and length in user-spa 059 * - its base address and length in user-space 060 * - the allowed accesses, aka "protection" 060 * - the allowed accesses, aka "protection" (read-only or read/write) 061 * - the resource it maps in virtual memory 061 * - the resource it maps in virtual memory 062 * 062 * 063 * A so-called resource is typically: 063 * A so-called resource is typically: 064 * - a file 064 * - a file 065 * - a device 065 * - a device 066 * - an area initially full of zeros (the VR 066 * - an area initially full of zeros (the VR mapping this are called 067 * "anonymous mappings") 067 * "anonymous mappings") 068 * 068 * 069 * The implementation is very close to that of 069 * The implementation is very close to that of Linux and Kos. This is 070 * a "simple" implementation, not the most ele 070 * a "simple" implementation, not the most elegant one, such as those 071 * based on "shadow objects" hierarchies as fo 071 * based on "shadow objects" hierarchies as found in BSD 4.4 and Mach, 072 * or that of Solaris (based on the "anon" lis 072 * or that of Solaris (based on the "anon" lists). Actually, this 073 * implementation does not use "shadow-objects 073 * implementation does not use "shadow-objects"/anon list when a COW 074 * page of a shared mapping is made anonymous. 074 * page of a shared mapping is made anonymous. This won't hurt the 075 * implementation of the basic demand-mapping 075 * implementation of the basic demand-mapping mechanism; on the 076 * contrary, it will make things simpler. But 076 * contrary, it will make things simpler. But this will largely impact 077 * the implementation of the swap-in/swap-out 077 * the implementation of the swap-in/swap-out strategies, as these 078 * would require a non trivial intrication of 078 * would require a non trivial intrication of low-level and higher 079 * level algorithms. 079 * level algorithms. 080 */ 080 */ 081 081 082 082 083 /** 083 /** 084 * Definition of an "address space" in Kos. Th 084 * Definition of an "address space" in Kos. This is an opaque 085 * structure defined in umem_vmm.c. Its main r 085 * structure defined in umem_vmm.c. Its main role is to list virtual 086 * regions. It mainly consists in: 086 * regions. It mainly consists in: 087 * - a reference to the process owning it 087 * - a reference to the process owning it 088 * - maximum allowed protection (ie can it be 088 * - maximum allowed protection (ie can it be mapped read-only or 089 * read/write ?) 089 * read/write ?) 090 * - the list of VRs mapping resources 090 * - the list of VRs mapping resources 091 * - a mm_context that reflects the configura 091 * - a mm_context that reflects the configuration of the MMU 092 * - the location of the heap for this proces 092 * - the location of the heap for this process 093 * - statistics 093 * - statistics 094 */ 094 */ 095 struct sos_umem_vmm_as; 095 struct sos_umem_vmm_as; 096 096 097 097 098 /** 098 /** 099 * Definition of a "virtual region". Linux wou 099 * Definition of a "virtual region". Linux would call them "vma" 100 * (Virtual Memory Area), and Solaris: "segmen 100 * (Virtual Memory Area), and Solaris: "segments". It mainly consists 101 * in: 101 * in: 102 * - the start/end addresses of the mapping 102 * - the start/end addresses of the mapping 103 * - a pointer to the resource that it maps 103 * - a pointer to the resource that it maps 104 * - the type of mapping (shared/private) 104 * - the type of mapping (shared/private) 105 * - the actual protection flags (@see SOS_VM 105 * - the actual protection flags (@see SOS_VM_MAP_PROT_* flags in 106 * hwcore/paging.h) 106 * hwcore/paging.h) 107 * - a set of callbacks (@see sos_umem_vmm_vr 107 * - a set of callbacks (@see sos_umem_vmm_vr_ops below) automatically 108 * called by the umem_vmm subsystem each ti 108 * called by the umem_vmm subsystem each time the VR is modified 109 */ 109 */ 110 struct sos_umem_vmm_vr; 110 struct sos_umem_vmm_vr; 111 111 112 112 113 /** VR flag: region can be shared between a pr 113 /** VR flag: region can be shared between a process and its 114 children */ 114 children */ 115 #define SOS_VR_MAP_SHARED (1 << 0) 115 #define SOS_VR_MAP_SHARED (1 << 0) 116 116 117 117 118 #include <sos/types.h> 118 #include <sos/types.h> 119 #include <sos/process.h> 119 #include <sos/process.h> 120 120 121 121 122 /** 122 /** 123 * The callbacks applicable on a virtual regio 123 * The callbacks applicable on a virtual region. Automatically called 124 * by the umem_vmm subsystem. 124 * by the umem_vmm subsystem. 125 * 125 * 126 * Calling sequences: 126 * Calling sequences: 127 * - duplicate_as() (aka fork()): 127 * - duplicate_as() (aka fork()): 128 * vr->ops->ref() 128 * vr->ops->ref() 129 * add vr to lists 129 * add vr to lists 130 * - delete_as() (aka exit()): 130 * - delete_as() (aka exit()): 131 * vr->ops->unmap() 131 * vr->ops->unmap() 132 * remove vr from lists 132 * remove vr from lists 133 * vr->ops->unref() 133 * vr->ops->unref() 134 * - mmap(): 134 * - mmap(): 135 * -> left + new + right VRs can fusion: 135 * -> left + new + right VRs can fusion: 136 * remove right_vr from list 136 * remove right_vr from list 137 * right_vr->ops->unref() 137 * right_vr->ops->unref() 138 * -> left + new VRs can fusion: 138 * -> left + new VRs can fusion: 139 * nothing 139 * nothing 140 * -> new + right VRs can fusion: 140 * -> new + right VRs can fusion: 141 * nothing 141 * nothing 142 * -> isolated: 142 * -> isolated: 143 * add new_vr to lists 143 * add new_vr to lists 144 * new_vr->map() 144 * new_vr->map() 145 * new_vr->ops->ref() 145 * new_vr->ops->ref() 146 * - munmap(): 146 * - munmap(): 147 * -> VR totally unmapped: 147 * -> VR totally unmapped: 148 * vr->ops->unmap() 148 * vr->ops->unmap() 149 * remove vr from lists 149 * remove vr from lists 150 * vr->ops->unref() 150 * vr->ops->unref() 151 * -> VR unmapped in the middle (split into 151 * -> VR unmapped in the middle (split into 2): 152 * add (new) right VR into the lists 152 * add (new) right VR into the lists 153 * vr->unmap(middle_unmapped_area) 153 * vr->unmap(middle_unmapped_area) 154 * right_vr->ops->ref() 154 * right_vr->ops->ref() 155 * -> VR unmapped on its left: 155 * -> VR unmapped on its left: 156 * vr->ops->unmap(left_unmapped_area) 156 * vr->ops->unmap(left_unmapped_area) 157 * -> VR unmapped on its right: 157 * -> VR unmapped on its right: 158 * vr->ops->unmap(right_unmapped_area) 158 * vr->ops->unmap(right_unmapped_area) 159 * - chprot(): 159 * - chprot(): 160 * -> VR totally chprot: 160 * -> VR totally chprot: 161 * nothing 161 * nothing 162 * -> VR chprot in the middle (split into 3 162 * -> VR chprot in the middle (split into 3): 163 * add (new) middle+right VRs into the 163 * add (new) middle+right VRs into the lists 164 * middle_vr->ops->ref() 164 * middle_vr->ops->ref() 165 * right_vr->ops->ref() 165 * right_vr->ops->ref() 166 * -> VR chprot on its left (split into 2): 166 * -> VR chprot on its left (split into 2): 167 * add (new) right VR into the lists 167 * add (new) right VR into the lists 168 * right_vr->ops->ref() 168 * right_vr->ops->ref() 169 * -> VR chprot on its right (split into 2) 169 * -> VR chprot on its right (split into 2): 170 * add (new) right VR into the lists 170 * add (new) right VR into the lists 171 * right_vr->ops->ref() 171 * right_vr->ops->ref() 172 * - resize(): 172 * - resize(): 173 * -> if moving the VR: map/unmap 173 * -> if moving the VR: map/unmap 174 * -> otherwise: nothing 174 * -> otherwise: nothing 175 */ 175 */ 176 struct sos_umem_vmm_vr_ops 176 struct sos_umem_vmm_vr_ops 177 { 177 { 178 /** 178 /** 179 * Called after the virtual region has been 179 * Called after the virtual region has been inserted 180 * inside its address space. 180 * inside its address space. 181 * @note Optional 181 * @note Optional 182 */ 182 */ 183 void (*ref)(struct sos_umem_vmm_vr * vr); 183 void (*ref)(struct sos_umem_vmm_vr * vr); 184 184 185 /** 185 /** 186 * Called when the virtual region is removed 186 * Called when the virtual region is removed from its 187 * address space 187 * address space 188 * @note Optional 188 * @note Optional 189 */ 189 */ 190 void (*unref)(struct sos_umem_vmm_vr * vr); 190 void (*unref)(struct sos_umem_vmm_vr * vr); 191 191 192 /** 192 /** 193 * Called when part or all a VR is unmapped 193 * Called when part or all a VR is unmapped 194 * @note Optional 194 * @note Optional 195 */ 195 */ 196 void (*unmap)(struct sos_umem_vmm_vr * vr, 196 void (*unmap)(struct sos_umem_vmm_vr * vr, 197 sos_uaddr_t uaddr, sos_size_t 197 sos_uaddr_t uaddr, sos_size_t size); 198 198 199 /** 199 /** 200 * Called by the page fault handler to map d 200 * Called by the page fault handler to map data at the given virtual 201 * address. In the Linux kernel, this callba 201 * address. In the Linux kernel, this callback is named "nopage". 202 * 202 * 203 * @note MANDATORY 203 * @note MANDATORY 204 */ 204 */ 205 sos_ret_t (*page_in)(struct sos_umem_vmm_vr 205 sos_ret_t (*page_in)(struct sos_umem_vmm_vr * vr, 206 sos_uaddr_t uaddr, 206 sos_uaddr_t uaddr, 207 sos_bool_t write_access 207 sos_bool_t write_access); >> 208 >> 209 >> 210 /** >> 211 * Called to synchronize the contents of the given page with its >> 212 * backing store. This method is responsible for resetting the dirty >> 213 * flag of the page (@see sos_paging_set_dirty). Appropriate locking >> 214 * MUST be handled internally by this method. >> 215 * >> 216 * @note Optional >> 217 */ >> 218 sos_ret_t (*sync_page)(struct sos_umem_vmm_vr * vr, >> 219 sos_uaddr_t page_uaddr, >> 220 sos_ui32_t flags); >> 221 /** Flags for msync */ >> 222 #define SOS_MSYNC_SYNC (1 << 0) >> 223 #define SOS_MSYNC_ASYNC (0 << 0) 208 }; 224 }; 209 225 210 226 211 /** 227 /** 212 * The definition of a mapped resource. Typica 228 * The definition of a mapped resource. Typically, a mapped resource 213 * is a file or a device: in both cases, only 229 * is a file or a device: in both cases, only part of the resource is 214 * mapped by each VR, this part is given by th 230 * mapped by each VR, this part is given by the offset_in_resource 215 * field of the VR, and the size field of the 231 * field of the VR, and the size field of the VR. 216 */ 232 */ 217 struct sos_umem_vmm_mapped_resource 233 struct sos_umem_vmm_mapped_resource 218 { 234 { 219 /** Represent the maximum authrized SOS_VR_P 235 /** Represent the maximum authrized SOS_VR_PROT_* for the VRs mapping 220 it */ 236 it */ 221 sos_ui32_t allowed_access_rights; 237 sos_ui32_t allowed_access_rights; 222 238 223 /** Some flags associated with the resource. 239 /** Some flags associated with the resource. Currently only 224 SOS_MAPPED_RESOURCE_ANONYMOUS is support 240 SOS_MAPPED_RESOURCE_ANONYMOUS is supported */ 225 sos_ui32_t flags; 241 sos_ui32_t flags; 226 242 227 /** List of VRs mapping this resource */ 243 /** List of VRs mapping this resource */ 228 struct sos_umem_vmm_vr * list_vr; 244 struct sos_umem_vmm_vr * list_vr; 229 245 230 /** 246 /** 231 * MANDATORY Callback function called when a 247 * MANDATORY Callback function called when a new VR is created, 232 * which maps the resource. This callback is 248 * which maps the resource. This callback is allowed to change the 233 * following fields of the VR: 249 * following fields of the VR: 234 * - sos_umem_vmm_set_ops_of_vr() 250 * - sos_umem_vmm_set_ops_of_vr() 235 */ 251 */ 236 sos_ret_t (*mmap)(struct sos_umem_vmm_vr *); 252 sos_ret_t (*mmap)(struct sos_umem_vmm_vr *); 237 253 238 /** 254 /** 239 * Custom data that the user is free to defi 255 * Custom data that the user is free to define: the umem_vmm 240 * subsystem won't ever look at it or change !! 256 * subsystem won't ever look at it or change it. 241 */ 257 */ 242 void *custom_data; 258 void *custom_data; 243 }; 259 }; 244 260 245 261 246 /** Inidicate that this resource is not backed 262 /** Inidicate that this resource is not backed by any physical 247 storage. This means that the "offset_in_re 263 storage. This means that the "offset_in_resource" field of the 248 VRs will be computed by sos_umem_vmm_map() 264 VRs will be computed by sos_umem_vmm_map() */ 249 #define SOS_MAPPED_RESOURCE_ANONYMOUS (1 << 0) 265 #define SOS_MAPPED_RESOURCE_ANONYMOUS (1 << 0) 250 266 251 267 252 /** 268 /** 253 * Physical address of THE page (full of 0s) u 269 * Physical address of THE page (full of 0s) used for anonymous 254 * mappings. Anybody can map it provided it is 270 * mappings. Anybody can map it provided it is ALWAYS in read-only 255 * mode 271 * mode 256 */ 272 */ 257 extern sos_paddr_t sos_zero_page; !! 273 extern sos_paddr_t sos_zero_physpage; >> 274 >> 275 /** >> 276 * "ZERO" page address mapped in kernel space >> 277 */ >> 278 extern sos_vaddr_t sos_zero_kernelpage; 258 279 259 280 260 /** 281 /** 261 * Setup the umem_vmm subsystem. 282 * Setup the umem_vmm subsystem. 262 */ 283 */ 263 sos_ret_t sos_umem_vmm_subsystem_setup(); !! 284 sos_ret_t sos_umem_vmm_subsystem_setup(void); 264 285 265 286 266 /** 287 /** 267 * Create a new, empty, address space 288 * Create a new, empty, address space 268 * 289 * 269 * @param owner The process that will own the 290 * @param owner The process that will own the new address space 270 * 291 * 271 * @note no need to call 292 * @note no need to call 272 * sos_thread_prepare_user_space_access()/sos_ 293 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 273 */ 294 */ 274 struct sos_umem_vmm_as * 295 struct sos_umem_vmm_as * 275 sos_umem_vmm_create_empty_as(struct sos_proces 296 sos_umem_vmm_create_empty_as(struct sos_process *owner); 276 297 277 298 278 /** 299 /** 279 * Create a new address space, copy of the cur 300 * Create a new address space, copy of the current thread's address 280 * space. All the translations belonging to pr 301 * space. All the translations belonging to private mappings are 281 * marked 'read-only' to activate the "copy-on 302 * marked 'read-only' to activate the "copy-on-write" semantics. 282 * 303 * 283 * @param owner The process that will hold the 304 * @param owner The process that will hold the new address space 284 * 305 * 285 * @note automatically calls 306 * @note automatically calls 286 * sos_thread_prepare_user_space_access()/sos_ 307 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 287 */ 308 */ 288 struct sos_umem_vmm_as * 309 struct sos_umem_vmm_as * 289 sos_umem_vmm_duplicate_current_thread_as(struc 310 sos_umem_vmm_duplicate_current_thread_as(struct sos_process *owner); 290 311 291 312 292 /** 313 /** 293 * Called at process deletion time, to remove 314 * Called at process deletion time, to remove all mappings present in 294 * the address space. This function not only d 315 * the address space. This function not only delete all the VR data 295 * structures, it also calls the unmap()/unref 316 * structures, it also calls the unmap()/unref() callbacks of these 296 * VRs. However, the physical pages mapped ins 317 * VRs. However, the physical pages mapped inside the address space 297 * won't be unmapped at this stage: they will 318 * won't be unmapped at this stage: they will be unmapped all in one 298 * go when the undelying mm_context will becom 319 * go when the undelying mm_context will become unused. 299 * 320 * 300 * @note no need to call 321 * @note no need to call 301 * sos_thread_prepare_user_space_access()/sos_ 322 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 302 */ 323 */ 303 sos_ret_t 324 sos_ret_t 304 sos_umem_vmm_delete_as(struct sos_umem_vmm_as 325 sos_umem_vmm_delete_as(struct sos_umem_vmm_as * as); 305 326 306 327 307 /* 328 /* 308 * Accessor functions for the address space 329 * Accessor functions for the address space 309 */ 330 */ 310 331 311 /** Retrieve the pointer (NOT a new reference 332 /** Retrieve the pointer (NOT a new reference !) to the process owning 312 the given address space. */ 333 the given address space. */ 313 struct sos_process * 334 struct sos_process * 314 sos_umem_vmm_get_process(struct sos_umem_vmm_a 335 sos_umem_vmm_get_process(struct sos_umem_vmm_as * as); 315 336 316 /** Retrieve the pointer (NOT a new reference 337 /** Retrieve the pointer (NOT a new reference !) to the MMU 317 configuration for the given address space 338 configuration for the given address space */ 318 struct sos_mm_context * 339 struct sos_mm_context * 319 sos_umem_vmm_get_mm_context(struct sos_umem_vm 340 sos_umem_vmm_get_mm_context(struct sos_umem_vmm_as * as); 320 341 321 /** Retrieve a pointer to the VR that covers t 342 /** Retrieve a pointer to the VR that covers the given virtual address 322 in the given address space */ 343 in the given address space */ 323 struct sos_umem_vmm_vr * 344 struct sos_umem_vmm_vr * 324 sos_umem_vmm_get_vr_at_address(struct sos_umem 345 sos_umem_vmm_get_vr_at_address(struct sos_umem_vmm_as * as, 325 sos_uaddr_t uad 346 sos_uaddr_t uaddr); 326 347 327 348 328 /* 349 /* 329 * Accessor functions for the virtual regions 350 * Accessor functions for the virtual regions 330 */ 351 */ 331 352 332 /** Retrieve the address space owning the give 353 /** Retrieve the address space owning the given VR */ 333 struct sos_umem_vmm_as * 354 struct sos_umem_vmm_as * 334 sos_umem_vmm_get_as_of_vr(struct sos_umem_vmm_ 355 sos_umem_vmm_get_as_of_vr(struct sos_umem_vmm_vr * vr); 335 356 336 /** Retrieve the set of callbacks of the given 357 /** Retrieve the set of callbacks of the given VR */ 337 struct sos_umem_vmm_vr_ops * 358 struct sos_umem_vmm_vr_ops * 338 sos_umem_vmm_get_ops_of_vr(struct sos_umem_vmm 359 sos_umem_vmm_get_ops_of_vr(struct sos_umem_vmm_vr * vr); 339 360 340 /** Retrieve the current protection of the giv 361 /** Retrieve the current protection of the given VR */ 341 sos_ui32_t sos_umem_vmm_get_prot_of_vr(struct 362 sos_ui32_t sos_umem_vmm_get_prot_of_vr(struct sos_umem_vmm_vr * vr); 342 363 343 /** Retrieve the flags of the given VR. One wi 364 /** Retrieve the flags of the given VR. One will especially be 344 interested in the SOS_VR_MAP_SHARED bit */ 365 interested in the SOS_VR_MAP_SHARED bit */ 345 sos_ui32_t sos_umem_vmm_get_flags_of_vr(struct 366 sos_ui32_t sos_umem_vmm_get_flags_of_vr(struct sos_umem_vmm_vr * vr); 346 367 347 /** Retrieve the resource mapped by the VR */ 368 /** Retrieve the resource mapped by the VR */ 348 struct sos_umem_vmm_mapped_resource * 369 struct sos_umem_vmm_mapped_resource * 349 sos_umem_vmm_get_mapped_resource_of_vr(struct 370 sos_umem_vmm_get_mapped_resource_of_vr(struct sos_umem_vmm_vr * vr); 350 371 351 /** Retrieve the start user address for the gi 372 /** Retrieve the start user address for the given mapping */ 352 sos_uaddr_t sos_umem_vmm_get_start_of_vr(struc 373 sos_uaddr_t sos_umem_vmm_get_start_of_vr(struct sos_umem_vmm_vr * vr); 353 374 354 /** Retrieve the size (in user space) of the g 375 /** Retrieve the size (in user space) of the given mapping */ 355 sos_size_t sos_umem_vmm_get_size_of_vr(struct 376 sos_size_t sos_umem_vmm_get_size_of_vr(struct sos_umem_vmm_vr * vr); 356 377 357 /** Retrieve the offset in the resource of the 378 /** Retrieve the offset in the resource of the mapping */ 358 sos_luoffset_t 379 sos_luoffset_t 359 sos_umem_vmm_get_offset_in_resource(struct sos 380 sos_umem_vmm_get_offset_in_resource(struct sos_umem_vmm_vr * vr); 360 381 361 382 362 /* 383 /* 363 * Restricted accessor functions. May only be 384 * Restricted accessor functions. May only be called from inside the 364 * map() callback of a VR 385 * map() callback of a VR 365 */ 386 */ 366 387 367 /** 388 /** 368 * Function that is not called directly by the 389 * Function that is not called directly by the umem_subsystem: It MUST 369 * always be called by the mmap() callback of 390 * always be called by the mmap() callback of the resource being 370 * mapped (@see sos_umem_vmm_mapped_resource:: 391 * mapped (@see sos_umem_vmm_mapped_resource::mmap()). The mmap() 371 * method is called at VR creation time, autom 392 * method is called at VR creation time, automatically by 372 * sos_umem_vmm_map(). 393 * sos_umem_vmm_map(). 373 * 394 * 374 * @note The VR MUST NOT already have a set of 395 * @note The VR MUST NOT already have a set of operations (fatal error) 375 */ 396 */ 376 sos_ret_t sos_umem_vmm_set_ops_of_vr(struct so 397 sos_ret_t sos_umem_vmm_set_ops_of_vr(struct sos_umem_vmm_vr * vr, 377 struct so 398 struct sos_umem_vmm_vr_ops * ops); 378 399 379 400 380 /* 401 /* 381 * mmap API 402 * mmap API 382 */ 403 */ 383 404 384 405 385 /** sos_umem_vmm_map() flag: the address given 406 /** sos_umem_vmm_map() flag: the address given as parameter to 386 sos_umem_vmm_map() is not only a hint, it 407 sos_umem_vmm_map() is not only a hint, it is where the VR is 387 expected to be mapped */ 408 expected to be mapped */ 388 #define SOS_VR_MAP_FIXED (1 << 31) 409 #define SOS_VR_MAP_FIXED (1 << 31) 389 410 390 411 391 /** 412 /** 392 * Add a new VR in the given address space, th 413 * Add a new VR in the given address space, that maps the given 393 * resource. Its semantics follows that of the 414 * resource. Its semantics follows that of the UNIX mmap() call 394 * (including SOS_VR_MAP_FIXED). Real mapping 415 * (including SOS_VR_MAP_FIXED). Real mapping in physical memory will 395 * be delayed as much as possible (demand pagi 416 * be delayed as much as possible (demand paging) and the physical 396 * pages will be shared among processes as muc 417 * pages will be shared among processes as much as possible (COW). 397 * 418 * 398 * @param *uaddr must be page-aligned, and can 419 * @param *uaddr must be page-aligned, and can be NULL. It stores the 399 * address of the mapping, when successful 420 * address of the mapping, when successful 400 * 421 * 401 * @param size The size of the mapping in user 422 * @param size The size of the mapping in user space 402 * 423 * 403 * @param access_rights The allowed accesses t 424 * @param access_rights The allowed accesses to the mapped resource 404 * (@see SOS_VM_MAP_PROT_* flags in hwcore/pag 425 * (@see SOS_VM_MAP_PROT_* flags in hwcore/paging.h) 405 * 426 * 406 * @param flags mainly: is it shared mapping ( 427 * @param flags mainly: is it shared mapping (SOS_VR_MAP_SHARED) or not ? 407 * 428 * 408 * @param resource MUST be NON NULL, and its m 429 * @param resource MUST be NON NULL, and its mmap() method must also 409 * be NON NULL 430 * be NON NULL 410 * 431 * 411 * @param offset_in_resource where inside the 432 * @param offset_in_resource where inside the resource does the 412 * mapping start 433 * mapping start 413 * 434 * 414 * @return SOS_OK on success (address of the m 435 * @return SOS_OK on success (address of the mapping stored in uaddr) 415 * 436 * 416 * @note no need to call 437 * @note no need to call 417 * sos_thread_prepare_user_space_access()/sos_ 438 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 418 */ 439 */ 419 sos_ret_t 440 sos_ret_t 420 sos_umem_vmm_map(struct sos_umem_vmm_as * as, 441 sos_umem_vmm_map(struct sos_umem_vmm_as * as, 421 sos_uaddr_t *uaddr, sos_size_ 442 sos_uaddr_t *uaddr, sos_size_t size, 422 sos_ui32_t access_rights, 443 sos_ui32_t access_rights, 423 sos_ui32_t flags, 444 sos_ui32_t flags, 424 struct sos_umem_vmm_mapped_re 445 struct sos_umem_vmm_mapped_resource * resource, 425 sos_luoffset_t offset_in_reso 446 sos_luoffset_t offset_in_resource); 426 447 427 448 428 /** 449 /** 429 * Unmap the given address interval. This migh 450 * Unmap the given address interval. This might imply the partial or 430 * complete unmapping of 0, 1 or more VRs. Sam 451 * complete unmapping of 0, 1 or more VRs. Same semantics as unix 431 * munmap() 452 * munmap() 432 * 453 * 433 * @note automatically calls 454 * @note automatically calls 434 * sos_thread_prepare_user_space_access()/sos_ 455 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 435 */ 456 */ 436 sos_ret_t 457 sos_ret_t 437 sos_umem_vmm_unmap(struct sos_umem_vmm_as * as 458 sos_umem_vmm_unmap(struct sos_umem_vmm_as * as, 438 sos_uaddr_t uaddr, sos_size 459 sos_uaddr_t uaddr, sos_size_t size); >> 460 >> 461 >> 462 /** >> 463 * Flush the given pages to backing store. Call the sync_page method >> 464 * for each of the dirty pages. The MMU is expected to be configured >> 465 * for the given AS ! >> 466 * >> 467 * @note MAKE SURE YOU CALL >> 468 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() >> 469 */ >> 470 sos_ret_t >> 471 sos_umem_vmm_sync(struct sos_umem_vmm_as * as, >> 472 sos_uaddr_t uaddr, sos_size_t size, >> 473 sos_ui32_t flags); 439 474 440 475 441 /** 476 /** 442 * Change the access rights of the given addre 477 * Change the access rights of the given address interval. This might 443 * concern 0, 1 or more VRs, and result in the 478 * concern 0, 1 or more VRs, and result in the splitting in 1 or 2 VRs 444 * if they are partially concerned by the chan 479 * if they are partially concerned by the change in protection.. Same 445 * semantics as unix mprotect() 480 * semantics as unix mprotect() 446 * 481 * 447 * @param new_access_rights @see SOS_VM_MAP_PR 482 * @param new_access_rights @see SOS_VM_MAP_PROT_* flags in hwcore/paging.h 448 * 483 * 449 * @note MAKE SURE YOU CALL 484 * @note MAKE SURE YOU CALL 450 * sos_thread_prepare_user_space_access()/sos_ 485 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 451 */ 486 */ 452 sos_ret_t 487 sos_ret_t 453 sos_umem_vmm_chprot(struct sos_umem_vmm_as * a 488 sos_umem_vmm_chprot(struct sos_umem_vmm_as * as, 454 sos_uaddr_t uaddr, sos_siz 489 sos_uaddr_t uaddr, sos_size_t size, 455 sos_ui32_t new_access_righ 490 sos_ui32_t new_access_rights); 456 491 457 492 458 493 459 /** 494 /** 460 * Flag for sos_umem_vmm_resize() to indicate 495 * Flag for sos_umem_vmm_resize() to indicate that the VR being 461 * resized can be moved elsewhere if there is 496 * resized can be moved elsewhere if there is not enough room to 462 * resize it in-place 497 * resize it in-place 463 */ 498 */ 464 #define SOS_VR_REMAP_MAYMOVE (1 << 30) 499 #define SOS_VR_REMAP_MAYMOVE (1 << 30) 465 500 466 /** 501 /** 467 * Lookup the region covering the old_uaddr/ol 502 * Lookup the region covering the old_uaddr/old_size interval, and 468 * resize it to match the *new_uaddr/new_size 503 * resize it to match the *new_uaddr/new_size requirements. This is a 469 * variant of Unix's mremap() that allow to re 504 * variant of Unix's mremap() that allow to resize the VR by its 470 * low-addresses (mremap only allows to resize 505 * low-addresses (mremap only allows to resize a VR by its 471 * top-address). 506 * top-address). 472 * 507 * 473 * @param old_uaddr Low address of the interva 508 * @param old_uaddr Low address of the interval covered by the VR to resize 474 * 509 * 475 * @param old_size Size of the interval covere 510 * @param old_size Size of the interval covered by the VR to resize 476 * 511 * 477 * @param new_uaddr MUST BE page-aligned ! Ini 512 * @param new_uaddr MUST BE page-aligned ! Initially: the new start 478 * address of the VR, allowing to change the l 513 * address of the VR, allowing to change the low-address. Once the 479 * function returns: the actual start address 514 * function returns: the actual start address of the VR (which might 480 * be different, due to SOS_VR_REMAP_MAYMOVE f 515 * be different, due to SOS_VR_REMAP_MAYMOVE flag, when set) 481 * 516 * 482 * @param new_size The size requested for the 517 * @param new_size The size requested for the VR. Might be 483 * smaller/larger than the original VR size 518 * smaller/larger than the original VR size 484 * 519 * 485 * @param flags Essentially: 0 or SOS_VR_REMAP 520 * @param flags Essentially: 0 or SOS_VR_REMAP_MAYMOVE 486 * 521 * 487 * @note MAKE SURE YOU CALL 522 * @note MAKE SURE YOU CALL 488 * sos_thread_prepare_user_space_access()/sos_ 523 * sos_thread_prepare_user_space_access()/sos_thread_end_user_space_access() 489 */ 524 */ 490 sos_ret_t 525 sos_ret_t 491 sos_umem_vmm_resize(struct sos_umem_vmm_as * a 526 sos_umem_vmm_resize(struct sos_umem_vmm_as * as, 492 sos_uaddr_t old_uaddr, sos 527 sos_uaddr_t old_uaddr, sos_size_t old_size, 493 sos_uaddr_t /* in/out */*n 528 sos_uaddr_t /* in/out */*new_uaddr, sos_size_t new_size, 494 sos_ui32_t flags); 529 sos_ui32_t flags); 495 530 496 531 497 /* 532 /* 498 * Heap management API (ie libc's malloc suppo 533 * Heap management API (ie libc's malloc support) 499 */ 534 */ 500 535 501 /** 536 /** 502 * Change the top address of the heap. 537 * Change the top address of the heap. 503 * 538 * 504 * @param new_top_uaddr When NULL don't change 539 * @param new_top_uaddr When NULL don't change anything. Otherwise: 505 * change the top address of the heap 540 * change the top address of the heap 506 * 541 * 507 * @return The top address of the heap after h 542 * @return The top address of the heap after having been updated (if 508 * ever) 543 * ever) 509 */ 544 */ 510 sos_uaddr_t 545 sos_uaddr_t 511 sos_umem_vmm_brk(struct sos_umem_vmm_as * as, 546 sos_umem_vmm_brk(struct sos_umem_vmm_as * as, 512 sos_uaddr_t new_top_uaddr); 547 sos_uaddr_t new_top_uaddr); 513 548 514 549 515 /* 550 /* 516 * Reserved functions 551 * Reserved functions 517 */ 552 */ 518 553 519 /** 554 /** 520 * Called by the main page fault handler when 555 * Called by the main page fault handler when a physical page is not 521 * mapped for the given address of the current 556 * mapped for the given address of the current address space. This 522 * function is called only if: 557 * function is called only if: 523 * - The access (read / write) is allowed on 558 * - The access (read / write) is allowed on this VR 524 * - no physical page is mapped yet 559 * - no physical page is mapped yet 525 * This function first calls the sos_paging_tr 560 * This function first calls the sos_paging_try_resolve_COW() to 526 * resolve the COW if a COW access pattern is 561 * resolve the COW if a COW access pattern is detected, and, if 527 * unsuccessful, the sos_umem_vmm_vr_ops::page 562 * unsuccessful, the sos_umem_vmm_vr_ops::page_in() method of the VR. 528 * 563 * 529 * @param uaddr The address that was accessed, 564 * @param uaddr The address that was accessed, causing the fault. 530 * 565 * 531 * @param write_access Was it write access ? 566 * @param write_access Was it write access ? 532 * 567 * 533 * @param user_access Was it a user access ? O 568 * @param user_access Was it a user access ? Or a kernel access (by 534 * uaccess.h functions) ? 569 * uaccess.h functions) ? 535 * 570 * 536 * @return SOS_OK when the fault could be solv 571 * @return SOS_OK when the fault could be solved, ie a page could be 537 * mapped for the given address. -SOS_EFAULT o 572 * mapped for the given address. -SOS_EFAULT otherwise, meaning the 538 * faulting thread should be terminated or sig 573 * faulting thread should be terminated or signalled (SIGSEGV) 539 * 574 * 540 * @note: The current mm_context MUST be that 575 * @note: The current mm_context MUST be that of the current thread 541 * (which caused the exception) ! 576 * (which caused the exception) ! 542 */ 577 */ 543 sos_ret_t sos_umem_vmm_try_resolve_page_fault( 578 sos_ret_t sos_umem_vmm_try_resolve_page_fault(sos_uaddr_t uaddr, 544 579 sos_bool_t write_access, 545 580 sos_bool_t user_access); 546 581 547 582 548 583 549 /** 584 /** 550 * Initialize the initial heap once the progra 585 * Initialize the initial heap once the program code/data is mapped 551 * Called by the ELF32 program loader. 586 * Called by the ELF32 program loader. 552 */ 587 */ 553 sos_ret_t 588 sos_ret_t 554 sos_umem_vmm_init_heap(struct sos_umem_vmm_as 589 sos_umem_vmm_init_heap(struct sos_umem_vmm_as * as, 555 sos_uaddr_t heap_start) 590 sos_uaddr_t heap_start); 556 591 557 #endif /* _SOS_UMEM_VMM_H_ */ 592 #endif /* _SOS_UMEM_VMM_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |