* this routine is called if the page table page is not * mapped correctly. */
| 1160 | * mapped correctly. |
| 1161 | */ |
| 1162 | static vm_page_t |
| 1163 | _pmap_allocpte(pmap_t pmap, unsigned ptepindex, u_int flags) |
| 1164 | { |
| 1165 | vm_offset_t pageva; |
| 1166 | vm_page_t m; |
| 1167 | int req_class; |
| 1168 | |
| 1169 | /* |
| 1170 | * Find or fabricate a new pagetable page |
| 1171 | */ |
| 1172 | req_class = VM_ALLOC_NORMAL; |
| 1173 | if ((m = pmap_alloc_direct_page(ptepindex, req_class)) == NULL) { |
| 1174 | if ((flags & PMAP_ENTER_NOSLEEP) == 0) { |
| 1175 | PMAP_UNLOCK(pmap); |
| 1176 | rw_wunlock(&pvh_global_lock); |
| 1177 | pmap_grow_direct_page(req_class); |
| 1178 | rw_wlock(&pvh_global_lock); |
| 1179 | PMAP_LOCK(pmap); |
| 1180 | } |
| 1181 | |
| 1182 | /* |
| 1183 | * Indicate the need to retry. While waiting, the page |
| 1184 | * table page may have been allocated. |
| 1185 | */ |
| 1186 | return (NULL); |
| 1187 | } |
| 1188 | |
| 1189 | /* |
| 1190 | * Map the pagetable page into the process address space, if it |
| 1191 | * isn't already there. |
| 1192 | */ |
| 1193 | pageva = MIPS_PHYS_TO_DIRECT(VM_PAGE_TO_PHYS(m)); |
| 1194 | |
| 1195 | #ifdef __mips_n64 |
| 1196 | if (ptepindex >= NUPDE) { |
| 1197 | pmap->pm_segtab[ptepindex - NUPDE] = (pd_entry_t)pageva; |
| 1198 | } else { |
| 1199 | pd_entry_t *pdep, *pde; |
| 1200 | int segindex = ptepindex >> (SEGSHIFT - PDRSHIFT); |
| 1201 | int pdeindex = ptepindex & (NPDEPG - 1); |
| 1202 | vm_page_t pg; |
| 1203 | |
| 1204 | pdep = &pmap->pm_segtab[segindex]; |
| 1205 | if (*pdep == NULL) { |
| 1206 | /* recurse for allocating page dir */ |
| 1207 | if (_pmap_allocpte(pmap, NUPDE + segindex, |
| 1208 | flags) == NULL) { |
| 1209 | /* alloc failed, release current */ |
| 1210 | vm_page_unwire_noq(m); |
| 1211 | vm_page_free_zero(m); |
| 1212 | return (NULL); |
| 1213 | } |
| 1214 | } else { |
| 1215 | pg = PHYS_TO_VM_PAGE(MIPS_DIRECT_TO_PHYS(*pdep)); |
| 1216 | pg->ref_count++; |
| 1217 | } |
| 1218 | /* Next level entry */ |
| 1219 | pde = (pd_entry_t *)*pdep; |
no test coverage detected