Rev 3386 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 3386 | Rev 4153 | ||
|---|---|---|---|
| Line 120... | Line 120... | ||
| 120 | { |
120 | { |
| 121 | as_t *as = (as_t *) obj; |
121 | as_t *as = (as_t *) obj; |
| 122 | int rc; |
122 | int rc; |
| 123 | 123 | ||
| 124 | link_initialize(&as->inactive_as_with_asid_link); |
124 | link_initialize(&as->inactive_as_with_asid_link); |
| 125 | mutex_initialize(&as->lock, MUTEX_PASSIVE); |
125 | mutex_initialize(&as->lock, MUTEX_PASSIVE); |
| 126 | 126 | ||
| 127 | rc = as_constructor_arch(as, flags); |
127 | rc = as_constructor_arch(as, flags); |
| 128 | 128 | ||
| 129 | return rc; |
129 | return rc; |
| 130 | } |
130 | } |
| Line 144... | Line 144... | ||
| 144 | as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
144 | as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
| 145 | as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
145 | as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
| 146 | 146 | ||
| 147 | AS_KERNEL = as_create(FLAG_AS_KERNEL); |
147 | AS_KERNEL = as_create(FLAG_AS_KERNEL); |
| 148 | if (!AS_KERNEL) |
148 | if (!AS_KERNEL) |
| 149 | panic("can't create kernel address space\n"); |
149 | panic("Cannot create kernel address space."); |
| 150 | 150 | ||
| - | 151 | /* Make sure the kernel address space |
|
| - | 152 | * reference count never drops to zero. |
|
| - | 153 | */ |
|
| - | 154 | atomic_set(&AS_KERNEL->refcount, 1); |
|
| 151 | } |
155 | } |
| 152 | 156 | ||
| 153 | /** Create address space. |
157 | /** Create address space. |
| 154 | * |
158 | * |
| 155 | * @param flags Flags that influence the way in wich the address space |
159 | * @param flags Flags that influence the way in wich the address space |
| Line 174... | Line 178... | ||
| 174 | #ifdef AS_PAGE_TABLE |
178 | #ifdef AS_PAGE_TABLE |
| 175 | as->genarch.page_table = page_table_create(flags); |
179 | as->genarch.page_table = page_table_create(flags); |
| 176 | #else |
180 | #else |
| 177 | page_table_create(flags); |
181 | page_table_create(flags); |
| 178 | #endif |
182 | #endif |
| 179 | 183 | ||
| 180 | return as; |
184 | return as; |
| 181 | } |
185 | } |
| 182 | 186 | ||
| 183 | /** Destroy adress space. |
187 | /** Destroy adress space. |
| 184 | * |
188 | * |
| Line 383... | Line 387... | ||
| 383 | return EPERM; |
387 | return EPERM; |
| 384 | } |
388 | } |
| 385 | 389 | ||
| 386 | if (pages < area->pages) { |
390 | if (pages < area->pages) { |
| 387 | bool cond; |
391 | bool cond; |
| 388 | uintptr_t start_free = area->base + pages*PAGE_SIZE; |
392 | uintptr_t start_free = area->base + pages * PAGE_SIZE; |
| 389 | 393 | ||
| 390 | /* |
394 | /* |
| 391 | * Shrinking the area. |
395 | * Shrinking the area. |
| 392 | * No need to check for overlaps. |
396 | * No need to check for overlaps. |
| 393 | */ |
397 | */ |
| 394 | 398 | ||
| 395 | /* |
399 | /* |
| 396 | * Start TLB shootdown sequence. |
400 | * Start TLB shootdown sequence. |
| 397 | */ |
401 | */ |
| 398 | tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + |
402 | tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base + |
| 399 | pages * PAGE_SIZE, area->pages - pages); |
403 | pages * PAGE_SIZE, area->pages - pages); |
| 400 | 404 | ||
| 401 | /* |
405 | /* |
| 402 | * Remove frames belonging to used space starting from |
406 | * Remove frames belonging to used space starting from |
| 403 | * the highest addresses downwards until an overlap with |
407 | * the highest addresses downwards until an overlap with |
| Line 438... | Line 442... | ||
| 438 | 442 | ||
| 439 | cond = false; /* we are almost done */ |
443 | cond = false; /* we are almost done */ |
| 440 | i = (start_free - b) >> PAGE_WIDTH; |
444 | i = (start_free - b) >> PAGE_WIDTH; |
| 441 | if (!used_space_remove(area, start_free, |
445 | if (!used_space_remove(area, start_free, |
| 442 | c - i)) |
446 | c - i)) |
| 443 | panic("Could not remove used " |
447 | panic("Cannot remove used " |
| 444 | "space.\n"); |
448 | "space."); |
| 445 | } else { |
449 | } else { |
| 446 | /* |
450 | /* |
| 447 | * The interval of used space can be |
451 | * The interval of used space can be |
| 448 | * completely removed. |
452 | * completely removed. |
| 449 | */ |
453 | */ |
| 450 | if (!used_space_remove(area, b, c)) |
454 | if (!used_space_remove(area, b, c)) |
| 451 | panic("Could not remove used " |
455 | panic("Cannot remove used " |
| 452 | "space.\n"); |
456 | "space."); |
| 453 | } |
457 | } |
| 454 | 458 | ||
| 455 | for (; i < c; i++) { |
459 | for (; i < c; i++) { |
| 456 | pte_t *pte; |
460 | pte_t *pte; |
| 457 | 461 | ||
| Line 767... | Line 771... | ||
| 767 | * The idea is to have the same data, but with a different access mode. |
771 | * The idea is to have the same data, but with a different access mode. |
| 768 | * This is needed e.g. for writing code into memory and then executing it. |
772 | * This is needed e.g. for writing code into memory and then executing it. |
| 769 | * In order for this to work properly, this may copy the data |
773 | * In order for this to work properly, this may copy the data |
| 770 | * into private anonymous memory (unless it's already there). |
774 | * into private anonymous memory (unless it's already there). |
| 771 | * |
775 | * |
| 772 | * @param as Address space. |
776 | * @param as Address space. |
| 773 | * @param flags Flags of the area memory. |
777 | * @param flags Flags of the area memory. |
| 774 | * @param address Address withing the area to be changed. |
778 | * @param address Address within the area to be changed. |
| - | 779 | * |
|
| - | 780 | * @return Zero on success or a value from @ref errno.h on failure. |
|
| 775 | * |
781 | * |
| 776 | * @return Zero on success or a value from @ref errno.h on failure. |
- | |
| 777 | */ |
782 | */ |
| 778 | int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
783 | int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
| 779 | { |
784 | { |
| 780 | as_area_t *area; |
785 | as_area_t *area; |
| 781 | uintptr_t base; |
786 | uintptr_t base; |
| Line 783... | Line 788... | ||
| 783 | ipl_t ipl; |
788 | ipl_t ipl; |
| 784 | int page_flags; |
789 | int page_flags; |
| 785 | uintptr_t *old_frame; |
790 | uintptr_t *old_frame; |
| 786 | index_t frame_idx; |
791 | index_t frame_idx; |
| 787 | count_t used_pages; |
792 | count_t used_pages; |
| 788 | 793 | ||
| 789 | /* Flags for the new memory mapping */ |
794 | /* Flags for the new memory mapping */ |
| 790 | page_flags = area_flags_to_page_flags(flags); |
795 | page_flags = area_flags_to_page_flags(flags); |
| 791 | 796 | ||
| 792 | ipl = interrupts_disable(); |
797 | ipl = interrupts_disable(); |
| 793 | mutex_lock(&as->lock); |
798 | mutex_lock(&as->lock); |
| Line 797... | Line 802... | ||
| 797 | mutex_unlock(&as->lock); |
802 | mutex_unlock(&as->lock); |
| 798 | interrupts_restore(ipl); |
803 | interrupts_restore(ipl); |
| 799 | return ENOENT; |
804 | return ENOENT; |
| 800 | } |
805 | } |
| 801 | 806 | ||
| 802 | if (area->sh_info || area->backend != &anon_backend) { |
807 | if ((area->sh_info) || (area->backend != &anon_backend)) { |
| 803 | /* Copying shared areas not supported yet */ |
808 | /* Copying shared areas not supported yet */ |
| 804 | /* Copying non-anonymous memory not supported yet */ |
809 | /* Copying non-anonymous memory not supported yet */ |
| 805 | mutex_unlock(&area->lock); |
810 | mutex_unlock(&area->lock); |
| 806 | mutex_unlock(&as->lock); |
811 | mutex_unlock(&as->lock); |
| 807 | interrupts_restore(ipl); |
812 | interrupts_restore(ipl); |
| Line 868... | Line 873... | ||
| 868 | /* |
873 | /* |
| 869 | * Finish TLB shootdown sequence. |
874 | * Finish TLB shootdown sequence. |
| 870 | */ |
875 | */ |
| 871 | 876 | ||
| 872 | tlb_invalidate_pages(as->asid, area->base, area->pages); |
877 | tlb_invalidate_pages(as->asid, area->base, area->pages); |
| - | 878 | ||
| 873 | /* |
879 | /* |
| 874 | * Invalidate potential software translation caches (e.g. TSB on |
880 | * Invalidate potential software translation caches (e.g. TSB on |
| 875 | * sparc64). |
881 | * sparc64). |
| 876 | */ |
882 | */ |
| 877 | as_invalidate_translation_cache(as, area->base, area->pages); |
883 | as_invalidate_translation_cache(as, area->base, area->pages); |
| Line 1658... | Line 1664... | ||
| 1658 | } |
1664 | } |
| 1659 | } |
1665 | } |
| 1660 | } |
1666 | } |
| 1661 | 1667 | ||
| 1662 | panic("Inconsistency detected while adding %" PRIc " pages of used " |
1668 | panic("Inconsistency detected while adding %" PRIc " pages of used " |
| 1663 | "space at %p.\n", count, page); |
1669 | "space at %p.", count, page); |
| 1664 | } |
1670 | } |
| 1665 | 1671 | ||
| 1666 | /** Mark portion of address space area as unused. |
1672 | /** Mark portion of address space area as unused. |
| 1667 | * |
1673 | * |
| 1668 | * The address space area must be already locked. |
1674 | * The address space area must be already locked. |
| Line 1837... | Line 1843... | ||
| 1837 | } |
1843 | } |
| 1838 | } |
1844 | } |
| 1839 | 1845 | ||
| 1840 | error: |
1846 | error: |
| 1841 | panic("Inconsistency detected while removing %" PRIc " pages of used " |
1847 | panic("Inconsistency detected while removing %" PRIc " pages of used " |
| 1842 | "space from %p.\n", count, page); |
1848 | "space from %p.", count, page); |
| 1843 | } |
1849 | } |
| 1844 | 1850 | ||
| 1845 | /** Remove reference to address space area share info. |
1851 | /** Remove reference to address space area share info. |
| 1846 | * |
1852 | * |
| 1847 | * If the reference count drops to 0, the sh_info is deallocated. |
1853 | * If the reference count drops to 0, the sh_info is deallocated. |