fix(vkernel/paging): clone_for_process 处理 1GB 大页(先拆 PD 再逐层拷贝)
- 源端 PDPTE.PS=1 时没有下层 PD:原实现会把大页内存内容当 PD 拷进新页表,再用该垃圾 PD 替换新地址空间的该条目(该区间映射被写坏,后续写入会落到任意物理内存) - 现在先 _split_1gb_to_pd(kernel_pdp, pdp_idx) 拆成常规 PD(语义不变,512 个 2MB 条目仍映射同一物理 1GB),再沿用既有逐层拷贝;PD 层命中 2MB 时按既有 `if PTE_PS: return` 早退
This commit is contained in:
1 parent
07f4dbbb78
commit
1222d6caef
1 file changed
+6
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user