Changes in kernel/generic/src/mm/as.c [fc47885:eef1b031] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
rfc47885 reef1b031 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 … … 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 /* … … 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); 677 693 return EADDRNOTAVAIL; 694 } 695 } 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; 678 702 } 679 703 } … … 745 769 return ENOENT; 746 770 } 771 772 if (area->backend && area->backend->destroy) 773 area->backend->destroy(area); 747 774 748 775 uintptr_t base = area->base; … … 771 798 772 799 for (size = 0; size < (size_t) node->value[i]; size++) { 773 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 800 pte_t *pte = page_mapping_find(as, 801 ptr + P2SZ(size), false); 774 802 775 803 ASSERT(pte); … … 780 808 (area->backend->frame_free)) { 781 809 area->backend->frame_free(area, 782 ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte)); 810 ptr + P2SZ(size), 811 PTE_GET_FRAME(pte)); 783 812 } 784 813 785 page_mapping_remove(as, ptr + size * PAGE_SIZE);814 page_mapping_remove(as, ptr + P2SZ(size)); 786 815 } 787 816 } … … 795 824 796 825 /* 797 * Invalidate potential software translation caches (e.g. TSB on798 * sparc64).826 * Invalidate potential software translation caches 827 * (e.g. TSB on sparc64, PHT on ppc32). 799 828 */ 800 829 as_invalidate_translation_cache(as, area->base, area->pages); … … 870 899 } 871 900 872 size_t src_size = src_area->pages * PAGE_SIZE;901 size_t src_size = P2SZ(src_area->pages); 873 902 unsigned int src_flags = src_area->flags; 874 903 mem_backend_t *src_backend = src_area->backend; … … 1067 1096 for (cur = area->used_space.leaf_head.next; 1068 1097 cur != &area->used_space.leaf_head; cur = cur->next) { 1069 btree_node_t *node 1070 = list_get_instance(cur, btree_node_t,leaf_link);1098 btree_node_t *node = list_get_instance(cur, btree_node_t, 1099 leaf_link); 1071 1100 btree_key_t i; 1072 1101 … … 1076 1105 1077 1106 for (size = 0; size < (size_t) node->value[i]; size++) { 1078 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 1107 pte_t *pte = page_mapping_find(as, 1108 ptr + P2SZ(size), false); 1079 1109 1080 1110 ASSERT(pte); … … 1085 1115 1086 1116 /* Remove old mapping */ 1087 page_mapping_remove(as, ptr + size * PAGE_SIZE);1117 page_mapping_remove(as, ptr + P2SZ(size)); 1088 1118 } 1089 1119 } … … 1097 1127 1098 1128 /* 1099 * Invalidate potential software translation caches (e.g. TSB on1100 * sparc64).1129 * Invalidate potential software translation caches 1130 * (e.g. TSB on sparc64, PHT on ppc32). 1101 1131 */ 1102 1132 as_invalidate_translation_cache(as, area->base, area->pages); … … 1131 1161 1132 1162 /* Insert the new mapping */ 1133 page_mapping_insert(as, ptr + size * PAGE_SIZE,1163 page_mapping_insert(as, ptr + P2SZ(size), 1134 1164 old_frame[frame_idx++], page_flags); 1135 1165 … … 1212 1242 */ 1213 1243 pte_t *pte; 1214 if ((pte = page_mapping_find(AS, page ))) {1244 if ((pte = page_mapping_find(AS, page, false))) { 1215 1245 if (PTE_PRESENT(pte)) { 1216 1246 if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) || … … 1453 1483 1454 1484 if (src_area) { 1455 size = src_area->pages * PAGE_SIZE;1485 size = P2SZ(src_area->pages); 1456 1486 mutex_unlock(&src_area->lock); 1457 1487 } else … … 1508 1538 if (page >= right_pg) { 1509 1539 /* Do nothing. */ 1510 } else if (overlaps(page, count * PAGE_SIZE, left_pg,1511 left_cnt * PAGE_SIZE)) {1540 } else if (overlaps(page, P2SZ(count), left_pg, 1541 P2SZ(left_cnt))) { 1512 1542 /* The interval intersects with the left interval. */ 1513 1543 return false; 1514 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1515 right_cnt * PAGE_SIZE)) {1544 } else if (overlaps(page, P2SZ(count), right_pg, 1545 P2SZ(right_cnt))) { 1516 1546 /* The interval intersects with the right interval. */ 1517 1547 return false; 1518 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1519 (page + count * PAGE_SIZE== right_pg)) {1548 } else if ((page == left_pg + P2SZ(left_cnt)) && 1549 (page + P2SZ(count) == right_pg)) { 1520 1550 /* 1521 1551 * The interval can be added by merging the two already … … 1525 1555 btree_remove(&area->used_space, right_pg, leaf); 1526 1556 goto success; 1527 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1557 } else if (page == left_pg + P2SZ(left_cnt)) { 1528 1558 /* 1529 1559 * The interval can be added by simply growing the left … … 1532 1562 node->value[node->keys - 1] += count; 1533 1563 goto success; 1534 } else if (page + count * PAGE_SIZE== right_pg) {1564 } else if (page + P2SZ(count) == right_pg) { 1535 1565 /* 1536 1566 * The interval can be addded by simply moving base of … … 1559 1589 */ 1560 1590 1561 if (overlaps(page, count * PAGE_SIZE, right_pg, 1562 right_cnt * PAGE_SIZE)) { 1591 if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) { 1563 1592 /* The interval intersects with the right interval. */ 1564 1593 return false; 1565 } else if (page + count * PAGE_SIZE== right_pg) {1594 } else if (page + P2SZ(count) == right_pg) { 1566 1595 /* 1567 1596 * The interval can be added by moving the base of the … … 1598 1627 if (page < left_pg) { 1599 1628 /* Do nothing. */ 1600 } else if (overlaps(page, count * PAGE_SIZE, left_pg,1601 left_cnt * PAGE_SIZE)) {1629 } else if (overlaps(page, P2SZ(count), left_pg, 1630 P2SZ(left_cnt))) { 1602 1631 /* The interval intersects with the left interval. */ 1603 1632 return false; 1604 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1605 right_cnt * PAGE_SIZE)) {1633 } else if (overlaps(page, P2SZ(count), right_pg, 1634 P2SZ(right_cnt))) { 1606 1635 /* The interval intersects with the right interval. */ 1607 1636 return false; 1608 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1609 (page + count * PAGE_SIZE== right_pg)) {1637 } else if ((page == left_pg + P2SZ(left_cnt)) && 1638 (page + P2SZ(count) == right_pg)) { 1610 1639 /* 1611 1640 * The interval can be added by merging the two already … … 1615 1644 btree_remove(&area->used_space, right_pg, node); 1616 1645 goto success; 1617 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1646 } else if (page == left_pg + P2SZ(left_cnt)) { 1618 1647 /* 1619 1648 * The interval can be added by simply growing the left … … 1622 1651 leaf->value[leaf->keys - 1] += count; 1623 1652 goto success; 1624 } else if (page + count * PAGE_SIZE== right_pg) {1653 } else if (page + P2SZ(count) == right_pg) { 1625 1654 /* 1626 1655 * The interval can be addded by simply moving base of … … 1649 1678 */ 1650 1679 1651 if (overlaps(page, count * PAGE_SIZE, left_pg, 1652 left_cnt * PAGE_SIZE)) { 1680 if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) { 1653 1681 /* The interval intersects with the left interval. */ 1654 1682 return false; 1655 } else if (left_pg + left_cnt * PAGE_SIZE== page) {1683 } else if (left_pg + P2SZ(left_cnt) == page) { 1656 1684 /* 1657 1685 * The interval can be added by growing the left … … 1688 1716 */ 1689 1717 1690 if (overlaps(page, count * PAGE_SIZE, left_pg,1691 left_cnt * PAGE_SIZE)) {1718 if (overlaps(page, P2SZ(count), left_pg, 1719 P2SZ(left_cnt))) { 1692 1720 /* 1693 1721 * The interval intersects with the left … … 1695 1723 */ 1696 1724 return false; 1697 } else if (overlaps(page, count * PAGE_SIZE, right_pg,1698 right_cnt * PAGE_SIZE)) {1725 } else if (overlaps(page, P2SZ(count), right_pg, 1726 P2SZ(right_cnt))) { 1699 1727 /* 1700 1728 * The interval intersects with the right … … 1702 1730 */ 1703 1731 return false; 1704 } else if ((page == left_pg + left_cnt * PAGE_SIZE) &&1705 (page + count * PAGE_SIZE== right_pg)) {1732 } else if ((page == left_pg + P2SZ(left_cnt)) && 1733 (page + P2SZ(count) == right_pg)) { 1706 1734 /* 1707 1735 * The interval can be added by merging the two … … 1711 1739 btree_remove(&area->used_space, right_pg, leaf); 1712 1740 goto success; 1713 } else if (page == left_pg + left_cnt * PAGE_SIZE) {1741 } else if (page == left_pg + P2SZ(left_cnt)) { 1714 1742 /* 1715 1743 * The interval can be added by simply growing … … 1718 1746 leaf->value[i - 1] += count; 1719 1747 goto success; 1720 } else if (page + count * PAGE_SIZE== right_pg) {1748 } else if (page + P2SZ(count) == right_pg) { 1721 1749 /* 1722 1750 * The interval can be addded by simply moving … … 1784 1812 for (i = 0; i < leaf->keys; i++) { 1785 1813 if (leaf->key[i] == page) { 1786 leaf->key[i] += count * PAGE_SIZE;1814 leaf->key[i] += P2SZ(count); 1787 1815 leaf->value[i] -= count; 1788 1816 goto success; … … 1794 1822 } 1795 1823 1796 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf); 1824 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, 1825 leaf); 1797 1826 if ((node) && (page < leaf->key[0])) { 1798 1827 uintptr_t left_pg = node->key[node->keys - 1]; 1799 1828 size_t left_cnt = (size_t) node->value[node->keys - 1]; 1800 1829 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) { 1830 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1831 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 1805 1832 /* 1806 1833 * The interval is contained in the rightmost … … 1811 1838 node->value[node->keys - 1] -= count; 1812 1839 goto success; 1813 } else if (page + count * PAGE_SIZE < 1814 left_pg + left_cnt*PAGE_SIZE) { 1840 } else if (page + P2SZ(count) < 1841 left_pg + P2SZ(left_cnt)) { 1842 size_t new_cnt; 1843 1815 1844 /* 1816 1845 * The interval is contained in the rightmost … … 1820 1849 * new interval. 1821 1850 */ 1822 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -1823 (page + count*PAGE_SIZE)) >> PAGE_WIDTH;1851 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1852 (page + P2SZ(count))) >> PAGE_WIDTH; 1824 1853 node->value[node->keys - 1] -= count + new_cnt; 1825 1854 btree_insert(&area->used_space, page + 1826 count * PAGE_SIZE, (void *) new_cnt, leaf);1855 P2SZ(count), (void *) new_cnt, leaf); 1827 1856 goto success; 1828 1857 } … … 1837 1866 size_t left_cnt = (size_t) leaf->value[leaf->keys - 1]; 1838 1867 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) { 1868 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1869 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 1843 1870 /* 1844 1871 * The interval is contained in the rightmost … … 1848 1875 leaf->value[leaf->keys - 1] -= count; 1849 1876 goto success; 1850 } else if (page + count * PAGE_SIZE < left_pg + 1851 left_cnt * PAGE_SIZE) { 1877 } else if (page + P2SZ(count) < left_pg + 1878 P2SZ(left_cnt)) { 1879 size_t new_cnt; 1880 1852 1881 /* 1853 1882 * The interval is contained in the rightmost … … 1857 1886 * interval. 1858 1887 */ 1859 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) -1860 (page + count * PAGE_SIZE)) >> PAGE_WIDTH;1888 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1889 (page + P2SZ(count))) >> PAGE_WIDTH; 1861 1890 leaf->value[leaf->keys - 1] -= count + new_cnt; 1862 1891 btree_insert(&area->used_space, page + 1863 count * PAGE_SIZE, (void *) new_cnt, leaf);1892 P2SZ(count), (void *) new_cnt, leaf); 1864 1893 goto success; 1865 1894 } … … 1883 1912 * to (i - 1) and i. 1884 1913 */ 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) {1914 if (overlaps(left_pg, P2SZ(left_cnt), page, 1915 P2SZ(count))) { 1916 if (page + P2SZ(count) == 1917 left_pg + P2SZ(left_cnt)) { 1889 1918 /* 1890 1919 * The interval is contained in the … … 1895 1924 leaf->value[i - 1] -= count; 1896 1925 goto success; 1897 } else if (page + count * PAGE_SIZE < 1898 left_pg + left_cnt * PAGE_SIZE) { 1926 } else if (page + P2SZ(count) < 1927 left_pg + P2SZ(left_cnt)) { 1928 size_t new_cnt; 1929 1899 1930 /* 1900 1931 * The interval is contained in the … … 1904 1935 * also inserting a new interval. 1905 1936 */ 1906 size_t new_cnt = ((left_pg + 1907 left_cnt * PAGE_SIZE) - 1908 (page + count * PAGE_SIZE)) >> 1937 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1938 (page + P2SZ(count))) >> 1909 1939 PAGE_WIDTH; 1910 1940 leaf->value[i - 1] -= count + new_cnt; 1911 1941 btree_insert(&area->used_space, page + 1912 count * PAGE_SIZE, (void *) new_cnt,1942 P2SZ(count), (void *) new_cnt, 1913 1943 leaf); 1914 1944 goto success; … … 1961 1991 } 1962 1992 1993 /** Return pointer to unmapped address space area 1994 * 1995 * @param base Lowest address bound. 1996 * @param size Requested size of the allocation. 1997 * 1998 * @return Pointer to the beginning of unmapped address space area. 1999 * 2000 */ 2001 sysarg_t sys_as_get_unmapped_area(uintptr_t base, size_t size) 2002 { 2003 if (size == 0) 2004 return 0; 2005 2006 /* 2007 * Make sure we allocate from page-aligned 2008 * address. Check for possible overflow in 2009 * each step. 2010 */ 2011 2012 size_t pages = SIZE2FRAMES(size); 2013 uintptr_t ret = 0; 2014 2015 /* 2016 * Find the lowest unmapped address aligned on the sz 2017 * boundary, not smaller than base and of the required size. 2018 */ 2019 2020 mutex_lock(&AS->lock); 2021 2022 /* First check the base address itself */ 2023 uintptr_t addr = ALIGN_UP(base, PAGE_SIZE); 2024 if ((addr >= base) && 2025 (check_area_conflicts(AS, addr, pages, NULL))) 2026 ret = addr; 2027 2028 /* Eventually check the addresses behind each area */ 2029 link_t *cur; 2030 for (cur = AS->as_area_btree.leaf_head.next; 2031 (ret == 0) && (cur != &AS->as_area_btree.leaf_head); 2032 cur = cur->next) { 2033 btree_node_t *node = 2034 list_get_instance(cur, btree_node_t, leaf_link); 2035 2036 btree_key_t i; 2037 for (i = 0; (ret == 0) && (i < node->keys); i++) { 2038 uintptr_t addr; 2039 2040 as_area_t *area = (as_area_t *) node->value[i]; 2041 2042 mutex_lock(&area->lock); 2043 2044 addr = ALIGN_UP(area->base + P2SZ(area->pages), 2045 PAGE_SIZE); 2046 2047 if ((addr >= base) && (addr >= area->base) && 2048 (check_area_conflicts(AS, addr, pages, area))) 2049 ret = addr; 2050 2051 mutex_unlock(&area->lock); 2052 } 2053 } 2054 2055 mutex_unlock(&AS->lock); 2056 2057 return (sysarg_t) ret; 2058 } 2059 1963 2060 /** Get list of adress space areas. 1964 2061 * … … 2004 2101 2005 2102 info[area_idx].start_addr = area->base; 2006 info[area_idx].size = FRAMES2SIZE(area->pages);2103 info[area_idx].size = P2SZ(area->pages); 2007 2104 info[area_idx].flags = area->flags; 2008 2105 ++area_idx; … … 2027 2124 mutex_lock(&as->lock); 2028 2125 2029 /* print out info about address space areas */2126 /* Print out info about address space areas */ 2030 2127 link_t *cur; 2031 2128 for (cur = as->as_area_btree.leaf_head.next; … … 2042 2139 " (%p - %p)\n", area, (void *) area->base, 2043 2140 area->pages, (void *) area->base, 2044 (void *) (area->base + FRAMES2SIZE(area->pages)));2141 (void *) (area->base + P2SZ(area->pages))); 2045 2142 mutex_unlock(&area->lock); 2046 2143 }
Note:
See TracChangeset
for help on using the changeset viewer.