Changes in kernel/generic/src/mm/as.c [fc47885:7250d2c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
rfc47885 r7250d2c 71 71 #include <memstr.h> 72 72 #include <macros.h> 73 #include <bitops.h> 73 74 #include <arch.h> 74 75 #include <errno.h> … … 79 80 #include <arch/interrupt.h> 80 81 81 #ifdef CONFIG_VIRT_IDX_DCACHE82 #include <arch/mm/cache.h>83 #endif /* CONFIG_VIRT_IDX_DCACHE */84 85 82 /** 86 83 * Each architecture decides what functions will be used to carry out … … 97 94 * 98 95 * This lock protects: 99 * - inactive_as_with_asid_ headlist96 * - inactive_as_with_asid_list 100 97 * - as->asid for each as of the as_t type 101 98 * - asids_allocated counter … … 108 105 * that have valid ASID. 109 106 */ 110 LIST_INITIALIZE(inactive_as_with_asid_ head);107 LIST_INITIALIZE(inactive_as_with_asid_list); 111 108 112 109 /** Kernel address space. */ … … 238 235 bool cond = true; 239 236 while (cond) { 240 ASSERT(!list_empty(&as->as_area_btree.leaf_ head));237 ASSERT(!list_empty(&as->as_area_btree.leaf_list)); 241 238 242 239 btree_node_t *node = 243 list_get_instance( as->as_area_btree.leaf_head.next,240 list_get_instance(list_first(&as->as_area_btree.leaf_list), 244 241 btree_node_t, leaf_link); 245 242 … … 288 285 /** Check area conflicts with other areas. 289 286 * 290 * @param as 291 * @param vaStarting virtual address of the area being tested.292 * @param size Size ofthe area being tested.293 * @param avoid _areaDo not touch this area.287 * @param as Address space. 288 * @param addr Starting virtual address of the area being tested. 289 * @param count Number of pages in the area being tested. 290 * @param avoid Do not touch this area. 294 291 * 295 292 * @return True if there is no conflict, false otherwise. 296 293 * 297 294 */ 298 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, 299 as_area_t *avoid_area) 300 { 295 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t addr, 296 size_t count, as_area_t *avoid) 297 { 298 ASSERT((addr % PAGE_SIZE) == 0); 301 299 ASSERT(mutex_locked(&as->lock)); 302 300 … … 304 302 * We don't want any area to have conflicts with NULL page. 305 303 */ 306 if (overlaps( va, size, (uintptr_t) NULL, PAGE_SIZE))304 if (overlaps(addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE)) 307 305 return false; 308 306 … … 316 314 btree_node_t *leaf; 317 315 as_area_t *area = 318 (as_area_t *) btree_search(&as->as_area_btree, va, &leaf);316 (as_area_t *) btree_search(&as->as_area_btree, addr, &leaf); 319 317 if (area) { 320 if (area != avoid _area)318 if (area != avoid) 321 319 return false; 322 320 } … … 328 326 area = (as_area_t *) node->value[node->keys - 1]; 329 327 330 mutex_lock(&area->lock); 331 332 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 328 if (area != avoid) { 329 mutex_lock(&area->lock); 330 331 if (overlaps(addr, P2SZ(count), area->base, 332 P2SZ(area->pages))) { 333 mutex_unlock(&area->lock); 334 return false; 335 } 336 333 337 mutex_unlock(&area->lock); 334 return false; 335 } 336 337 mutex_unlock(&area->lock); 338 } 338 339 } 339 340 … … 342 343 area = (as_area_t *) node->value[0]; 343 344 344 mutex_lock(&area->lock); 345 346 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 345 if (area != avoid) { 346 mutex_lock(&area->lock); 347 348 if (overlaps(addr, P2SZ(count), area->base, 349 P2SZ(area->pages))) { 350 mutex_unlock(&area->lock); 351 return false; 352 } 353 347 354 mutex_unlock(&area->lock); 348 return false; 349 } 350 351 mutex_unlock(&area->lock); 355 } 352 356 } 353 357 … … 357 361 area = (as_area_t *) leaf->value[i]; 358 362 359 if (area == avoid _area)363 if (area == avoid) 360 364 continue; 361 365 362 366 mutex_lock(&area->lock); 363 367 364 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 368 if (overlaps(addr, P2SZ(count), area->base, 369 P2SZ(area->pages))) { 365 370 mutex_unlock(&area->lock); 366 371 return false; … … 375 380 */ 376 381 if (!KERNEL_ADDRESS_SPACE_SHADOWED) { 377 return !overlaps(va, size, 378 KERNEL_ADDRESS_SPACE_START, 382 return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START, 379 383 KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START); 380 384 } … … 402 406 mem_backend_data_t *backend_data) 403 407 { 404 if ( base % PAGE_SIZE)408 if ((base % PAGE_SIZE) != 0) 405 409 return NULL; 406 410 407 if ( !size)411 if (size == 0) 408 412 return NULL; 413 414 size_t pages = SIZE2FRAMES(size); 409 415 410 416 /* Writeable executable areas are not supported. */ … … 414 420 mutex_lock(&as->lock); 415 421 416 if (!check_area_conflicts(as, base, size, NULL)) {422 if (!check_area_conflicts(as, base, pages, NULL)) { 417 423 mutex_unlock(&as->lock); 418 424 return NULL; … … 426 432 area->flags = flags; 427 433 area->attributes = attrs; 428 area->pages = SIZE2FRAMES(size);434 area->pages = pages; 429 435 area->resident = 0; 430 436 area->base = base; … … 437 443 memsetb(&area->backend_data, sizeof(area->backend_data), 0); 438 444 445 if (area->backend && area->backend->create) { 446 if (!area->backend->create(area)) { 447 free(area); 448 mutex_unlock(&as->lock); 449 return NULL; 450 } 451 } 452 439 453 btree_create(&area->used_space); 440 454 btree_insert(&as->as_area_btree, base, (void *) area, NULL); … … 459 473 460 474 btree_node_t *leaf; 461 as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf); 475 as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, 476 &leaf); 462 477 if (area) { 463 478 /* va is the base address of an address space area */ … … 467 482 468 483 /* 469 * Search the leaf node and the righ most record of its left neighbour484 * Search the leaf node and the rightmost record of its left neighbour 470 485 * to find out whether this is a miss or va belongs to an address 471 486 * space area found there. … … 479 494 480 495 mutex_lock(&area->lock); 481 482 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE)) 496 497 if ((area->base <= va) && 498 (va <= area->base + (P2SZ(area->pages) - 1))) 483 499 return area; 484 500 … … 490 506 * Because of its position in the B+tree, it must have base < va. 491 507 */ 492 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf); 508 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, 509 leaf); 493 510 if (lnode) { 494 511 area = (as_area_t *) lnode->value[lnode->keys - 1]; … … 496 513 mutex_lock(&area->lock); 497 514 498 if (va < area->base + area->pages * PAGE_SIZE)515 if (va <= area->base + (P2SZ(area->pages) - 1)) 499 516 return area; 500 517 … … 561 578 562 579 if (pages < area->pages) { 563 uintptr_t start_free = area->base + pages * PAGE_SIZE;580 uintptr_t start_free = area->base + P2SZ(pages); 564 581 565 582 /* … … 574 591 */ 575 592 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, 576 area->base + pages * PAGE_SIZE, area->pages - pages);593 area->base + P2SZ(pages), area->pages - pages); 577 594 578 595 /* … … 585 602 bool cond = true; 586 603 while (cond) { 587 ASSERT(!list_empty(&area->used_space.leaf_ head));604 ASSERT(!list_empty(&area->used_space.leaf_list)); 588 605 589 606 btree_node_t *node = 590 list_get_instance( area->used_space.leaf_head.prev,607 list_get_instance(list_last(&area->used_space.leaf_list), 591 608 btree_node_t, leaf_link); 592 609 … … 597 614 size_t i = 0; 598 615 599 if (overlaps(ptr, size * PAGE_SIZE, area->base,600 pages * PAGE_SIZE)) {616 if (overlaps(ptr, P2SZ(size), area->base, 617 P2SZ(pages))) { 601 618 602 if (ptr + size * PAGE_SIZE<= start_free) {619 if (ptr + P2SZ(size) <= start_free) { 603 620 /* 604 621 * The whole interval fits … … 631 648 632 649 for (; i < size; i++) { 633 pte_t *pte = page_mapping_find(as, ptr +634 i * PAGE_SIZE);650 pte_t *pte = page_mapping_find(as, 651 ptr + P2SZ(i), false); 635 652 636 653 ASSERT(pte); … … 641 658 (area->backend->frame_free)) { 642 659 area->backend->frame_free(area, 643 ptr + i * PAGE_SIZE,660 ptr + P2SZ(i), 644 661 PTE_GET_FRAME(pte)); 645 662 } 646 663 647 page_mapping_remove(as, ptr + 648 i * PAGE_SIZE); 664 page_mapping_remove(as, ptr + P2SZ(i)); 649 665 } 650 666 } … … 655 671 */ 656 672 657 tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE,673 tlb_invalidate_pages(as->asid, area->base + P2SZ(pages), 658 674 area->pages - pages); 659 675 660 676 /* 661 * Invalidate software translation caches (e.g. TSB on sparc64). 662 */ 663 as_invalidate_translation_cache(as, area->base + 664 pages * PAGE_SIZE, area->pages - pages); 677 * Invalidate software translation caches 678 * (e.g. TSB on sparc64, PHT on ppc32). 679 */ 680 as_invalidate_translation_cache(as, area->base + P2SZ(pages), 681 area->pages - pages); 665 682 tlb_shootdown_finalize(ipl); 666 683 … … 671 688 * Check for overlaps with other address space areas. 672 689 */ 673 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, 674 area)) { 690 if (!check_area_conflicts(as, address, pages, area)) { 675 691 mutex_unlock(&area->lock); 676 692 mutex_unlock(&as->lock); … … 679 695 } 680 696 697 if (area->backend && area->backend->resize) { 698 if (!area->backend->resize(area, pages)) { 699 mutex_unlock(&area->lock); 700 mutex_unlock(&as->lock); 701 return ENOMEM; 702 } 703 } 704 681 705 area->pages = pages; 682 706 … … 703 727 if (--sh_info->refcount == 0) { 704 728 dealloc = true; 705 link_t *cur;706 729 707 730 /* … … 709 732 * reference from all frames found there. 710 733 */ 711 for (cur = sh_info->pagemap.leaf_head.next; 712 cur != &sh_info->pagemap.leaf_head; cur = cur->next) { 734 list_foreach(sh_info->pagemap.leaf_list, cur) { 713 735 btree_node_t *node 714 736 = list_get_instance(cur, btree_node_t, leaf_link); … … 745 767 return ENOENT; 746 768 } 769 770 if (area->backend && area->backend->destroy) 771 area->backend->destroy(area); 747 772 748 773 uintptr_t base = area->base; … … 759 784 * Visit only the pages mapped by used_space B+tree. 760 785 */ 761 link_t *cur; 762 for (cur = area->used_space.leaf_head.next; 763 cur != &area->used_space.leaf_head; cur = cur->next) { 786 list_foreach(area->used_space.leaf_list, cur) { 764 787 btree_node_t *node; 765 788 btree_key_t i; … … 771 794 772 795 for (size = 0; size < (size_t) node->value[i]; size++) { 773 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 796 pte_t *pte = page_mapping_find(as, 797 ptr + P2SZ(size), false); 774 798 775 799 ASSERT(pte); … … 780 804 (area->backend->frame_free)) { 781 805 area->backend->frame_free(area, 782 ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte)); 806 ptr + P2SZ(size), 807 PTE_GET_FRAME(pte)); 783 808 } 784 809 785 page_mapping_remove(as, ptr + size * PAGE_SIZE);810 page_mapping_remove(as, ptr + P2SZ(size)); 786 811 } 787 812 } … … 795 820 796 821 /* 797 * Invalidate potential software translation caches (e.g. TSB on798 * sparc64).822 * Invalidate potential software translation caches 823 * (e.g. TSB on sparc64, PHT on ppc32). 799 824 */ 800 825 as_invalidate_translation_cache(as, area->base, area->pages); … … 870 895 } 871 896 872 size_t src_size = src_area->pages * PAGE_SIZE;897 size_t src_size = P2SZ(src_area->pages); 873 898 unsigned int src_flags = src_area->flags; 874 899 mem_backend_t *src_backend = src_area->backend; … … 1036 1061 */ 1037 1062 size_t used_pages = 0; 1038 link_t *cur; 1039 1040 for (cur = area->used_space.leaf_head.next; 1041 cur != &area->used_space.leaf_head; cur = cur->next) { 1063 1064 list_foreach(area->used_space.leaf_list, cur) { 1042 1065 btree_node_t *node 1043 1066 = list_get_instance(cur, btree_node_t, leaf_link); … … 1065 1088 size_t frame_idx = 0; 1066 1089 1067 for (cur = area->used_space.leaf_head.next; 1068 cur != &area->used_space.leaf_head; cur = cur->next) { 1069 btree_node_t *node 1070 = list_get_instance(cur, btree_node_t, leaf_link); 1090 list_foreach(area->used_space.leaf_list, cur) { 1091 btree_node_t *node = list_get_instance(cur, btree_node_t, 1092 leaf_link); 1071 1093 btree_key_t i; 1072 1094 … … 1076 1098 1077 1099 for (size = 0; size < (size_t) node->value[i]; size++) { 1078 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 1100 pte_t *pte = page_mapping_find(as, 1101 ptr + P2SZ(size), false); 1079 1102 1080 1103 ASSERT(pte); … … 1085 1108 1086 1109 /* Remove old mapping */ 1087 page_mapping_remove(as, ptr + size * PAGE_SIZE);1110 page_mapping_remove(as, ptr + P2SZ(size)); 1088 1111 } 1089 1112 } … … 1097 1120 1098 1121 /* 1099 * Invalidate potential software translation caches (e.g. TSB on1100 * sparc64).1122 * Invalidate potential software translation caches 1123 * (e.g. TSB on sparc64, PHT on ppc32). 1101 1124 */ 1102 1125 as_invalidate_translation_cache(as, area->base, area->pages); … … 1117 1140 frame_idx = 0; 1118 1141 1119 for (cur = area->used_space.leaf_head.next; 1120 cur != &area->used_space.leaf_head; cur = cur->next) { 1142 list_foreach(area->used_space.leaf_list, cur) { 1121 1143 btree_node_t *node 1122 1144 = list_get_instance(cur, btree_node_t, leaf_link); … … 1131 1153 1132 1154 /* Insert the new mapping */ 1133 page_mapping_insert(as, ptr + size * PAGE_SIZE,1155 page_mapping_insert(as, ptr + P2SZ(size), 1134 1156 old_frame[frame_idx++], page_flags); 1135 1157 … … 1212 1234 */ 1213 1235 pte_t *pte; 1214 if ((pte = page_mapping_find(AS, page ))) {1236 if ((pte = page_mapping_find(AS, page, false))) { 1215 1237 if (PTE_PRESENT(pte)) { 1216 1238 if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) || … … 1262 1284 * thing which is forbidden in this context is locking the address space. 1263 1285 * 1264 * When this function is en etered, no spinlocks may be held.1286 * When this function is entered, no spinlocks may be held. 1265 1287 * 1266 1288 * @param old Old address space or NULL. … … 1304 1326 1305 1327 list_append(&old_as->inactive_as_with_asid_link, 1306 &inactive_as_with_asid_ head);1328 &inactive_as_with_asid_list); 1307 1329 } 1308 1330 … … 1453 1475 1454 1476 if (src_area) { 1455 size = src_area->pages * PAGE_SIZE;1477 size = P2SZ(src_area->pages); 1456 1478 mutex_unlock(&src_area->lock); 1457 1479 } else … … 1508 1530 if (page >= right_pg) { 1509 1531 /* Do nothing. */ 1510 } else if (overlaps(page, count * PAGE_SIZE, left_pg,1511 left_cnt * PAGE_SIZE)) {1532 } else if (overlaps(page, P2SZ(count), left_pg, 1533 P2SZ(left_cnt))) { 1512 1534 /* The interval intersects with the left interval. */ 1513 1535 return false; 1514 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1515 right_cnt * PAGE_SIZE)) {1536 } else if (overlaps(page, P2SZ(count), right_pg, 1537 P2SZ(right_cnt))) { 1516 1538 /* The interval intersects with the right interval. */ 1517 1539 return false; 1518 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1519 (page + count * PAGE_SIZE== right_pg)) {1540 } else if ((page == left_pg + P2SZ(left_cnt)) && 1541 (page + P2SZ(count) == right_pg)) { 1520 1542 /* 1521 1543 * The interval can be added by merging the two already … … 1525 1547 btree_remove(&area->used_space, right_pg, leaf); 1526 1548 goto success; 1527 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1549 } else if (page == left_pg + P2SZ(left_cnt)) { 1528 1550 /* 1529 1551 * The interval can be added by simply growing the left … … 1532 1554 node->value[node->keys - 1] += count; 1533 1555 goto success; 1534 } else if (page + count * PAGE_SIZE== right_pg) {1556 } else if (page + P2SZ(count) == right_pg) { 1535 1557 /* 1536 1558 * The interval can be addded by simply moving base of … … 1559 1581 */ 1560 1582 1561 if (overlaps(page, count * PAGE_SIZE, right_pg, 1562 right_cnt * PAGE_SIZE)) { 1583 if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) { 1563 1584 /* The interval intersects with the right interval. */ 1564 1585 return false; 1565 } else if (page + count * PAGE_SIZE== right_pg) {1586 } else if (page + P2SZ(count) == right_pg) { 1566 1587 /* 1567 1588 * The interval can be added by moving the base of the … … 1598 1619 if (page < left_pg) { 1599 1620 /* Do nothing. */ 1600 } else if (overlaps(page, count * PAGE_SIZE, left_pg,1601 left_cnt * PAGE_SIZE)) {1621 } else if (overlaps(page, P2SZ(count), left_pg, 1622 P2SZ(left_cnt))) { 1602 1623 /* The interval intersects with the left interval. */ 1603 1624 return false; 1604 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1605 right_cnt * PAGE_SIZE)) {1625 } else if (overlaps(page, P2SZ(count), right_pg, 1626 P2SZ(right_cnt))) { 1606 1627 /* The interval intersects with the right interval. */ 1607 1628 return false; 1608 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1609 (page + count * PAGE_SIZE== right_pg)) {1629 } else if ((page == left_pg + P2SZ(left_cnt)) && 1630 (page + P2SZ(count) == right_pg)) { 1610 1631 /* 1611 1632 * The interval can be added by merging the two already … … 1615 1636 btree_remove(&area->used_space, right_pg, node); 1616 1637 goto success; 1617 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1638 } else if (page == left_pg + P2SZ(left_cnt)) { 1618 1639 /* 1619 1640 * The interval can be added by simply growing the left … … 1622 1643 leaf->value[leaf->keys - 1] += count; 1623 1644 goto success; 1624 } else if (page + count * PAGE_SIZE== right_pg) {1645 } else if (page + P2SZ(count) == right_pg) { 1625 1646 /* 1626 1647 * The interval can be addded by simply moving base of … … 1649 1670 */ 1650 1671 1651 if (overlaps(page, count * PAGE_SIZE, left_pg, 1652 left_cnt * PAGE_SIZE)) { 1672 if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) { 1653 1673 /* The interval intersects with the left interval. */ 1654 1674 return false; 1655 } else if (left_pg + left_cnt * PAGE_SIZE== page) {1675 } else if (left_pg + P2SZ(left_cnt) == page) { 1656 1676 /* 1657 1677 * The interval can be added by growing the left … … 1688 1708 */ 1689 1709 1690 if (overlaps(page, count * PAGE_SIZE, left_pg,1691 left_cnt * PAGE_SIZE)) {1710 if (overlaps(page, P2SZ(count), left_pg, 1711 P2SZ(left_cnt))) { 1692 1712 /* 1693 1713 * The interval intersects with the left … … 1695 1715 */ 1696 1716 return false; 1697 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1698 right_cnt * PAGE_SIZE)) {1717 } else if (overlaps(page, P2SZ(count), right_pg, 1718 P2SZ(right_cnt))) { 1699 1719 /* 1700 1720 * The interval intersects with the right … … 1702 1722 */ 1703 1723 return false; 1704 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1705 (page + count * PAGE_SIZE== right_pg)) {1724 } else if ((page == left_pg + P2SZ(left_cnt)) && 1725 (page + P2SZ(count) == right_pg)) { 1706 1726 /* 1707 1727 * The interval can be added by merging the two … … 1711 1731 btree_remove(&area->used_space, right_pg, leaf); 1712 1732 goto success; 1713 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1733 } else if (page == left_pg + P2SZ(left_cnt)) { 1714 1734 /* 1715 1735 * The interval can be added by simply growing … … 1718 1738 leaf->value[i - 1] += count; 1719 1739 goto success; 1720 } else if (page + count * PAGE_SIZE== right_pg) {1740 } else if (page + P2SZ(count) == right_pg) { 1721 1741 /* 1722 1742 * The interval can be addded by simply moving … … 1784 1804 for (i = 0; i < leaf->keys; i++) { 1785 1805 if (leaf->key[i] == page) { 1786 leaf->key[i] += count * PAGE_SIZE;1806 leaf->key[i] += P2SZ(count); 1787 1807 leaf->value[i] -= count; 1788 1808 goto success; … … 1794 1814 } 1795 1815 1796 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf); 1816 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, 1817 leaf); 1797 1818 if ((node) && (page < leaf->key[0])) { 1798 1819 uintptr_t left_pg = node->key[node->keys - 1]; 1799 1820 size_t left_cnt = (size_t) node->value[node->keys - 1]; 1800 1821 1801 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page, 1802 count * PAGE_SIZE)) { 1803 if (page + count * PAGE_SIZE == 1804 left_pg + left_cnt * PAGE_SIZE) { 1822 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1823 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 1805 1824 /* 1806 1825 * The interval is contained in the rightmost … … 1811 1830 node->value[node->keys - 1] -= count; 1812 1831 goto success; 1813 } else if (page + count * PAGE_SIZE < 1814 left_pg + left_cnt*PAGE_SIZE) { 1832 } else if (page + P2SZ(count) < 1833 left_pg + P2SZ(left_cnt)) { 1834 size_t new_cnt; 1835 1815 1836 /* 1816 1837 * The interval is contained in the rightmost … … 1820 1841 * new interval. 1821 1842 */ 1822 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -1823 (page + count*PAGE_SIZE)) >> PAGE_WIDTH;1843 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1844 (page + P2SZ(count))) >> PAGE_WIDTH; 1824 1845 node->value[node->keys - 1] -= count + new_cnt; 1825 1846 btree_insert(&area->used_space, page + 1826 count * PAGE_SIZE, (void *) new_cnt, leaf);1847 P2SZ(count), (void *) new_cnt, leaf); 1827 1848 goto success; 1828 1849 } … … 1837 1858 size_t left_cnt = (size_t) leaf->value[leaf->keys - 1]; 1838 1859 1839 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page, 1840 count * PAGE_SIZE)) { 1841 if (page + count * PAGE_SIZE == 1842 left_pg + left_cnt * PAGE_SIZE) { 1860 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1861 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 1843 1862 /* 1844 1863 * The interval is contained in the rightmost … … 1848 1867 leaf->value[leaf->keys - 1] -= count; 1849 1868 goto success; 1850 } else if (page + count * PAGE_SIZE < left_pg + 1851 left_cnt * PAGE_SIZE) { 1869 } else if (page + P2SZ(count) < left_pg + 1870 P2SZ(left_cnt)) { 1871 size_t new_cnt; 1872 1852 1873 /* 1853 1874 * The interval is contained in the rightmost … … 1857 1878 * interval. 1858 1879 */ 1859 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -1860 (page + count * PAGE_SIZE)) >> PAGE_WIDTH;1880 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1881 (page + P2SZ(count))) >> PAGE_WIDTH; 1861 1882 leaf->value[leaf->keys - 1] -= count + new_cnt; 1862 1883 btree_insert(&area->used_space, page + 1863 count * PAGE_SIZE, (void *) new_cnt, leaf);1884 P2SZ(count), (void *) new_cnt, leaf); 1864 1885 goto success; 1865 1886 } … … 1883 1904 * to (i - 1) and i. 1884 1905 */ 1885 if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,1886 count * PAGE_SIZE)) {1887 if (page + count * PAGE_SIZE==1888 left_pg + left_cnt*PAGE_SIZE) {1906 if (overlaps(left_pg, P2SZ(left_cnt), page, 1907 P2SZ(count))) { 1908 if (page + P2SZ(count) == 1909 left_pg + P2SZ(left_cnt)) { 1889 1910 /* 1890 1911 * The interval is contained in the … … 1895 1916 leaf->value[i - 1] -= count; 1896 1917 goto success; 1897 } else if (page + count * PAGE_SIZE < 1898 left_pg + left_cnt * PAGE_SIZE) { 1918 } else if (page + P2SZ(count) < 1919 left_pg + P2SZ(left_cnt)) { 1920 size_t new_cnt; 1921 1899 1922 /* 1900 1923 * The interval is contained in the … … 1904 1927 * also inserting a new interval. 1905 1928 */ 1906 size_t new_cnt = ((left_pg + 1907 left_cnt * PAGE_SIZE) - 1908 (page + count * PAGE_SIZE)) >> 1929 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1930 (page + P2SZ(count))) >> 1909 1931 PAGE_WIDTH; 1910 1932 leaf->value[i - 1] -= count + new_cnt; 1911 1933 btree_insert(&area->used_space, page + 1912 count * PAGE_SIZE, (void *) new_cnt,1934 P2SZ(count), (void *) new_cnt, 1913 1935 leaf); 1914 1936 goto success; … … 1961 1983 } 1962 1984 1985 /** Return pointer to unmapped address space area 1986 * 1987 * @param base Lowest address bound. 1988 * @param size Requested size of the allocation. 1989 * 1990 * @return Pointer to the beginning of unmapped address space area. 1991 * 1992 */ 1993 sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size) 1994 { 1995 if (size == 0) 1996 return 0; 1997 1998 /* 1999 * Make sure we allocate from page-aligned 2000 * address. Check for possible overflow in 2001 * each step. 2002 */ 2003 2004 size_t pages = SIZE2FRAMES(size); 2005 uintptr_t ret = 0; 2006 2007 /* 2008 * Find the lowest unmapped address aligned on the sz 2009 * boundary, not smaller than base and of the required size. 2010 */ 2011 2012 mutex_lock(&AS->lock); 2013 2014 /* First check the base address itself */ 2015 uintptr_t addr = ALIGN_UP(base, PAGE_SIZE); 2016 if ((addr >= base) && 2017 (check_area_conflicts(AS, addr, pages, NULL))) 2018 ret = addr; 2019 2020 /* Eventually check the addresses behind each area */ 2021 list_foreach(AS->as_area_btree.leaf_list, cur) { 2022 if (ret != 0) 2023 break; 2024 2025 btree_node_t *node = 2026 list_get_instance(cur, btree_node_t, leaf_link); 2027 2028 btree_key_t i; 2029 for (i = 0; (ret == 0) && (i < node->keys); i++) { 2030 uintptr_t addr; 2031 2032 as_area_t *area = (as_area_t *) node->value[i]; 2033 2034 mutex_lock(&area->lock); 2035 2036 addr = ALIGN_UP(area->base + P2SZ(area->pages), 2037 PAGE_SIZE); 2038 2039 if ((addr >= base) && (addr >= area->base) && 2040 (check_area_conflicts(AS, addr, pages, area))) 2041 ret = addr; 2042 2043 mutex_unlock(&area->lock); 2044 } 2045 } 2046 2047 mutex_unlock(&AS->lock); 2048 2049 return (sysarg_t) ret; 2050 } 2051 1963 2052 /** Get list of adress space areas. 1964 2053 * … … 1975 2064 1976 2065 size_t area_cnt = 0; 1977 link_t *cur; 1978 1979 for (cur = as->as_area_btree.leaf_head.next; 1980 cur != &as->as_area_btree.leaf_head; cur = cur->next) { 2066 2067 list_foreach(as->as_area_btree.leaf_list, cur) { 1981 2068 btree_node_t *node = 1982 2069 list_get_instance(cur, btree_node_t, leaf_link); … … 1991 2078 size_t area_idx = 0; 1992 2079 1993 for (cur = as->as_area_btree.leaf_head.next; 1994 cur != &as->as_area_btree.leaf_head; cur = cur->next) { 2080 list_foreach(as->as_area_btree.leaf_list, cur) { 1995 2081 btree_node_t *node = 1996 2082 list_get_instance(cur, btree_node_t, leaf_link); … … 2004 2090 2005 2091 info[area_idx].start_addr = area->base; 2006 info[area_idx].size = FRAMES2SIZE(area->pages);2092 info[area_idx].size = P2SZ(area->pages); 2007 2093 info[area_idx].flags = area->flags; 2008 2094 ++area_idx; … … 2027 2113 mutex_lock(&as->lock); 2028 2114 2029 /* print out info about address space areas */ 2030 link_t *cur; 2031 for (cur = as->as_area_btree.leaf_head.next; 2032 cur != &as->as_area_btree.leaf_head; cur = cur->next) { 2115 /* Print out info about address space areas */ 2116 list_foreach(as->as_area_btree.leaf_list, cur) { 2033 2117 btree_node_t *node 2034 2118 = list_get_instance(cur, btree_node_t, leaf_link); … … 2042 2126 " (%p - %p)\n", area, (void *) area->base, 2043 2127 area->pages, (void *) area->base, 2044 (void *) (area->base + FRAMES2SIZE(area->pages)));2128 (void *) (area->base + P2SZ(area->pages))); 2045 2129 mutex_unlock(&area->lock); 2046 2130 }
Note:
See TracChangeset
for help on using the changeset viewer.