Subversion Repositories HelenOS

Rev

Rev 2927 | Rev 2985 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2927 Rev 2984
Line 773... Line 773...
773
        return false;
773
        return false;
774
   
774
   
775
    return true;
775
    return true;
776
}
776
}
777
 
777
 
-
 
778
/** Change adress area flags.
-
 
779
 *
-
 
780
 * The idea is to have the same data, but with a different access mode.
-
 
781
 * This is needed e.g. for writing code into memory and then executing it.
-
 
782
 * In order for this to work properly, this may copy the data
-
 
783
 * into private anonymous memory (unless it's already there).
-
 
784
 *
-
 
785
 * @param as Address space.
-
 
786
 * @param flags Flags of the area memory.
-
 
787
 * @param address Address withing the area to be changed.
-
 
788
 *
-
 
789
 * @return Zero on success or a value from @ref errno.h on failure.
-
 
790
 */
-
 
791
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
-
 
792
{
-
 
793
    as_area_t *area;
-
 
794
    uintptr_t base;
-
 
795
    link_t *cur;
-
 
796
    ipl_t ipl;
-
 
797
 
-
 
798
    ipl = interrupts_disable();
-
 
799
    mutex_lock(&as->lock);
-
 
800
 
-
 
801
    area = find_area_and_lock(as, address);
-
 
802
    if (!area) {
-
 
803
        mutex_unlock(&as->lock);
-
 
804
        interrupts_restore(ipl);
-
 
805
        return ENOENT;
-
 
806
    }
-
 
807
 
-
 
808
    if (area->sh_info || area->backend != &anon_backend) {
-
 
809
        /* Copying shared areas not supported yet */
-
 
810
        /* Copying non-anonymous memory not supported yet */
-
 
811
        mutex_unlock(&as->lock);
-
 
812
        interrupts_restore(ipl);
-
 
813
        return ENOTSUP;
-
 
814
    }
-
 
815
 
-
 
816
    base = area->base;
-
 
817
 
-
 
818
    /*
-
 
819
     * Start TLB shootdown sequence.
-
 
820
     */
-
 
821
    tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
-
 
822
 
-
 
823
    /*
-
 
824
     * Visit only the pages mapped by used_space B+tree.
-
 
825
     */
-
 
826
    for (cur = area->used_space.leaf_head.next;
-
 
827
        cur != &area->used_space.leaf_head; cur = cur->next) {
-
 
828
        btree_node_t *node;
-
 
829
        unsigned int i;
-
 
830
       
-
 
831
        node = list_get_instance(cur, btree_node_t, leaf_link);
-
 
832
        for (i = 0; i < node->keys; i++) {
-
 
833
            uintptr_t b = node->key[i];
-
 
834
            count_t j;
-
 
835
            pte_t *pte;
-
 
836
           
-
 
837
            for (j = 0; j < (count_t) node->value[i]; j++) {
-
 
838
                page_table_lock(as, false);
-
 
839
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
-
 
840
                ASSERT(pte && PTE_VALID(pte) &&
-
 
841
                    PTE_PRESENT(pte));
-
 
842
 
-
 
843
                /* Remove old mapping and insert the new one */
-
 
844
                page_mapping_remove(as, b + j * PAGE_SIZE);
-
 
845
                page_mapping_insert(as, b + j * PAGE_SIZE,
-
 
846
                    PTE_GET_FRAME(pte), flags);
-
 
847
                page_table_unlock(as, false);
-
 
848
            }
-
 
849
        }
-
 
850
    }
-
 
851
 
-
 
852
    /*
-
 
853
     * Finish TLB shootdown sequence.
-
 
854
     */
-
 
855
 
-
 
856
    tlb_invalidate_pages(as->asid, area->base, area->pages);
-
 
857
    /*
-
 
858
     * Invalidate potential software translation caches (e.g. TSB on
-
 
859
     * sparc64).
-
 
860
     */
-
 
861
    as_invalidate_translation_cache(as, area->base, area->pages);
-
 
862
    tlb_shootdown_finalize();
-
 
863
   
-
 
864
    mutex_unlock(&area->lock);
-
 
865
    mutex_unlock(&as->lock);
-
 
866
    interrupts_restore(ipl);
-
 
867
 
-
 
868
    return 0;
-
 
869
}
-
 
870
 
-
 
871
 
778
/** Handle page fault within the current address space.
872
/** Handle page fault within the current address space.
779
 *
873
 *
780
 * This is the high-level page fault handler. It decides
874
 * This is the high-level page fault handler. It decides
781
 * whether the page fault can be resolved by any backend
875
 * whether the page fault can be resolved by any backend
782
 * and if so, it invokes the backend to resolve the page
876
 * and if so, it invokes the backend to resolve the page
Line 1768... Line 1862...
1768
unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
1862
unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags)
1769
{
1863
{
1770
    return (unative_t) as_area_resize(AS, address, size, 0);
1864
    return (unative_t) as_area_resize(AS, address, size, 0);
1771
}
1865
}
1772
 
1866
 
-
 
1867
/** Wrapper for as_area_change_flags(). */
-
 
1868
unative_t sys_as_area_change_flags(uintptr_t address, int flags)
-
 
1869
{
-
 
1870
    return (unative_t) as_area_change_flags(AS, flags, address);
-
 
1871
}
-
 
1872
 
1773
/** Wrapper for as_area_destroy(). */
1873
/** Wrapper for as_area_destroy(). */
1774
unative_t sys_as_area_destroy(uintptr_t address)
1874
unative_t sys_as_area_destroy(uintptr_t address)
1775
{
1875
{
1776
    return (unative_t) as_area_destroy(AS, address);
1876
    return (unative_t) as_area_destroy(AS, address);
1777
}
1877
}