Subversion Repositories HelenOS

Rev

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

Rev 2132 Rev 2134
Line 76... Line 76...
76
 *     serviced).
76
 *     serviced).
77
 */
77
 */
78
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
78
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access)
79
{
79
{
80
    uintptr_t frame;
80
    uintptr_t frame;
-
 
81
    bool dirty = false;
81
 
82
 
82
    if (!as_area_check_access(area, access))
83
    if (!as_area_check_access(area, access))
83
        return AS_PF_FAULT;
84
        return AS_PF_FAULT;
84
 
85
 
85
    if (area->sh_info) {
86
    if (area->sh_info) {
Line 92... Line 93...
92
         * In the case that the pagemap does not contain the respective
93
         * In the case that the pagemap does not contain the respective
93
         * mapping, a new frame is allocated and the mapping is created.
94
         * mapping, a new frame is allocated and the mapping is created.
94
         */
95
         */
95
        mutex_lock(&area->sh_info->lock);
96
        mutex_lock(&area->sh_info->lock);
96
        frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
97
        frame = (uintptr_t) btree_search(&area->sh_info->pagemap,
97
            ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
98
            ALIGN_DOWN(addr, PAGE_SIZE) - area->base, &leaf);
98
        if (!frame) {
99
        if (!frame) {
99
            bool allocate = true;
100
            bool allocate = true;
100
            int i;
101
            int i;
101
           
102
           
102
            /*
103
            /*
Line 111... Line 112...
111
                }
112
                }
112
            }
113
            }
113
            if (allocate) {
114
            if (allocate) {
114
                frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
115
                frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
115
                memsetb(PA2KA(frame), FRAME_SIZE, 0);
116
                memsetb(PA2KA(frame), FRAME_SIZE, 0);
-
 
117
                dirty = true;
116
               
118
               
117
                /*
119
                /*
118
                 * Insert the address of the newly allocated
120
                 * Insert the address of the newly allocated
119
                 * frame to the pagemap.
121
                 * frame to the pagemap.
120
                 */
122
                 */
Line 141... Line 143...
141
         *   do not forget to distinguish between
143
         *   do not forget to distinguish between
142
         *   the different causes
144
         *   the different causes
143
         */
145
         */
144
        frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
146
        frame = (uintptr_t) frame_alloc(ONE_FRAME, 0);
145
        memsetb(PA2KA(frame), FRAME_SIZE, 0);
147
        memsetb(PA2KA(frame), FRAME_SIZE, 0);
-
 
148
        dirty = true;
146
    }
149
    }
147
   
150
   
148
    /*
151
    /*
149
     * Map 'page' to 'frame'.
152
     * Map 'page' to 'frame'.
150
     * Note that TLB shootdown is not attempted as only new information is
153
     * Note that TLB shootdown is not attempted as only new information is
Line 152... Line 155...
152
     */
155
     */
153
    page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
156
    page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
154
    if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
157
    if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
155
        panic("Could not insert used space.\n");
158
        panic("Could not insert used space.\n");
156
       
159
       
-
 
160
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
161
    if (dirty && PAGE_COLOR(PA2KA(frame)) != PAGE_COLOR(addr)) {
-
 
162
        /*
-
 
163
         * By writing to the frame using kernel virtual address,
-
 
164
         * we have created an illegal virtual alias. We now have to
-
 
165
         * invalidate cachelines belonging to addr on all processors
-
 
166
         * so that they will be reloaded with the new content on next
-
 
167
         * read.
-
 
168
         */
-
 
169
        dcache_flush_frame(addr, frame);
-
 
170
        dcache_shootdown_start(DCACHE_INVL_FRAME, PAGE_COLOR(addr), frame);
-
 
171
        dcache_shootdown_finalize();
-
 
172
    }
-
 
173
#endif
-
 
174
 
157
    return AS_PF_OK;
175
    return AS_PF_OK;
158
}
176
}
159
 
177
 
160
/** Free a frame that is backed by the anonymous memory backend.
178
/** Free a frame that is backed by the anonymous memory backend.
161
 *
179
 *
Line 166... Line 184...
166
 * @param frame Frame to be released.
184
 * @param frame Frame to be released.
167
 */
185
 */
168
void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
186
void anon_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame)
169
{
187
{
170
    frame_free(frame);
188
    frame_free(frame);
171
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
172
    dcache_flush_frame(page, frame);
-
 
173
#endif
-
 
174
}
189
}
175
 
190
 
176
/** Share the anonymous address space area.
191
/** Share the anonymous address space area.
177
 *
192
 *
178
 * Sharing of anonymous area is done by duplicating its entire mapping
193
 * Sharing of anonymous area is done by duplicating its entire mapping
Line 215... Line 230...
215
                page_table_unlock(area->as, false);
230
                page_table_unlock(area->as, false);
216
 
231
 
217
                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
232
                pfn_t pfn = ADDR2PFN(PTE_GET_FRAME(pte));
218
                frame_reference_add(pfn);
233
                frame_reference_add(pfn);
219
            }
234
            }
220
               
235
 
221
        }
236
        }
222
    }
237
    }
223
    mutex_unlock(&area->sh_info->lock);
238
    mutex_unlock(&area->sh_info->lock);
224
}
239
}
225
 
240