Rev 1423 | Rev 1428 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 1423 | Rev 1424 | ||
|---|---|---|---|
| Line 72... | Line 72... | ||
| 72 | #include <arch/types.h> |
72 | #include <arch/types.h> |
| 73 | #include <typedefs.h> |
73 | #include <typedefs.h> |
| 74 | #include <syscall/copy.h> |
74 | #include <syscall/copy.h> |
| 75 | #include <arch/interrupt.h> |
75 | #include <arch/interrupt.h> |
| 76 | 76 | ||
| 77 | /** This structure contains information associated with the shared address space area. */ |
- | |
| 78 | struct share_info { |
- | |
| 79 | mutex_t lock; /**< This lock must be acquired only when the as_area lock is held. */ |
- | |
| 80 | count_t refcount; /**< This structure can be deallocated if refcount drops to 0. */ |
- | |
| 81 | btree_t pagemap; /**< B+tree containing complete map of anonymous pages of the shared area. */ |
- | |
| 82 | }; |
- | |
| 83 | - | ||
| 84 | as_operations_t *as_operations = NULL; |
77 | as_operations_t *as_operations = NULL; |
| 85 | 78 | ||
| 86 | /** This lock protects inactive_as_with_asid_head list. It must be acquired before as_t mutex. */ |
79 | /** This lock protects inactive_as_with_asid_head list. It must be acquired before as_t mutex. */ |
| 87 | SPINLOCK_INITIALIZE(inactive_as_with_asid_lock); |
80 | SPINLOCK_INITIALIZE(inactive_as_with_asid_lock); |
| 88 | 81 | ||
| Line 157... | Line 150... | ||
| 157 | * @param backend_data NULL or a pointer to an array holding two void *. |
150 | * @param backend_data NULL or a pointer to an array holding two void *. |
| 158 | * |
151 | * |
| 159 | * @return Address space area on success or NULL on failure. |
152 | * @return Address space area on success or NULL on failure. |
| 160 | */ |
153 | */ |
| 161 | as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs, |
154 | as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs, |
| 162 | mem_backend_t *backend, void **backend_data) |
155 | mem_backend_t *backend, mem_backend_data_t *backend_data) |
| 163 | { |
156 | { |
| 164 | ipl_t ipl; |
157 | ipl_t ipl; |
| 165 | as_area_t *a; |
158 | as_area_t *a; |
| 166 | 159 | ||
| 167 | if (base % PAGE_SIZE) |
160 | if (base % PAGE_SIZE) |
| Line 185... | Line 178... | ||
| 185 | 178 | ||
| 186 | a = (as_area_t *) malloc(sizeof(as_area_t), 0); |
179 | a = (as_area_t *) malloc(sizeof(as_area_t), 0); |
| 187 | 180 | ||
| 188 | mutex_initialize(&a->lock); |
181 | mutex_initialize(&a->lock); |
| 189 | 182 | ||
| - | 183 | a->as = as; |
|
| 190 | a->flags = flags; |
184 | a->flags = flags; |
| 191 | a->attributes = attrs; |
185 | a->attributes = attrs; |
| 192 | a->pages = SIZE2FRAMES(size); |
186 | a->pages = SIZE2FRAMES(size); |
| 193 | a->base = base; |
187 | a->base = base; |
| 194 | a->sh_info = NULL; |
188 | a->sh_info = NULL; |
| 195 | a->backend = backend; |
189 | a->backend = backend; |
| 196 | if (backend_data) { |
190 | if (backend_data) |
| 197 | a->backend_data[0] = backend_data[0]; |
191 | a->backend_data = *backend_data; |
| - | 192 | else |
|
| 198 | a->backend_data[1] = backend_data[1]; |
193 | memsetb((__address) &a->backend_data, sizeof(a->backend_data), 0); |
| 199 | } |
194 | |
| 200 | btree_create(&a->used_space); |
195 | btree_create(&a->used_space); |
| 201 | 196 | ||
| 202 | btree_insert(&as->as_area_btree, base, (void *) a, NULL); |
197 | btree_insert(&as->as_area_btree, base, (void *) a, NULL); |
| 203 | 198 | ||
| 204 | mutex_unlock(&as->lock); |
199 | mutex_unlock(&as->lock); |
| Line 233... | Line 228... | ||
| 233 | mutex_unlock(&as->lock); |
228 | mutex_unlock(&as->lock); |
| 234 | interrupts_restore(ipl); |
229 | interrupts_restore(ipl); |
| 235 | return ENOENT; |
230 | return ENOENT; |
| 236 | } |
231 | } |
| 237 | 232 | ||
| 238 | if (area->flags & AS_AREA_DEVICE) { |
233 | if (area->backend == &phys_backend) { |
| 239 | /* |
234 | /* |
| 240 | * Remapping of address space areas associated |
235 | * Remapping of address space areas associated |
| 241 | * with memory mapped devices is not supported. |
236 | * with memory mapped devices is not supported. |
| 242 | */ |
237 | */ |
| 243 | mutex_unlock(&area->lock); |
238 | mutex_unlock(&area->lock); |
| Line 324... | Line 319... | ||
| 324 | pte_t *pte; |
319 | pte_t *pte; |
| 325 | 320 | ||
| 326 | page_table_lock(as, false); |
321 | page_table_lock(as, false); |
| 327 | pte = page_mapping_find(as, b + i*PAGE_SIZE); |
322 | pte = page_mapping_find(as, b + i*PAGE_SIZE); |
| 328 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
323 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
| 329 | if (area->backend && area->backend->backend_frame_free) { |
324 | if (area->backend && area->backend->frame_free) { |
| 330 | area->backend->backend_frame_free(area, |
325 | area->backend->frame_free(area, |
| 331 | b + i*PAGE_SIZE, PTE_GET_FRAME(pte)); |
326 | b + i*PAGE_SIZE, PTE_GET_FRAME(pte)); |
| 332 | } |
327 | } |
| 333 | page_mapping_remove(as, b + i*PAGE_SIZE); |
328 | page_mapping_remove(as, b + i*PAGE_SIZE); |
| 334 | page_table_unlock(as, false); |
329 | page_table_unlock(as, false); |
| 335 | } |
330 | } |
| Line 409... | Line 404... | ||
| 409 | 404 | ||
| 410 | for (i = 0; i < (count_t) node->value[0]; i++) { |
405 | for (i = 0; i < (count_t) node->value[0]; i++) { |
| 411 | page_table_lock(as, false); |
406 | page_table_lock(as, false); |
| 412 | pte = page_mapping_find(as, b + i*PAGE_SIZE); |
407 | pte = page_mapping_find(as, b + i*PAGE_SIZE); |
| 413 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
408 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
| 414 | if (area->backend && area->backend->backend_frame_free) { |
409 | if (area->backend && area->backend->frame_free) { |
| 415 | area->backend->backend_frame_free(area, |
410 | area->backend->frame_free(area, |
| 416 | b + i*PAGE_SIZE, PTE_GET_FRAME(pte)); |
411 | b + i*PAGE_SIZE, PTE_GET_FRAME(pte)); |
| 417 | } |
412 | } |
| 418 | page_mapping_remove(as, b + i*PAGE_SIZE); |
413 | page_mapping_remove(as, b + i*PAGE_SIZE); |
| 419 | page_table_unlock(as, false); |
414 | page_table_unlock(as, false); |
| 420 | } |
415 | } |
| Line 450... | Line 445... | ||
| 450 | return 0; |
445 | return 0; |
| 451 | } |
446 | } |
| 452 | 447 | ||
| 453 | /** Share address space area with another or the same address space. |
448 | /** Share address space area with another or the same address space. |
| 454 | * |
449 | * |
| 455 | * Address space area of anonymous memory is shared with a new address |
450 | * Address space area mapping is shared with a new address space area. |
| 456 | * space area. If the source address space area has not been shared so |
451 | * If the source address space area has not been shared so far, |
| 457 | * far, a new sh_info is created and the original mapping is duplicated |
452 | * a new sh_info is created. The new address space area simply gets the |
| 458 | * in its pagemap B+tree. The new address space are simply gets the |
453 | * sh_info of the source area. The process of duplicating the |
| 459 | * sh_info of the source area. |
454 | * mapping is done through the backend share function. |
| 460 | * |
455 | * |
| 461 | * @param src_as Pointer to source address space. |
456 | * @param src_as Pointer to source address space. |
| 462 | * @param src_base Base address of the source address space area. |
457 | * @param src_base Base address of the source address space area. |
| 463 | * @param acc_size Expected size of the source area. |
458 | * @param acc_size Expected size of the source area. |
| 464 | * @param dst_base Target base address. |
459 | * @param dst_base Target base address. |
| Line 477... | Line 472... | ||
| 477 | ipl_t ipl; |
472 | ipl_t ipl; |
| 478 | int src_flags; |
473 | int src_flags; |
| 479 | size_t src_size; |
474 | size_t src_size; |
| 480 | as_area_t *src_area, *dst_area; |
475 | as_area_t *src_area, *dst_area; |
| 481 | share_info_t *sh_info; |
476 | share_info_t *sh_info; |
| 482 | link_t *cur; |
477 | mem_backend_t *src_backend; |
| - | 478 | mem_backend_data_t src_backend_data; |
|
| 483 | 479 | ||
| 484 | ipl = interrupts_disable(); |
480 | ipl = interrupts_disable(); |
| 485 | mutex_lock(&src_as->lock); |
481 | mutex_lock(&src_as->lock); |
| 486 | src_area = find_area_and_lock(src_as, src_base); |
482 | src_area = find_area_and_lock(src_as, src_base); |
| 487 | if (!src_area) { |
483 | if (!src_area) { |
| Line 491... | Line 487... | ||
| 491 | mutex_unlock(&src_as->lock); |
487 | mutex_unlock(&src_as->lock); |
| 492 | interrupts_restore(ipl); |
488 | interrupts_restore(ipl); |
| 493 | return ENOENT; |
489 | return ENOENT; |
| 494 | } |
490 | } |
| 495 | 491 | ||
| 496 | if (!src_area->backend || src_area->backend != &anon_backend) { |
492 | if (!src_area->backend || !src_area->backend->share) { |
| 497 | /* |
493 | /* |
| 498 | * As of now, only anonymous address space areas can be shared. |
494 | * There is now backend or the backend does not |
| - | 495 | * know how to share the area. |
|
| 499 | */ |
496 | */ |
| 500 | mutex_unlock(&src_area->lock); |
497 | mutex_unlock(&src_area->lock); |
| 501 | mutex_unlock(&src_as->lock); |
498 | mutex_unlock(&src_as->lock); |
| 502 | interrupts_restore(ipl); |
499 | interrupts_restore(ipl); |
| 503 | return ENOTSUP; |
500 | return ENOTSUP; |
| 504 | } |
501 | } |
| 505 | 502 | ||
| 506 | src_size = src_area->pages * PAGE_SIZE; |
503 | src_size = src_area->pages * PAGE_SIZE; |
| 507 | src_flags = src_area->flags; |
504 | src_flags = src_area->flags; |
| - | 505 | src_backend = src_area->backend; |
|
| - | 506 | src_backend_data = src_area->backend_data; |
|
| 508 | 507 | ||
| 509 | if (src_size != acc_size) { |
508 | if (src_size != acc_size) { |
| 510 | mutex_unlock(&src_area->lock); |
509 | mutex_unlock(&src_area->lock); |
| 511 | mutex_unlock(&src_as->lock); |
510 | mutex_unlock(&src_as->lock); |
| 512 | interrupts_restore(ipl); |
511 | interrupts_restore(ipl); |
| Line 529... | Line 528... | ||
| 529 | mutex_lock(&sh_info->lock); |
528 | mutex_lock(&sh_info->lock); |
| 530 | sh_info->refcount++; |
529 | sh_info->refcount++; |
| 531 | mutex_unlock(&sh_info->lock); |
530 | mutex_unlock(&sh_info->lock); |
| 532 | } |
531 | } |
| 533 | 532 | ||
| 534 | /* |
- | |
| 535 | * Copy used portions of the area to sh_info's page map. |
- | |
| 536 | */ |
- | |
| 537 | mutex_lock(&sh_info->lock); |
- | |
| 538 | for (cur = src_area->used_space.leaf_head.next; cur != &src_area->used_space.leaf_head; cur = cur->next) { |
- | |
| 539 | btree_node_t *node; |
- | |
| 540 | int i; |
- | |
| 541 | - | ||
| 542 | node = list_get_instance(cur, btree_node_t, leaf_link); |
- | |
| 543 | for (i = 0; i < node->keys; i++) { |
- | |
| 544 | __address base = node->key[i]; |
- | |
| 545 | count_t count = (count_t) node->value[i]; |
- | |
| 546 | int j; |
- | |
| 547 | - | ||
| 548 | for (j = 0; j < count; j++) { |
- | |
| 549 | pte_t *pte; |
- | |
| 550 | - | ||
| 551 | page_table_lock(src_as, false); |
- | |
| 552 | pte = page_mapping_find(src_as, base + j*PAGE_SIZE); |
- | |
| 553 | ASSERT(pte && PTE_VALID(pte) && PTE_PRESENT(pte)); |
- | |
| 554 | btree_insert(&sh_info->pagemap, (base + j*PAGE_SIZE) - src_area->base, |
- | |
| 555 | (void *) PTE_GET_FRAME(pte), NULL); |
- | |
| 556 | page_table_unlock(src_as, false); |
533 | src_area->backend->share(src_area); |
| 557 | } |
- | |
| 558 | - | ||
| 559 | } |
- | |
| 560 | } |
- | |
| 561 | mutex_unlock(&sh_info->lock); |
- | |
| 562 | 534 | ||
| 563 | mutex_unlock(&src_area->lock); |
535 | mutex_unlock(&src_area->lock); |
| 564 | mutex_unlock(&src_as->lock); |
536 | mutex_unlock(&src_as->lock); |
| 565 | 537 | ||
| 566 | /* |
538 | /* |
| Line 570... | Line 542... | ||
| 570 | * preliminary as_page_fault() calls. |
542 | * preliminary as_page_fault() calls. |
| 571 | * The flags of the source area are masked against dst_flags_mask |
543 | * The flags of the source area are masked against dst_flags_mask |
| 572 | * to support sharing in less privileged mode. |
544 | * to support sharing in less privileged mode. |
| 573 | */ |
545 | */ |
| 574 | dst_area = as_area_create(AS, src_flags & dst_flags_mask, src_size, dst_base, |
546 | dst_area = as_area_create(AS, src_flags & dst_flags_mask, src_size, dst_base, |
| 575 | AS_AREA_ATTR_PARTIAL, &anon_backend, NULL); |
547 | AS_AREA_ATTR_PARTIAL, src_backend, &src_backend_data); |
| 576 | if (!dst_area) { |
548 | if (!dst_area) { |
| 577 | /* |
549 | /* |
| 578 | * Destination address space area could not be created. |
550 | * Destination address space area could not be created. |
| 579 | */ |
551 | */ |
| 580 | sh_info_remove_reference(sh_info); |
552 | sh_info_remove_reference(sh_info); |
| Line 596... | Line 568... | ||
| 596 | interrupts_restore(ipl); |
568 | interrupts_restore(ipl); |
| 597 | 569 | ||
| 598 | return 0; |
570 | return 0; |
| 599 | } |
571 | } |
| 600 | 572 | ||
| 601 | /** Initialize mapping for one page of address space. |
- | |
| 602 | * |
- | |
| 603 | * This functions maps 'page' to 'frame' according |
- | |
| 604 | * to attributes of the address space area to |
- | |
| 605 | * wich 'page' belongs. |
- | |
| 606 | * |
- | |
| 607 | * @param as Target address space. |
- | |
| 608 | * @param page Virtual page within the area. |
- | |
| 609 | * @param frame Physical frame to which page will be mapped. |
- | |
| 610 | */ |
- | |
| 611 | void as_set_mapping(as_t *as, __address page, __address frame) |
- | |
| 612 | { |
- | |
| 613 | as_area_t *area; |
- | |
| 614 | ipl_t ipl; |
- | |
| 615 | - | ||
| 616 | ipl = interrupts_disable(); |
- | |
| 617 | page_table_lock(as, true); |
- | |
| 618 | - | ||
| 619 | area = find_area_and_lock(as, page); |
- | |
| 620 | if (!area) { |
- | |
| 621 | panic("Page not part of any as_area.\n"); |
- | |
| 622 | } |
- | |
| 623 | - | ||
| 624 | ASSERT(!area->backend); |
- | |
| 625 | - | ||
| 626 | page_mapping_insert(as, page, frame, as_area_get_flags(area)); |
- | |
| 627 | if (!used_space_insert(area, page, 1)) |
- | |
| 628 | panic("Could not insert used space.\n"); |
- | |
| 629 | - | ||
| 630 | mutex_unlock(&area->lock); |
- | |
| 631 | page_table_unlock(as, true); |
- | |
| 632 | interrupts_restore(ipl); |
- | |
| 633 | } |
- | |
| 634 | - | ||
| 635 | /** Check access mode for address space area. |
573 | /** Check access mode for address space area. |
| 636 | * |
574 | * |
| 637 | * The address space area must be locked prior to this call. |
575 | * The address space area must be locked prior to this call. |
| 638 | * |
576 | * |
| 639 | * @param area Address space area. |
577 | * @param area Address space area. |
| Line 700... | Line 638... | ||
| 700 | mutex_unlock(&area->lock); |
638 | mutex_unlock(&area->lock); |
| 701 | mutex_unlock(&AS->lock); |
639 | mutex_unlock(&AS->lock); |
| 702 | goto page_fault; |
640 | goto page_fault; |
| 703 | } |
641 | } |
| 704 | 642 | ||
| 705 | if (!area->backend || !area->backend->backend_page_fault) { |
643 | if (!area->backend || !area->backend->page_fault) { |
| 706 | /* |
644 | /* |
| 707 | * The address space area is not backed by any backend |
645 | * The address space area is not backed by any backend |
| 708 | * or the backend cannot handle page faults. |
646 | * or the backend cannot handle page faults. |
| 709 | */ |
647 | */ |
| 710 | mutex_unlock(&area->lock); |
648 | mutex_unlock(&area->lock); |
| Line 733... | Line 671... | ||
| 733 | } |
671 | } |
| 734 | 672 | ||
| 735 | /* |
673 | /* |
| 736 | * Resort to the backend page fault handler. |
674 | * Resort to the backend page fault handler. |
| 737 | */ |
675 | */ |
| 738 | if (area->backend->backend_page_fault(area, page, access) != AS_PF_OK) { |
676 | if (area->backend->page_fault(area, page, access) != AS_PF_OK) { |
| 739 | page_table_unlock(AS, false); |
677 | page_table_unlock(AS, false); |
| 740 | mutex_unlock(&area->lock); |
678 | mutex_unlock(&area->lock); |
| 741 | mutex_unlock(&AS->lock); |
679 | mutex_unlock(&AS->lock); |
| 742 | goto page_fault; |
680 | goto page_fault; |
| 743 | } |
681 | } |
| Line 852... | Line 790... | ||
| 852 | flags |= PAGE_WRITE; |
790 | flags |= PAGE_WRITE; |
| 853 | 791 | ||
| 854 | if (aflags & AS_AREA_EXEC) |
792 | if (aflags & AS_AREA_EXEC) |
| 855 | flags |= PAGE_EXEC; |
793 | flags |= PAGE_EXEC; |
| 856 | 794 | ||
| 857 | if (!(aflags & AS_AREA_DEVICE)) |
795 | if (aflags & AS_AREA_CACHEABLE) |
| 858 | flags |= PAGE_CACHEABLE; |
796 | flags |= PAGE_CACHEABLE; |
| 859 | 797 | ||
| 860 | return flags; |
798 | return flags; |
| 861 | } |
799 | } |
| 862 | 800 | ||
| Line 1495... | Line 1433... | ||
| 1495 | btree_destroy(&sh_info->pagemap); |
1433 | btree_destroy(&sh_info->pagemap); |
| 1496 | free(sh_info); |
1434 | free(sh_info); |
| 1497 | } |
1435 | } |
| 1498 | } |
1436 | } |
| 1499 | 1437 | ||
| 1500 | static int anon_page_fault(as_area_t *area, __address addr, pf_access_t access); |
- | |
| 1501 | static void anon_frame_free(as_area_t *area, __address page, __address frame); |
- | |
| 1502 | - | ||
| 1503 | /* |
- | |
| 1504 | * Anonymous memory backend. |
- | |
| 1505 | */ |
- | |
| 1506 | mem_backend_t anon_backend = { |
- | |
| 1507 | .backend_page_fault = anon_page_fault, |
- | |
| 1508 | .backend_frame_free = anon_frame_free |
- | |
| 1509 | }; |
- | |
| 1510 | - | ||
| 1511 | /** Service a page fault in the anonymous memory address space area. |
- | |
| 1512 | * |
- | |
| 1513 | * The address space area and page tables must be already locked. |
- | |
| 1514 | * |
- | |
| 1515 | * @param area Pointer to the address space area. |
- | |
| 1516 | * @param addr Faulting virtual address. |
- | |
| 1517 | * @param access Access mode that caused the fault (i.e. read/write/exec). |
- | |
| 1518 | * |
- | |
| 1519 | * @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. serviced). |
- | |
| 1520 | */ |
- | |
| 1521 | int anon_page_fault(as_area_t *area, __address addr, pf_access_t access) |
- | |
| 1522 | { |
- | |
| 1523 | __address frame; |
- | |
| 1524 | - | ||
| 1525 | if (!as_area_check_access(area, access)) |
- | |
| 1526 | return AS_PF_FAULT; |
- | |
| 1527 | - | ||
| 1528 | if (area->sh_info) { |
- | |
| 1529 | btree_node_t *leaf; |
- | |
| 1530 | - | ||
| 1531 | /* |
- | |
| 1532 | * The area is shared, chances are that the mapping can be found |
- | |
| 1533 | * in the pagemap of the address space area share info structure. |
- | |
| 1534 | * In the case that the pagemap does not contain the respective |
- | |
| 1535 | * mapping, a new frame is allocated and the mapping is created. |
- | |
| 1536 | */ |
- | |
| 1537 | mutex_lock(&area->sh_info->lock); |
- | |
| 1538 | frame = (__address) btree_search(&area->sh_info->pagemap, |
- | |
| 1539 | ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf); |
- | |
| 1540 | if (!frame) { |
- | |
| 1541 | bool allocate = true; |
- | |
| 1542 | int i; |
- | |
| 1543 | - | ||
| 1544 | /* |
- | |
| 1545 | * Zero can be returned as a valid frame address. |
- | |
| 1546 | * Just a small workaround. |
- | |
| 1547 | */ |
- | |
| 1548 | for (i = 0; i < leaf->keys; i++) { |
- | |
| 1549 | if (leaf->key[i] == ALIGN_DOWN(addr, PAGE_SIZE)) { |
- | |
| 1550 | allocate = false; |
- | |
| 1551 | break; |
- | |
| 1552 | } |
- | |
| 1553 | } |
- | |
| 1554 | if (allocate) { |
- | |
| 1555 | frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0)); |
- | |
| 1556 | memsetb(PA2KA(frame), FRAME_SIZE, 0); |
- | |
| 1557 | - | ||
| 1558 | /* |
- | |
| 1559 | * Insert the address of the newly allocated frame to the pagemap. |
- | |
| 1560 | */ |
- | |
| 1561 | btree_insert(&area->sh_info->pagemap, ALIGN_DOWN(addr, PAGE_SIZE) - area->base, (void *) frame, leaf); |
- | |
| 1562 | } |
- | |
| 1563 | } |
- | |
| 1564 | mutex_unlock(&area->sh_info->lock); |
- | |
| 1565 | } else { |
- | |
| 1566 | - | ||
| 1567 | /* |
- | |
| 1568 | * In general, there can be several reasons that |
- | |
| 1569 | * can have caused this fault. |
- | |
| 1570 | * |
- | |
| 1571 | * - non-existent mapping: the area is an anonymous |
- | |
| 1572 | * area (e.g. heap or stack) and so far has not been |
- | |
| 1573 | * allocated a frame for the faulting page |
- | |
| 1574 | * |
- | |
| 1575 | * - non-present mapping: another possibility, |
- | |
| 1576 | * currently not implemented, would be frame |
- | |
| 1577 | * reuse; when this becomes a possibility, |
- | |
| 1578 | * do not forget to distinguish between |
- | |
| 1579 | * the different causes |
- | |
| 1580 | */ |
- | |
| 1581 | frame = PFN2ADDR(frame_alloc(ONE_FRAME, 0)); |
- | |
| 1582 | memsetb(PA2KA(frame), FRAME_SIZE, 0); |
- | |
| 1583 | } |
- | |
| 1584 | - | ||
| 1585 | /* |
- | |
| 1586 | * Map 'page' to 'frame'. |
- | |
| 1587 | * Note that TLB shootdown is not attempted as only new information is being |
- | |
| 1588 | * inserted into page tables. |
- | |
| 1589 | */ |
- | |
| 1590 | page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); |
- | |
| 1591 | if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
- | |
| 1592 | panic("Could not insert used space.\n"); |
- | |
| 1593 | - | ||
| 1594 | return AS_PF_OK; |
- | |
| 1595 | } |
- | |
| 1596 | - | ||
| 1597 | /** Free a frame that is backed by the anonymous memory backend. |
- | |
| 1598 | * |
- | |
| 1599 | * The address space area and page tables must be already locked. |
- | |
| 1600 | * |
- | |
| 1601 | * @param area Ignored. |
- | |
| 1602 | * @param page Ignored. |
- | |
| 1603 | * @param frame Frame to be released. |
- | |
| 1604 | */ |
- | |
| 1605 | void anon_frame_free(as_area_t *area, __address page, __address frame) |
- | |
| 1606 | { |
- | |
| 1607 | frame_free(ADDR2PFN(frame)); |
- | |
| 1608 | } |
- | |
| 1609 | - | ||
| 1610 | /* |
1438 | /* |
| 1611 | * Address space related syscalls. |
1439 | * Address space related syscalls. |
| 1612 | */ |
1440 | */ |
| 1613 | 1441 | ||
| 1614 | /** Wrapper for as_area_create(). */ |
1442 | /** Wrapper for as_area_create(). */ |
| 1615 | __native sys_as_area_create(__address address, size_t size, int flags) |
1443 | __native sys_as_area_create(__address address, size_t size, int flags) |
| 1616 | { |
1444 | { |
| 1617 | if (as_area_create(AS, flags, size, address, AS_AREA_ATTR_NONE, &anon_backend, NULL)) |
1445 | if (as_area_create(AS, flags | AS_AREA_CACHEABLE, size, address, AS_AREA_ATTR_NONE, &anon_backend, NULL)) |
| 1618 | return (__native) address; |
1446 | return (__native) address; |
| 1619 | else |
1447 | else |
| 1620 | return (__native) -1; |
1448 | return (__native) -1; |
| 1621 | } |
1449 | } |
| 1622 | 1450 | ||