From 1222d6caefaf07241c9ff736e54af43a6092e0ed Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 18:17:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(vkernel/paging):=20clone=5Ffor=5Fprocess=20?= =?UTF-8?q?=E5=A4=84=E7=90=86=201GB=20=E5=A4=A7=E9=A1=B5=EF=BC=88=E5=85=88?= =?UTF-8?q?=E6=8B=86=20PD=20=E5=86=8D=E9=80=90=E5=B1=82=E6=8B=B7=E8=B4=9D?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 源端 PDPTE.PS=1 时没有下层 PD:原实现会把大页内存内容当 PD 拷进新页表,再用该垃圾 PD 替换新地址空间的该条目(该区间映射被写坏,后续写入会落到任意物理内存) - 现在先 _split_1gb_to_pd(kernel_pdp, pdp_idx) 拆成常规 PD(语义不变,512 个 2MB 条目仍映射同一物理 1GB),再沿用既有逐层拷贝;PD 层命中 2MB 时按既有 `if PTE_PS: return` 早退 --- VKernel/Kernel/paging/paging.vp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/VKernel/Kernel/paging/paging.vp b/VKernel/Kernel/paging/paging.vp index 631ca14..e9d54e1 100644 --- a/VKernel/Kernel/paging/paging.vp +++ b/VKernel/Kernel/paging/paging.vp @@ -457,6 +457,12 @@ def clone_for_process(isolate_vaddr: uint64) -> uint64: new_pml4_page.entries[pml4_idx] = (uint64(new_pdp_page) & ~uint64(0xFFF)) | (pml4.entries[pml4_idx] & uint64(0xFFF)) pdp_idx: uint64 = (isolate_vaddr >> 30) & 0x1FF if not (kernel_pdp.entries[pdp_idx] & PTE_PRESENT): return uint64(new_pml4_page) + # 1GB 大页(PDPTE.PS=1):源端没有下层 PD。先把它拆成常规 PD(语义不变:512 个 2MB + # 条目仍映射同一物理 1GB),否则下面会把**大页内存内容**当 PD 拷进新页表,再用这个 + # 垃圾 PD 替换新地址空间的该条目(该区间映射被写坏 / 后续写入落到任意物理内存)。 + # 拆完后面沿用既有逐层拷贝逻辑;PD 层命中 2MB 时按既有 `if PTE_PS: return` 早退。 + if kernel_pdp.entries[pdp_idx] & PTE_PS: + if _split_1gb_to_pd(kernel_pdp, pdp_idx) == 0: return uint64(new_pml4_page) kernel_pd: _p* = _p*(kernel_pdp.entries[pdp_idx] & ~uint64(0xFFF)) new_pd_page: _p* = AllocPage() if not new_pd_page: return uint64(new_pml4_page)