Changes in kernel/generic/src/mm/as.c [eef1b031:fc47885] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/mm/as.c
reef1b031 rfc47885 71 71 #include <memstr.h> 72 72 #include <macros.h> 73 #include <bitops.h>74 73 #include <arch.h> 75 74 #include <errno.h> … … 80 79 #include <arch/interrupt.h> 81 80 81 #ifdef CONFIG_VIRT_IDX_DCACHE 82 #include <arch/mm/cache.h> 83 #endif /* CONFIG_VIRT_IDX_DCACHE */ 84 82 85 /** 83 86 * Each architecture decides what functions will be used to carry out … … 285 288 /** Check area conflicts with other areas. 286 289 * 287 * @param as Address space.288 * @param addrStarting virtual address of the area being tested.289 * @param count Number of pages inthe area being tested.290 * @param avoid Do not touch this area.290 * @param as Address space. 291 * @param va Starting virtual address of the area being tested. 292 * @param size Size of the area being tested. 293 * @param avoid_area Do not touch this area. 291 294 * 292 295 * @return True if there is no conflict, false otherwise. 293 296 * 294 297 */ 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); 298 NO_TRACE static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, 299 as_area_t *avoid_area) 300 { 299 301 ASSERT(mutex_locked(&as->lock)); 300 302 … … 302 304 * We don't want any area to have conflicts with NULL page. 303 305 */ 304 if (overlaps( addr, P2SZ(count), (uintptr_t) NULL, PAGE_SIZE))306 if (overlaps(va, size, (uintptr_t) NULL, PAGE_SIZE)) 305 307 return false; 306 308 … … 314 316 btree_node_t *leaf; 315 317 as_area_t *area = 316 (as_area_t *) btree_search(&as->as_area_btree, addr, &leaf);318 (as_area_t *) btree_search(&as->as_area_btree, va, &leaf); 317 319 if (area) { 318 if (area != avoid )320 if (area != avoid_area) 319 321 return false; 320 322 } … … 326 328 area = (as_area_t *) node->value[node->keys - 1]; 327 329 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 330 mutex_lock(&area->lock); 331 332 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 337 333 mutex_unlock(&area->lock); 338 } 334 return false; 335 } 336 337 mutex_unlock(&area->lock); 339 338 } 340 339 … … 343 342 area = (as_area_t *) node->value[0]; 344 343 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 344 mutex_lock(&area->lock); 345 346 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 354 347 mutex_unlock(&area->lock); 355 } 348 return false; 349 } 350 351 mutex_unlock(&area->lock); 356 352 } 357 353 … … 361 357 area = (as_area_t *) leaf->value[i]; 362 358 363 if (area == avoid )359 if (area == avoid_area) 364 360 continue; 365 361 366 362 mutex_lock(&area->lock); 367 363 368 if (overlaps(addr, P2SZ(count), area->base, 369 P2SZ(area->pages))) { 364 if (overlaps(va, size, area->base, area->pages * PAGE_SIZE)) { 370 365 mutex_unlock(&area->lock); 371 366 return false; … … 380 375 */ 381 376 if (!KERNEL_ADDRESS_SPACE_SHADOWED) { 382 return !overlaps(addr, P2SZ(count), KERNEL_ADDRESS_SPACE_START, 377 return !overlaps(va, size, 378 KERNEL_ADDRESS_SPACE_START, 383 379 KERNEL_ADDRESS_SPACE_END - KERNEL_ADDRESS_SPACE_START); 384 380 } … … 406 402 mem_backend_data_t *backend_data) 407 403 { 408 if ( (base % PAGE_SIZE) != 0)404 if (base % PAGE_SIZE) 409 405 return NULL; 410 406 411 if ( size == 0)407 if (!size) 412 408 return NULL; 413 414 size_t pages = SIZE2FRAMES(size);415 409 416 410 /* Writeable executable areas are not supported. */ … … 420 414 mutex_lock(&as->lock); 421 415 422 if (!check_area_conflicts(as, base, pages, NULL)) {416 if (!check_area_conflicts(as, base, size, NULL)) { 423 417 mutex_unlock(&as->lock); 424 418 return NULL; … … 432 426 area->flags = flags; 433 427 area->attributes = attrs; 434 area->pages = pages;428 area->pages = SIZE2FRAMES(size); 435 429 area->resident = 0; 436 430 area->base = base; … … 443 437 memsetb(&area->backend_data, sizeof(area->backend_data), 0); 444 438 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 453 439 btree_create(&area->used_space); 454 440 btree_insert(&as->as_area_btree, base, (void *) area, NULL); … … 473 459 474 460 btree_node_t *leaf; 475 as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, 476 &leaf); 461 as_area_t *area = (as_area_t *) btree_search(&as->as_area_btree, va, &leaf); 477 462 if (area) { 478 463 /* va is the base address of an address space area */ … … 482 467 483 468 /* 484 * Search the leaf node and the righ tmost record of its left neighbour469 * Search the leaf node and the righmost record of its left neighbour 485 470 * to find out whether this is a miss or va belongs to an address 486 471 * space area found there. … … 494 479 495 480 mutex_lock(&area->lock); 496 497 if ((area->base <= va) && 498 (va <= area->base + (P2SZ(area->pages) - 1))) 481 482 if ((area->base <= va) && (va < area->base + area->pages * PAGE_SIZE)) 499 483 return area; 500 484 … … 506 490 * Because of its position in the B+tree, it must have base < va. 507 491 */ 508 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, 509 leaf); 492 btree_node_t *lnode = btree_leaf_node_left_neighbour(&as->as_area_btree, leaf); 510 493 if (lnode) { 511 494 area = (as_area_t *) lnode->value[lnode->keys - 1]; … … 513 496 mutex_lock(&area->lock); 514 497 515 if (va < = area->base + (P2SZ(area->pages) - 1))498 if (va < area->base + area->pages * PAGE_SIZE) 516 499 return area; 517 500 … … 578 561 579 562 if (pages < area->pages) { 580 uintptr_t start_free = area->base + P2SZ(pages);563 uintptr_t start_free = area->base + pages * PAGE_SIZE; 581 564 582 565 /* … … 591 574 */ 592 575 ipl_t ipl = tlb_shootdown_start(TLB_INVL_PAGES, as->asid, 593 area->base + P2SZ(pages), area->pages - pages);576 area->base + pages * PAGE_SIZE, area->pages - pages); 594 577 595 578 /* … … 614 597 size_t i = 0; 615 598 616 if (overlaps(ptr, P2SZ(size), area->base,617 P2SZ(pages))) {599 if (overlaps(ptr, size * PAGE_SIZE, area->base, 600 pages * PAGE_SIZE)) { 618 601 619 if (ptr + P2SZ(size)<= start_free) {602 if (ptr + size * PAGE_SIZE <= start_free) { 620 603 /* 621 604 * The whole interval fits … … 648 631 649 632 for (; i < size; i++) { 650 pte_t *pte = page_mapping_find(as, 651 ptr + P2SZ(i), false);633 pte_t *pte = page_mapping_find(as, ptr + 634 i * PAGE_SIZE); 652 635 653 636 ASSERT(pte); … … 658 641 (area->backend->frame_free)) { 659 642 area->backend->frame_free(area, 660 ptr + P2SZ(i),643 ptr + i * PAGE_SIZE, 661 644 PTE_GET_FRAME(pte)); 662 645 } 663 646 664 page_mapping_remove(as, ptr + P2SZ(i)); 647 page_mapping_remove(as, ptr + 648 i * PAGE_SIZE); 665 649 } 666 650 } … … 671 655 */ 672 656 673 tlb_invalidate_pages(as->asid, area->base + P2SZ(pages),657 tlb_invalidate_pages(as->asid, area->base + pages * PAGE_SIZE, 674 658 area->pages - pages); 675 659 676 660 /* 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); 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); 682 665 tlb_shootdown_finalize(ipl); 683 666 … … 688 671 * Check for overlaps with other address space areas. 689 672 */ 690 if (!check_area_conflicts(as, address, pages, area)) { 673 if (!check_area_conflicts(as, address, pages * PAGE_SIZE, 674 area)) { 691 675 mutex_unlock(&area->lock); 692 676 mutex_unlock(&as->lock); 693 677 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;702 678 } 703 679 } … … 769 745 return ENOENT; 770 746 } 771 772 if (area->backend && area->backend->destroy)773 area->backend->destroy(area);774 747 775 748 uintptr_t base = area->base; … … 798 771 799 772 for (size = 0; size < (size_t) node->value[i]; size++) { 800 pte_t *pte = page_mapping_find(as, 801 ptr + P2SZ(size), false); 773 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 802 774 803 775 ASSERT(pte); … … 808 780 (area->backend->frame_free)) { 809 781 area->backend->frame_free(area, 810 ptr + P2SZ(size), 811 PTE_GET_FRAME(pte)); 782 ptr + size * PAGE_SIZE, PTE_GET_FRAME(pte)); 812 783 } 813 784 814 page_mapping_remove(as, ptr + P2SZ(size));785 page_mapping_remove(as, ptr + size * PAGE_SIZE); 815 786 } 816 787 } … … 824 795 825 796 /* 826 * Invalidate potential software translation caches 827 * (e.g. TSB on sparc64, PHT on ppc32).797 * Invalidate potential software translation caches (e.g. TSB on 798 * sparc64). 828 799 */ 829 800 as_invalidate_translation_cache(as, area->base, area->pages); … … 899 870 } 900 871 901 size_t src_size = P2SZ(src_area->pages);872 size_t src_size = src_area->pages * PAGE_SIZE; 902 873 unsigned int src_flags = src_area->flags; 903 874 mem_backend_t *src_backend = src_area->backend; … … 1096 1067 for (cur = area->used_space.leaf_head.next; 1097 1068 cur != &area->used_space.leaf_head; cur = cur->next) { 1098 btree_node_t *node = list_get_instance(cur, btree_node_t,1099 leaf_link);1069 btree_node_t *node 1070 = list_get_instance(cur, btree_node_t, leaf_link); 1100 1071 btree_key_t i; 1101 1072 … … 1105 1076 1106 1077 for (size = 0; size < (size_t) node->value[i]; size++) { 1107 pte_t *pte = page_mapping_find(as, 1108 ptr + P2SZ(size), false); 1078 pte_t *pte = page_mapping_find(as, ptr + size * PAGE_SIZE); 1109 1079 1110 1080 ASSERT(pte); … … 1115 1085 1116 1086 /* Remove old mapping */ 1117 page_mapping_remove(as, ptr + P2SZ(size));1087 page_mapping_remove(as, ptr + size * PAGE_SIZE); 1118 1088 } 1119 1089 } … … 1127 1097 1128 1098 /* 1129 * Invalidate potential software translation caches 1130 * (e.g. TSB on sparc64, PHT on ppc32).1099 * Invalidate potential software translation caches (e.g. TSB on 1100 * sparc64). 1131 1101 */ 1132 1102 as_invalidate_translation_cache(as, area->base, area->pages); … … 1161 1131 1162 1132 /* Insert the new mapping */ 1163 page_mapping_insert(as, ptr + P2SZ(size),1133 page_mapping_insert(as, ptr + size * PAGE_SIZE, 1164 1134 old_frame[frame_idx++], page_flags); 1165 1135 … … 1242 1212 */ 1243 1213 pte_t *pte; 1244 if ((pte = page_mapping_find(AS, page , false))) {1214 if ((pte = page_mapping_find(AS, page))) { 1245 1215 if (PTE_PRESENT(pte)) { 1246 1216 if (((access == PF_ACCESS_READ) && PTE_READABLE(pte)) || … … 1483 1453 1484 1454 if (src_area) { 1485 size = P2SZ(src_area->pages);1455 size = src_area->pages * PAGE_SIZE; 1486 1456 mutex_unlock(&src_area->lock); 1487 1457 } else … … 1538 1508 if (page >= right_pg) { 1539 1509 /* Do nothing. */ 1540 } else if (overlaps(page, P2SZ(count), left_pg,1541 P2SZ(left_cnt))) {1510 } else if (overlaps(page, count * PAGE_SIZE, left_pg, 1511 left_cnt * PAGE_SIZE)) { 1542 1512 /* The interval intersects with the left interval. */ 1543 1513 return false; 1544 } else if (overlaps(page, P2SZ(count), right_pg,1545 P2SZ(right_cnt))) {1514 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1515 right_cnt * PAGE_SIZE)) { 1546 1516 /* The interval intersects with the right interval. */ 1547 1517 return false; 1548 } else if ((page == left_pg + P2SZ(left_cnt)) &&1549 (page + P2SZ(count)== right_pg)) {1518 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1519 (page + count * PAGE_SIZE == right_pg)) { 1550 1520 /* 1551 1521 * The interval can be added by merging the two already … … 1555 1525 btree_remove(&area->used_space, right_pg, leaf); 1556 1526 goto success; 1557 } else if (page == left_pg + P2SZ(left_cnt)) {1527 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1558 1528 /* 1559 1529 * The interval can be added by simply growing the left … … 1562 1532 node->value[node->keys - 1] += count; 1563 1533 goto success; 1564 } else if (page + P2SZ(count)== right_pg) {1534 } else if (page + count * PAGE_SIZE == right_pg) { 1565 1535 /* 1566 1536 * The interval can be addded by simply moving base of … … 1589 1559 */ 1590 1560 1591 if (overlaps(page, P2SZ(count), right_pg, P2SZ(right_cnt))) { 1561 if (overlaps(page, count * PAGE_SIZE, right_pg, 1562 right_cnt * PAGE_SIZE)) { 1592 1563 /* The interval intersects with the right interval. */ 1593 1564 return false; 1594 } else if (page + P2SZ(count)== right_pg) {1565 } else if (page + count * PAGE_SIZE == right_pg) { 1595 1566 /* 1596 1567 * The interval can be added by moving the base of the … … 1627 1598 if (page < left_pg) { 1628 1599 /* Do nothing. */ 1629 } else if (overlaps(page, P2SZ(count), left_pg,1630 P2SZ(left_cnt))) {1600 } else if (overlaps(page, count * PAGE_SIZE, left_pg, 1601 left_cnt * PAGE_SIZE)) { 1631 1602 /* The interval intersects with the left interval. */ 1632 1603 return false; 1633 } else if (overlaps(page, P2SZ(count), right_pg,1634 P2SZ(right_cnt))) {1604 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1605 right_cnt * PAGE_SIZE)) { 1635 1606 /* The interval intersects with the right interval. */ 1636 1607 return false; 1637 } else if ((page == left_pg + P2SZ(left_cnt)) &&1638 (page + P2SZ(count)== right_pg)) {1608 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1609 (page + count * PAGE_SIZE == right_pg)) { 1639 1610 /* 1640 1611 * The interval can be added by merging the two already … … 1644 1615 btree_remove(&area->used_space, right_pg, node); 1645 1616 goto success; 1646 } else if (page == left_pg + P2SZ(left_cnt)) {1617 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1647 1618 /* 1648 1619 * The interval can be added by simply growing the left … … 1651 1622 leaf->value[leaf->keys - 1] += count; 1652 1623 goto success; 1653 } else if (page + P2SZ(count)== right_pg) {1624 } else if (page + count * PAGE_SIZE == right_pg) { 1654 1625 /* 1655 1626 * The interval can be addded by simply moving base of … … 1678 1649 */ 1679 1650 1680 if (overlaps(page, P2SZ(count), left_pg, P2SZ(left_cnt))) { 1651 if (overlaps(page, count * PAGE_SIZE, left_pg, 1652 left_cnt * PAGE_SIZE)) { 1681 1653 /* The interval intersects with the left interval. */ 1682 1654 return false; 1683 } else if (left_pg + P2SZ(left_cnt)== page) {1655 } else if (left_pg + left_cnt * PAGE_SIZE == page) { 1684 1656 /* 1685 1657 * The interval can be added by growing the left … … 1716 1688 */ 1717 1689 1718 if (overlaps(page, P2SZ(count), left_pg,1719 P2SZ(left_cnt))) {1690 if (overlaps(page, count * PAGE_SIZE, left_pg, 1691 left_cnt * PAGE_SIZE)) { 1720 1692 /* 1721 1693 * The interval intersects with the left … … 1723 1695 */ 1724 1696 return false; 1725 } else if (overlaps(page, P2SZ(count), right_pg,1726 P2SZ(right_cnt))) {1697 } else if (overlaps(page, count * PAGE_SIZE, right_pg, 1698 right_cnt * PAGE_SIZE)) { 1727 1699 /* 1728 1700 * The interval intersects with the right … … 1730 1702 */ 1731 1703 return false; 1732 } else if ((page == left_pg + P2SZ(left_cnt)) &&1733 (page + P2SZ(count)== right_pg)) {1704 } else if ((page == left_pg + left_cnt * PAGE_SIZE) && 1705 (page + count * PAGE_SIZE == right_pg)) { 1734 1706 /* 1735 1707 * The interval can be added by merging the two … … 1739 1711 btree_remove(&area->used_space, right_pg, leaf); 1740 1712 goto success; 1741 } else if (page == left_pg + P2SZ(left_cnt)) {1713 } else if (page == left_pg + left_cnt * PAGE_SIZE) { 1742 1714 /* 1743 1715 * The interval can be added by simply growing … … 1746 1718 leaf->value[i - 1] += count; 1747 1719 goto success; 1748 } else if (page + P2SZ(count)== right_pg) {1720 } else if (page + count * PAGE_SIZE == right_pg) { 1749 1721 /* 1750 1722 * The interval can be addded by simply moving … … 1812 1784 for (i = 0; i < leaf->keys; i++) { 1813 1785 if (leaf->key[i] == page) { 1814 leaf->key[i] += P2SZ(count);1786 leaf->key[i] += count * PAGE_SIZE; 1815 1787 leaf->value[i] -= count; 1816 1788 goto success; … … 1822 1794 } 1823 1795 1824 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, 1825 leaf); 1796 btree_node_t *node = btree_leaf_node_left_neighbour(&area->used_space, leaf); 1826 1797 if ((node) && (page < leaf->key[0])) { 1827 1798 uintptr_t left_pg = node->key[node->keys - 1]; 1828 1799 size_t left_cnt = (size_t) node->value[node->keys - 1]; 1829 1800 1830 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1831 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 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) { 1832 1805 /* 1833 1806 * The interval is contained in the rightmost … … 1838 1811 node->value[node->keys - 1] -= count; 1839 1812 goto success; 1840 } else if (page + P2SZ(count) < 1841 left_pg + P2SZ(left_cnt)) { 1842 size_t new_cnt; 1843 1813 } else if (page + count * PAGE_SIZE < 1814 left_pg + left_cnt*PAGE_SIZE) { 1844 1815 /* 1845 1816 * The interval is contained in the rightmost … … 1849 1820 * new interval. 1850 1821 */ 1851 new_cnt = ((left_pg + P2SZ(left_cnt)) -1852 (page + P2SZ(count))) >> PAGE_WIDTH;1822 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - 1823 (page + count*PAGE_SIZE)) >> PAGE_WIDTH; 1853 1824 node->value[node->keys - 1] -= count + new_cnt; 1854 1825 btree_insert(&area->used_space, page + 1855 P2SZ(count), (void *) new_cnt, leaf);1826 count * PAGE_SIZE, (void *) new_cnt, leaf); 1856 1827 goto success; 1857 1828 } … … 1866 1837 size_t left_cnt = (size_t) leaf->value[leaf->keys - 1]; 1867 1838 1868 if (overlaps(left_pg, P2SZ(left_cnt), page, P2SZ(count))) { 1869 if (page + P2SZ(count) == left_pg + P2SZ(left_cnt)) { 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) { 1870 1843 /* 1871 1844 * The interval is contained in the rightmost … … 1875 1848 leaf->value[leaf->keys - 1] -= count; 1876 1849 goto success; 1877 } else if (page + P2SZ(count) < left_pg + 1878 P2SZ(left_cnt)) { 1879 size_t new_cnt; 1880 1850 } else if (page + count * PAGE_SIZE < left_pg + 1851 left_cnt * PAGE_SIZE) { 1881 1852 /* 1882 1853 * The interval is contained in the rightmost … … 1886 1857 * interval. 1887 1858 */ 1888 new_cnt = ((left_pg + P2SZ(left_cnt)) -1889 (page + P2SZ(count))) >> PAGE_WIDTH;1859 size_t new_cnt = ((left_pg + left_cnt * PAGE_SIZE) - 1860 (page + count * PAGE_SIZE)) >> PAGE_WIDTH; 1890 1861 leaf->value[leaf->keys - 1] -= count + new_cnt; 1891 1862 btree_insert(&area->used_space, page + 1892 P2SZ(count), (void *) new_cnt, leaf);1863 count * PAGE_SIZE, (void *) new_cnt, leaf); 1893 1864 goto success; 1894 1865 } … … 1912 1883 * to (i - 1) and i. 1913 1884 */ 1914 if (overlaps(left_pg, P2SZ(left_cnt), page,1915 P2SZ(count))) {1916 if (page + P2SZ(count)==1917 left_pg + P2SZ(left_cnt)) {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) { 1918 1889 /* 1919 1890 * The interval is contained in the … … 1924 1895 leaf->value[i - 1] -= count; 1925 1896 goto success; 1926 } else if (page + P2SZ(count) < 1927 left_pg + P2SZ(left_cnt)) { 1928 size_t new_cnt; 1929 1897 } else if (page + count * PAGE_SIZE < 1898 left_pg + left_cnt * PAGE_SIZE) { 1930 1899 /* 1931 1900 * The interval is contained in the … … 1935 1904 * also inserting a new interval. 1936 1905 */ 1937 new_cnt = ((left_pg + P2SZ(left_cnt)) - 1938 (page + P2SZ(count))) >> 1906 size_t new_cnt = ((left_pg + 1907 left_cnt * PAGE_SIZE) - 1908 (page + count * PAGE_SIZE)) >> 1939 1909 PAGE_WIDTH; 1940 1910 leaf->value[i - 1] -= count + new_cnt; 1941 1911 btree_insert(&area->used_space, page + 1942 P2SZ(count), (void *) new_cnt,1912 count * PAGE_SIZE, (void *) new_cnt, 1943 1913 leaf); 1944 1914 goto success; … … 1989 1959 { 1990 1960 return (sysarg_t) as_area_destroy(AS, address); 1991 }1992 1993 /** Return pointer to unmapped address space area1994 *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-aligned2008 * address. Check for possible overflow in2009 * 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 sz2017 * 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 1961 } 2059 1962 … … 2101 2004 2102 2005 info[area_idx].start_addr = area->base; 2103 info[area_idx].size = P2SZ(area->pages);2006 info[area_idx].size = FRAMES2SIZE(area->pages); 2104 2007 info[area_idx].flags = area->flags; 2105 2008 ++area_idx; … … 2124 2027 mutex_lock(&as->lock); 2125 2028 2126 /* Print out info about address space areas */2029 /* print out info about address space areas */ 2127 2030 link_t *cur; 2128 2031 for (cur = as->as_area_btree.leaf_head.next; … … 2139 2042 " (%p - %p)\n", area, (void *) area->base, 2140 2043 area->pages, (void *) area->base, 2141 (void *) (area->base + P2SZ(area->pages)));2044 (void *) (area->base + FRAMES2SIZE(area->pages))); 2142 2045 mutex_unlock(&area->lock); 2143 2046 }
Note:
See TracChangeset
for help on using the changeset viewer.