Subversion Repositories HelenOS

Rev

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

Rev 3153 Rev 3156
Line 789... Line 789...
789
    as_area_t *area;
789
    as_area_t *area;
790
    uintptr_t base;
790
    uintptr_t base;
791
    link_t *cur;
791
    link_t *cur;
792
    ipl_t ipl;
792
    ipl_t ipl;
793
    int page_flags;
793
    int page_flags;
794
    uintptr_t old_frame;
794
    uintptr_t *old_frame;
-
 
795
    index_t frame_idx;
-
 
796
    count_t used_pages;
795
 
797
 
796
    /* Flags for the new memory mapping */
798
    /* Flags for the new memory mapping */
797
    page_flags = area_flags_to_page_flags(flags);
799
    page_flags = area_flags_to_page_flags(flags);
798
 
800
 
799
    ipl = interrupts_disable();
801
    ipl = interrupts_disable();
Line 816... Line 818...
816
    }
818
    }
817
 
819
 
818
    base = area->base;
820
    base = area->base;
819
 
821
 
820
    /*
822
    /*
-
 
823
     * Compute total number of used pages in the used_space B+tree
-
 
824
     */
-
 
825
    used_pages = 0;
-
 
826
 
-
 
827
    for (cur = area->used_space.leaf_head.next;
-
 
828
        cur != &area->used_space.leaf_head; cur = cur->next) {
-
 
829
        btree_node_t *node;
-
 
830
        unsigned int i;
-
 
831
       
-
 
832
        node = list_get_instance(cur, btree_node_t, leaf_link);
-
 
833
        for (i = 0; i < node->keys; i++) {
-
 
834
            used_pages += (count_t) node->value[i];
-
 
835
        }
-
 
836
    }
-
 
837
 
-
 
838
    /* An array for storing frame numbers */
-
 
839
    old_frame = malloc(used_pages * sizeof(uintptr_t), 0);
-
 
840
 
-
 
841
    /*
821
     * Start TLB shootdown sequence.
842
     * Start TLB shootdown sequence.
822
     */
843
     */
823
    tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
844
    tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages);
824
 
845
 
825
    /*
846
    /*
826
     * Visit only the pages mapped by used_space B+tree.
847
     * Remove used pages from page tables and remember their frame
-
 
848
     * numbers.
827
     */
849
     */
-
 
850
    frame_idx = 0;
-
 
851
 
828
    for (cur = area->used_space.leaf_head.next;
852
    for (cur = area->used_space.leaf_head.next;
829
        cur != &area->used_space.leaf_head; cur = cur->next) {
853
        cur != &area->used_space.leaf_head; cur = cur->next) {
830
        btree_node_t *node;
854
        btree_node_t *node;
831
        unsigned int i;
855
        unsigned int i;
832
       
856
       
Line 839... Line 863...
839
            for (j = 0; j < (count_t) node->value[i]; j++) {
863
            for (j = 0; j < (count_t) node->value[i]; j++) {
840
                page_table_lock(as, false);
864
                page_table_lock(as, false);
841
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
865
                pte = page_mapping_find(as, b + j * PAGE_SIZE);
842
                ASSERT(pte && PTE_VALID(pte) &&
866
                ASSERT(pte && PTE_VALID(pte) &&
843
                    PTE_PRESENT(pte));
867
                    PTE_PRESENT(pte));
844
                old_frame = PTE_GET_FRAME(pte);
868
                old_frame[frame_idx++] = PTE_GET_FRAME(pte);
845
 
869
 
846
                /* Remove old mapping and insert the new one */
870
                /* Remove old mapping */
847
                page_mapping_remove(as, b + j * PAGE_SIZE);
871
                page_mapping_remove(as, b + j * PAGE_SIZE);
848
                page_mapping_insert(as, b + j * PAGE_SIZE,
-
 
849
                    old_frame, page_flags);
-
 
850
 
-
 
851
                page_table_unlock(as, false);
872
                page_table_unlock(as, false);
852
            }
873
            }
853
        }
874
        }
854
    }
875
    }
855
 
876
 
Line 862... Line 883...
862
     * Invalidate potential software translation caches (e.g. TSB on
883
     * Invalidate potential software translation caches (e.g. TSB on
863
     * sparc64).
884
     * sparc64).
864
     */
885
     */
865
    as_invalidate_translation_cache(as, area->base, area->pages);
886
    as_invalidate_translation_cache(as, area->base, area->pages);
866
    tlb_shootdown_finalize();
887
    tlb_shootdown_finalize();
-
 
888
 
-
 
889
    /*
-
 
890
     * Map pages back in with new flags. This step is kept separate
-
 
891
     * so that there's no instant when the memory area could be
-
 
892
     * accesed with both the old and the new flags at once.
-
 
893
     */
-
 
894
    frame_idx = 0;
-
 
895
 
-
 
896
    for (cur = area->used_space.leaf_head.next;
-
 
897
        cur != &area->used_space.leaf_head; cur = cur->next) {
-
 
898
        btree_node_t *node;
-
 
899
        unsigned int i;
867
   
900
       
-
 
901
        node = list_get_instance(cur, btree_node_t, leaf_link);
-
 
902
        for (i = 0; i < node->keys; i++) {
-
 
903
            uintptr_t b = node->key[i];
-
 
904
            count_t j;
-
 
905
           
-
 
906
            for (j = 0; j < (count_t) node->value[i]; j++) {
-
 
907
                page_table_lock(as, false);
-
 
908
 
-
 
909
                /* Insert the new mapping */
-
 
910
                page_mapping_insert(as, b + j * PAGE_SIZE,
-
 
911
                    old_frame[frame_idx++], page_flags);
-
 
912
 
-
 
913
                page_table_unlock(as, false);
-
 
914
            }
-
 
915
        }
-
 
916
    }
-
 
917
 
-
 
918
    free(old_frame);
-
 
919
 
868
    mutex_unlock(&area->lock);
920
    mutex_unlock(&area->lock);
869
    mutex_unlock(&as->lock);
921
    mutex_unlock(&as->lock);
870
    interrupts_restore(ipl);
922
    interrupts_restore(ipl);
871
 
923
 
872
    return 0;
924
    return 0;