| 176 | } |
| 177 | |
| 178 | auto VirtualMemory::ClonePageDirectory(void* src_page_dir, bool copy_mappings) |
| 179 | -> Expected<void*> { |
| 180 | assert(src_page_dir != nullptr && |
| 181 | "ClonePageDirectory: source page directory is nullptr"); |
| 182 | |
| 183 | // 创建新的页表目录 |
| 184 | auto dst_page_dir = aligned_alloc(cpu_io::virtual_memory::kPageSize, |
| 185 | cpu_io::virtual_memory::kPageSize); |
| 186 | if (dst_page_dir == nullptr) { |
| 187 | return std::unexpected(Error(ErrorCode::kVmAllocationFailed)); |
| 188 | } |
| 189 | |
| 190 | // 清零新页表 |
| 191 | std::memset(dst_page_dir, 0, cpu_io::virtual_memory::kPageSize); |
| 192 | |
| 193 | // 递归复制页表 |
| 194 | auto result = RecursiveClonePageTable( |
| 195 | reinterpret_cast<uint64_t*>(src_page_dir), |
| 196 | reinterpret_cast<uint64_t*>(dst_page_dir), |
| 197 | cpu_io::virtual_memory::kPageTableLevels - 1, copy_mappings); |
| 198 | if (!result.has_value()) { |
| 199 | // 复制失败,清理已分配的页表 |
| 200 | DestroyPageDirectory(dst_page_dir, false); |
| 201 | return std::unexpected(result.error()); |
| 202 | } |
| 203 | |
| 204 | klog::Debug("Cloned page directory from {:#x} to {:#x}", |
| 205 | static_cast<uint64_t>(reinterpret_cast<uintptr_t>(src_page_dir)), |
| 206 | static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dst_page_dir))); |
| 207 | return dst_page_dir; |
| 208 | } |
| 209 | |
| 210 | auto VirtualMemory::RecursiveFreePageTable(uint64_t* table, size_t level, |
| 211 | bool free_pages) -> void { |