Subversion Repositories HelenOS-historic

Rev

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

Rev 1270 Rev 1288
Line 66... Line 66...
66
 *
66
 *
67
 * Try to find PTE for faulting address.
67
 * Try to find PTE for faulting address.
68
 * The AS->lock must be held on entry to this function.
68
 * The AS->lock must be held on entry to this function.
69
 *
69
 *
70
 * @param badvaddr Faulting virtual address.
70
 * @param badvaddr Faulting virtual address.
-
 
71
 * @param istate Pointer to interrupted state.
-
 
72
 * @param pfrc Pointer to variable where as_page_fault() return code will be stored.
71
 * @return         PTE on success, NULL otherwise.
73
 * @return         PTE on success, NULL otherwise.
72
 *
74
 *
73
 */
75
 */
74
static pte_t *find_mapping_and_check(__address badvaddr)
76
static pte_t *find_mapping_and_check(__address badvaddr, istate_t *istate, int *pfcr)
75
{
77
{
76
    /*
78
    /*
77
     * Check if the mapping exists in page tables.
79
     * Check if the mapping exists in page tables.
78
     */
80
     */
79
    pte_t *pte = page_mapping_find(AS, badvaddr);
81
    pte_t *pte = page_mapping_find(AS, badvaddr);
Line 82... Line 84...
82
         * Mapping found in page tables.
84
         * Mapping found in page tables.
83
         * Immediately succeed.
85
         * Immediately succeed.
84
         */
86
         */
85
        return pte;
87
        return pte;
86
    } else {
88
    } else {
-
 
89
        int rc;
-
 
90
   
87
        /*
91
        /*
88
         * Mapping not found in page tables.
92
         * Mapping not found in page tables.
89
         * Resort to higher-level page fault handler.
93
         * Resort to higher-level page fault handler.
90
         */
94
         */
91
        page_table_unlock(AS, true);
95
        page_table_unlock(AS, true);
92
        if (as_page_fault(badvaddr)) {
96
        switch (rc = as_page_fault(badvaddr, istate)) {
-
 
97
        case AS_PF_OK:
93
            /*
98
            /*
94
             * The higher-level page fault handler succeeded,
99
             * The higher-level page fault handler succeeded,
95
             * The mapping ought to be in place.
100
             * The mapping ought to be in place.
96
             */
101
             */
97
            page_table_lock(AS, true);
102
            page_table_lock(AS, true);
98
            pte = page_mapping_find(AS, badvaddr);
103
            pte = page_mapping_find(AS, badvaddr);
99
            ASSERT((pte) && (pte->p));
104
            ASSERT((pte) && (pte->p));
100
            return pte;
105
            return pte;
-
 
106
            break;
-
 
107
        case AS_PF_DEFER:
-
 
108
            page_table_lock(AS, true);
-
 
109
            *pfcr = rc;
-
 
110
            return NULL;
101
        } else {
111
            break;
-
 
112
        case AS_PF_FAULT:
102
            page_table_lock(AS, true);
113
            page_table_lock(AS, true);
103
            printf("Page fault.\n");
114
            printf("Page fault.\n");
-
 
115
            *pfcr = rc;
104
            return NULL;
116
            return NULL;
-
 
117
            break;
-
 
118
        default:
-
 
119
            panic("unexpected rc (%d)\n", rc);
105
        }
120
            break;
106
       
121
        }  
107
    }
122
    }
108
}
123
}
109
 
124
 
110
 
125
 
111
static void pht_refill_fail(__address badvaddr, istate_t *istate)
126
static void pht_refill_fail(__address badvaddr, istate_t *istate)
Line 137... Line 152...
137
    __u32 page;
152
    __u32 page;
138
    __u32 api;
153
    __u32 api;
139
    __u32 vsid;
154
    __u32 vsid;
140
    __u32 hash;
155
    __u32 hash;
141
    __u32 i;
156
    __u32 i;
-
 
157
    int pfcr;
142
   
158
   
143
    if (data) {
159
    if (data) {
144
        asm volatile (
160
        asm volatile (
145
            "mfdar %0\n"
161
            "mfdar %0\n"
146
            : "=r" (badvaddr)
162
            : "=r" (badvaddr)
Line 152... Line 168...
152
    asid = AS->asid;
168
    asid = AS->asid;
153
    spinlock_unlock(&AS->lock);
169
    spinlock_unlock(&AS->lock);
154
   
170
   
155
    page_table_lock(AS, true);
171
    page_table_lock(AS, true);
156
   
172
   
157
    pte = find_mapping_and_check(badvaddr);
173
    pte = find_mapping_and_check(badvaddr, istate, &pfcr);
158
    if (!pte)
174
    if (!pte) {
-
 
175
        switch (pfcr) {
-
 
176
        case AS_PF_FAULT:
159
        goto fail;
177
            goto fail;
-
 
178
            break;
-
 
179
        case AS_PF_DEFER:
-
 
180
            /*
-
 
181
             * The page fault came during copy_from_uspace()
-
 
182
             * or copy_to_uspace().
-
 
183
             */
-
 
184
            page_table_unlock(AS, true);
-
 
185
            return;
-
 
186
        default:
-
 
187
            panic("Unexpected pfrc (%d)\n", pfcr);
-
 
188
            break;
-
 
189
        }
-
 
190
    }
160
 
191
 
161
    /* Record access to PTE */
192
    /* Record access to PTE */
162
    pte->a = 1;
193
    pte->a = 1;
163
   
194
   
164
    page = (badvaddr >> 12) & 0xffff;
195
    page = (badvaddr >> 12) & 0xffff;