Changeset 00b595b in mainline
- Timestamp:
- 2006-05-27T21:53:24Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 46fc2f9
- Parents:
- 127c957b
- Location:
- generic/src/mm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified generic/src/mm/backend_anon.c ¶
r127c957b r00b595b 162 162 * to the pagemap. Page faults will primarily search for frames there. 163 163 * 164 * The address space a rea and page tablesmust be already locked.164 * The address space and address space area must be already locked. 165 165 * 166 166 * @param area Address space area to be shared. -
TabularUnified generic/src/mm/backend_elf.c ¶
r127c957b r00b595b 39 39 #include <mm/frame.h> 40 40 #include <mm/slab.h> 41 #include <mm/page.h> 42 #include <genarch/mm/page_pt.h> 43 #include <genarch/mm/page_ht.h> 41 44 #include <align.h> 42 45 #include <memstr.h> … … 46 49 static int elf_page_fault(as_area_t *area, __address addr, pf_access_t access); 47 50 static void elf_frame_free(as_area_t *area, __address page, __address frame); 51 static void elf_share(as_area_t *area); 48 52 49 53 mem_backend_t elf_backend = { 50 54 .page_fault = elf_page_fault, 51 55 .frame_free = elf_frame_free, 52 .share = NULL56 .share = elf_share 53 57 }; 54 58 … … 67 71 elf_header_t *elf = area->backend_data.elf; 68 72 elf_segment_header_t *entry = area->backend_data.segment; 73 btree_node_t *leaf; 69 74 __address base, frame; 70 75 index_t i; … … 77 82 base = (__address) (((void *) elf) + entry->p_offset); 78 83 ASSERT(ALIGN_UP(base, FRAME_SIZE) == base); 84 85 if (area->sh_info) { 86 bool found = false; 87 88 /* 89 * The address space area is shared. 90 */ 91 92 mutex_lock(&area->sh_info->lock); 93 frame = (__address) btree_search(&area->sh_info->pagemap, 94 ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf); 95 if (!frame) { 96 int i; 97 98 /* 99 * Workaround for valid NULL address. 100 */ 101 102 for (i = 0; i < leaf->keys; i++) { 103 if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) { 104 found = true; 105 break; 106 } 107 } 108 } 109 if (frame || found) { 110 page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); 111 if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) 112 panic("Could not insert used space.\n"); 113 mutex_unlock(&area->sh_info->lock); 114 return AS_PF_OK; 115 } 116 } 117 118 /* 119 * The area is either not shared or the pagemap does not contain the mapping. 120 */ 79 121 80 122 if (ALIGN_DOWN(addr, PAGE_SIZE) + PAGE_SIZE < entry->p_vaddr + entry->p_filesz) { … … 90 132 frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0)); 91 133 memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), FRAME_SIZE); 134 135 if (area->sh_info) { 136 btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, 137 (void *) frame, leaf); 138 } 139 92 140 } else { 93 141 frame = KA2PA(base + i*FRAME_SIZE); … … 102 150 frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0)); 103 151 memsetb(PA2KA(frame), FRAME_SIZE, 0); 152 153 if (area->sh_info) { 154 btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, 155 (void *) frame, leaf); 156 } 157 104 158 } else { 105 159 size_t size; … … 113 167 memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0); 114 168 memcpy((void *) PA2KA(frame), (void *) (base + i*FRAME_SIZE), size); 115 } 169 170 if (area->sh_info) { 171 btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, 172 (void *) frame, leaf); 173 } 174 175 } 176 177 if (area->sh_info) 178 mutex_unlock(&area->sh_info->lock); 116 179 117 180 page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); 118 119 181 if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) 182 panic("Could not insert used space.\n"); 120 183 121 184 return AS_PF_OK; … … 159 222 } 160 223 } 224 225 /** Share ELF image backed address space area. 226 * 227 * If the area is writable, then all mapped pages are duplicated in the pagemap. 228 * Otherwise only portions of the area that are not backed by the ELF image 229 * are put into the pagemap. 230 * 231 * The address space and address space area must be locked prior to the call. 232 * 233 * @param area Address space area. 234 */ 235 void elf_share(as_area_t *area) 236 { 237 elf_segment_header_t *entry = area->backend_data.segment; 238 link_t *cur; 239 btree_node_t *leaf, *node; 240 __address start_anon = entry->p_vaddr + entry->p_filesz; 241 242 /* 243 * Find the node in which to start linear search. 244 */ 245 if (area->flags & AS_AREA_WRITE) { 246 node = list_get_instance(area->used_space.leaf_head.next, btree_node_t, leaf_link); 247 } else { 248 (void) btree_search(&area->sh_info->pagemap, start_anon, &leaf); 249 node = btree_leaf_node_left_neighbour(&area->sh_info->pagemap, leaf); 250 if (!node) 251 node = leaf; 252 } 253 254 /* 255 * Copy used anonymous portions of the area to sh_info's page map. 256 */ 257 mutex_lock(&area->sh_info->lock); 258 for (cur = &node->leaf_link; cur != &area->used_space.leaf_head; cur = cur->next) { 259 int i; 260 261 node = list_get_instance(cur, btree_node_t, leaf_link); 262 263 for (i = 0; i < node->keys; i++) { 264 __address base = node->key[i]; 265 count_t count = (count_t) node->value[i]; 266 int j; 267 268 /* 269 * Skip read-only areas of used space that are backed 270 * by the ELF image. 271 */ 272 if (!(area->flags & AS_AREA_WRITE)) 273 if (base + count*PAGE_SIZE <= start_anon) 274 continue; 275 276 for (j = 0; j < count; j++) { 277 pte_t *pte; 278 279 /* 280 * Skip read-only pages that are backed by the ELF image. 281 */ 282 if (!(area->flags & AS_AREA_WRITE)) 283 if (base + (j + 1)*PAGE_SIZE <= start_anon) 284 continue; 285 286 page_table_lock(area->as, false); 287 pte = page_mapping_find(area->as, base + j*PAGE_SIZE); 288 ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); 289 btree_insert(&area->sh_info->pagemap, (base + j*PAGE_SIZE) - area->base, 290 (void *) PTE_GET_FRAME(pte), NULL); 291 page_table_unlock(area->as, false); 292 } 293 294 } 295 } 296 mutex_unlock(&area->sh_info->lock); 297 }
Note:
See TracChangeset
for help on using the changeset viewer.