Rev 1288 | Rev 1309 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1288 | Rev 1306 | ||
|---|---|---|---|
| Line 192... | Line 192... | ||
| 192 | * @param as Address space. |
192 | * @param as Address space. |
| 193 | * @param address Virtual address belonging to the area to be changed. Must be page-aligned. |
193 | * @param address Virtual address belonging to the area to be changed. Must be page-aligned. |
| 194 | * @param size New size of the virtual memory block starting at address. |
194 | * @param size New size of the virtual memory block starting at address. |
| 195 | * @param flags Flags influencing the remap operation. Currently unused. |
195 | * @param flags Flags influencing the remap operation. Currently unused. |
| 196 | * |
196 | * |
| 197 | * @return address on success, (__address) -1 otherwise. |
197 | * @return Zero on success or a value from @ref errno.h otherwise. |
| 198 | */ |
198 | */ |
| 199 | __address as_area_resize(as_t *as, __address address, size_t size, int flags) |
199 | int as_area_resize(as_t *as, __address address, size_t size, int flags) |
| 200 | { |
200 | { |
| 201 | as_area_t *area = NULL; |
201 | as_area_t *area; |
| 202 | ipl_t ipl; |
202 | ipl_t ipl; |
| 203 | size_t pages; |
203 | size_t pages; |
| 204 | 204 | ||
| 205 | ipl = interrupts_disable(); |
205 | ipl = interrupts_disable(); |
| 206 | spinlock_lock(&as->lock); |
206 | spinlock_lock(&as->lock); |
| Line 210... | Line 210... | ||
| 210 | */ |
210 | */ |
| 211 | area = find_area_and_lock(as, address); |
211 | area = find_area_and_lock(as, address); |
| 212 | if (!area) { |
212 | if (!area) { |
| 213 | spinlock_unlock(&as->lock); |
213 | spinlock_unlock(&as->lock); |
| 214 | interrupts_restore(ipl); |
214 | interrupts_restore(ipl); |
| 215 | return (__address) -1; |
215 | return ENOENT; |
| 216 | } |
216 | } |
| 217 | 217 | ||
| 218 | if (area->flags & AS_AREA_DEVICE) { |
218 | if (area->flags & AS_AREA_DEVICE) { |
| 219 | /* |
219 | /* |
| 220 | * Remapping of address space areas associated |
220 | * Remapping of address space areas associated |
| 221 | * with memory mapped devices is not supported. |
221 | * with memory mapped devices is not supported. |
| 222 | */ |
222 | */ |
| 223 | spinlock_unlock(&area->lock); |
223 | spinlock_unlock(&area->lock); |
| 224 | spinlock_unlock(&as->lock); |
224 | spinlock_unlock(&as->lock); |
| 225 | interrupts_restore(ipl); |
225 | interrupts_restore(ipl); |
| 226 | return (__address) -1; |
226 | return ENOTSUP; |
| 227 | } |
227 | } |
| 228 | 228 | ||
| 229 | pages = SIZE2FRAMES((address - area->base) + size); |
229 | pages = SIZE2FRAMES((address - area->base) + size); |
| 230 | if (!pages) { |
230 | if (!pages) { |
| 231 | /* |
231 | /* |
| 232 | * Zero size address space areas are not allowed. |
232 | * Zero size address space areas are not allowed. |
| 233 | */ |
233 | */ |
| 234 | spinlock_unlock(&area->lock); |
234 | spinlock_unlock(&area->lock); |
| 235 | spinlock_unlock(&as->lock); |
235 | spinlock_unlock(&as->lock); |
| 236 | interrupts_restore(ipl); |
236 | interrupts_restore(ipl); |
| 237 | return (__address) -1; |
237 | return EPERM; |
| 238 | } |
238 | } |
| 239 | 239 | ||
| 240 | if (pages < area->pages) { |
240 | if (pages < area->pages) { |
| 241 | int i; |
241 | int i; |
| 242 | 242 | ||
| Line 279... | Line 279... | ||
| 279 | */ |
279 | */ |
| 280 | if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { |
280 | if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { |
| 281 | spinlock_unlock(&area->lock); |
281 | spinlock_unlock(&area->lock); |
| 282 | spinlock_unlock(&as->lock); |
282 | spinlock_unlock(&as->lock); |
| 283 | interrupts_restore(ipl); |
283 | interrupts_restore(ipl); |
| 284 | return (__address) -1; |
284 | return EADDRNOTAVAIL; |
| 285 | } |
285 | } |
| 286 | } |
286 | } |
| 287 | 287 | ||
| 288 | area->pages = pages; |
288 | area->pages = pages; |
| 289 | 289 | ||
| 290 | spinlock_unlock(&area->lock); |
290 | spinlock_unlock(&area->lock); |
| 291 | spinlock_unlock(&as->lock); |
291 | spinlock_unlock(&as->lock); |
| 292 | interrupts_restore(ipl); |
292 | interrupts_restore(ipl); |
| 293 | 293 | ||
| - | 294 | return 0; |
|
| - | 295 | } |
|
| - | 296 | ||
| - | 297 | /** Destroy address space area. |
|
| - | 298 | * |
|
| - | 299 | * @param as Address space. |
|
| - | 300 | * @param address Address withing the area to be deleted. |
|
| - | 301 | * |
|
| - | 302 | * @return Zero on success or a value from @ref errno.h on failure. |
|
| - | 303 | */ |
|
| - | 304 | int as_area_destroy(as_t *as, __address address) |
|
| - | 305 | { |
|
| - | 306 | as_area_t *area; |
|
| - | 307 | __address base; |
|
| - | 308 | ipl_t ipl; |
|
| - | 309 | int i; |
|
| - | 310 | ||
| - | 311 | ipl = interrupts_disable(); |
|
| - | 312 | spinlock_lock(&as->lock); |
|
| - | 313 | ||
| - | 314 | area = find_area_and_lock(as, address); |
|
| - | 315 | if (!area) { |
|
| - | 316 | spinlock_unlock(&as->lock); |
|
| - | 317 | interrupts_restore(ipl); |
|
| 294 | return address; |
318 | return ENOENT; |
| - | 319 | } |
|
| - | 320 | ||
| - | 321 | base = area->base; |
|
| - | 322 | for (i = 0; i < area->pages; i++) { |
|
| - | 323 | pte_t *pte; |
|
| - | 324 | ||
| - | 325 | /* |
|
| - | 326 | * Releasing physical memory. |
|
| - | 327 | * Areas mapping memory-mapped devices are treated differently than |
|
| - | 328 | * areas backing frame_alloc()'ed memory. |
|
| - | 329 | */ |
|
| - | 330 | page_table_lock(as, false); |
|
| - | 331 | pte = page_mapping_find(as, area->base + i*PAGE_SIZE); |
|
| - | 332 | if (pte && PTE_VALID(pte)) { |
|
| - | 333 | ASSERT(PTE_PRESENT(pte)); |
|
| - | 334 | page_mapping_remove(as, area->base + i*PAGE_SIZE); |
|
| - | 335 | if (area->flags & AS_AREA_DEVICE) { |
|
| - | 336 | __address frame; |
|
| - | 337 | frame = PTE_GET_FRAME(pte); |
|
| - | 338 | frame_free(ADDR2PFN(frame)); |
|
| - | 339 | } |
|
| - | 340 | page_table_unlock(as, false); |
|
| - | 341 | } else { |
|
| - | 342 | page_table_unlock(as, false); |
|
| - | 343 | } |
|
| - | 344 | } |
|
| - | 345 | /* |
|
| - | 346 | * Invalidate TLB's. |
|
| - | 347 | */ |
|
| - | 348 | tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages); |
|
| - | 349 | tlb_invalidate_pages(AS->asid, area->base, area->pages); |
|
| - | 350 | tlb_shootdown_finalize(); |
|
| - | 351 | ||
| - | 352 | spinlock_unlock(&area->lock); |
|
| - | 353 | ||
| - | 354 | /* |
|
| - | 355 | * Remove the empty area from address space. |
|
| - | 356 | */ |
|
| - | 357 | btree_remove(&AS->as_area_btree, base, NULL); |
|
| - | 358 | ||
| - | 359 | spinlock_unlock(&AS->lock); |
|
| - | 360 | interrupts_restore(ipl); |
|
| - | 361 | return 0; |
|
| 295 | } |
362 | } |
| 296 | 363 | ||
| 297 | /** Send address space area to another task. |
364 | /** Send address space area to another task. |
| 298 | * |
365 | * |
| 299 | * Address space area is sent to the specified task. |
366 | * Address space area is sent to the specified task. |
| Line 305... | Line 372... | ||
| 305 | * space area and any associated mapping is preserved. |
372 | * space area and any associated mapping is preserved. |
| 306 | * |
373 | * |
| 307 | * @param dst_id Task ID of the accepting task. |
374 | * @param dst_id Task ID of the accepting task. |
| 308 | * @param src_base Base address of the source address space area. |
375 | * @param src_base Base address of the source address space area. |
| 309 | * |
376 | * |
| 310 | * @return 0 on success or ENOENT if there is no such task or |
377 | * @return Zero on success or ENOENT if there is no such task or |
| 311 | * if there is no such address space area, |
378 | * if there is no such address space area, |
| 312 | * EPERM if there was a problem in accepting the area or |
379 | * EPERM if there was a problem in accepting the area or |
| 313 | * ENOMEM if there was a problem in allocating destination |
380 | * ENOMEM if there was a problem in allocating destination |
| 314 | * address space area. |
381 | * address space area. |
| 315 | */ |
382 | */ |
| Line 889... | Line 956... | ||
| 889 | } |
956 | } |
| 890 | 957 | ||
| 891 | /** Wrapper for as_area_resize. */ |
958 | /** Wrapper for as_area_resize. */ |
| 892 | __native sys_as_area_resize(__address address, size_t size, int flags) |
959 | __native sys_as_area_resize(__address address, size_t size, int flags) |
| 893 | { |
960 | { |
| 894 | return as_area_resize(AS, address, size, 0); |
961 | return (__native) as_area_resize(AS, address, size, 0); |
| - | 962 | } |
|
| - | 963 | ||
| - | 964 | /** Wrapper for as_area_destroy. */ |
|
| - | 965 | __native sys_as_area_destroy(__address address) |
|
| - | 966 | { |
|
| - | 967 | return (__native) as_area_destroy(AS, address); |
|
| 895 | } |
968 | } |
| 896 | 969 | ||
| 897 | /** Prepare task for accepting address space area from another task. |
970 | /** Prepare task for accepting address space area from another task. |
| 898 | * |
971 | * |
| 899 | * @param uspace_accept_arg Accept structure passed from userspace. |
972 | * @param uspace_accept_arg Accept structure passed from userspace. |