page frame inquiry or allocation in backup address space */
| 252 | |
| 253 | /* page frame inquiry or allocation in backup address space */ |
| 254 | static void *_get_page_from_backup(rt_aspace_t backup, rt_base_t offset_in_mobj) |
| 255 | { |
| 256 | void *frame_pa; |
| 257 | char *backup_addr; |
| 258 | rt_varea_t backup_varea; |
| 259 | void *rc = RT_NULL; |
| 260 | |
| 261 | backup_addr = (char *)(offset_in_mobj << MM_PAGE_SHIFT); |
| 262 | backup_varea = rt_aspace_query(backup, backup_addr); |
| 263 | |
| 264 | if (backup_varea) |
| 265 | { |
| 266 | /* synchronize between multiple request by aspace lock of backup */ |
| 267 | WR_LOCK(backup); |
| 268 | |
| 269 | frame_pa = rt_hw_mmu_v2p(backup, backup_addr); |
| 270 | if (frame_pa == ARCH_MAP_FAILED) |
| 271 | { |
| 272 | /* provide the page in backup varea */ |
| 273 | struct rt_aspace_fault_msg msg; |
| 274 | msg.fault_op = MM_FAULT_OP_WRITE; |
| 275 | msg.fault_type = MM_FAULT_TYPE_PAGE_FAULT; |
| 276 | msg.fault_vaddr = backup_addr; |
| 277 | msg.off = offset_in_mobj; |
| 278 | rt_mm_fault_res_init(&msg.response); |
| 279 | |
| 280 | rt_mm_dummy_mapper.on_page_fault(backup_varea, &msg); |
| 281 | if (msg.response.status != MM_FAULT_STATUS_UNRECOVERABLE) |
| 282 | { |
| 283 | _map_page_in_varea(backup, backup_varea, &msg, backup_addr); |
| 284 | if (msg.response.status == MM_FAULT_STATUS_OK_MAPPED) |
| 285 | { |
| 286 | rc = msg.response.vaddr; |
| 287 | } |
| 288 | rt_pages_free(msg.response.vaddr, 0); |
| 289 | } |
| 290 | } |
| 291 | else |
| 292 | { |
| 293 | rc = rt_kmem_p2v(frame_pa); |
| 294 | if (!rc) |
| 295 | RT_ASSERT(0 && "No kernel address of target page frame"); |
| 296 | } |
| 297 | WR_UNLOCK(backup); |
| 298 | } |
| 299 | else |
| 300 | { |
| 301 | /* out of range error */ |
| 302 | LOG_E("(backup_addr=%p): Page request out of range", backup_addr); |
| 303 | } |
| 304 | |
| 305 | return rc; |
| 306 | } |
| 307 | |
| 308 | /* get the backup page in kernel for the address in user space */ |
| 309 | static void _fetch_page_for_varea(struct rt_varea *varea, struct rt_aspace_fault_msg *msg, rt_bool_t need_map) |
no test coverage detected