fix(kernel): _set_page_writable 支持 2MB 大页(PD 条目直接置 W)

pml4 页(0xf801000)若经 2MB 大页映射,原实现遇 PS=1 直接 return 导致页表页仍只读,写 pml4.entries 持续 #PF。大页的 W 位在 PD 条目自身,直接置位即可。
This commit is contained in:
TermiNexus committed 2026-08-29 17:39:25 +08:00
1 parent a92073851e
commit 4f729b20a3
1 file changed
+5 -1
+5 -1
View File
@@ -205,7 +205,11 @@ def _set_page_writable(phys_addr: t.CUInt64T):
pd_s: _p | t.CPtr = t.CType(pdp_s.entries[pdp_idx] & ~t.CUInt64T(0xFFF), _p, t.CPtr)
pd_idx: t.CUInt64T = (va >> 21) & 0x1FF
if not (pd_s.entries[pd_idx] & PTE_PRESENT): return
if pd_s.entries[pd_idx] & PTE_PS: return
if pd_s.entries[pd_idx] & PTE_PS:
# 2MB 大页:W 位在 PD 条目自身(无下层 PT),直接置位
pd_s.entries[pd_idx] = pd_s.entries[pd_idx] | t.CUInt64T(PTE_WRITABLE)
c.Asm(f"invlpg [{c.AsmInp(va, t.ASM_DESCR.REG_ANY)}]")
return
pt_s: _p | t.CPtr = t.CType(pd_s.entries[pd_idx] & ~t.CUInt64T(0xFFF), _p, t.CPtr)
pt_idx: t.CUInt64T = (va >> 12) & 0x1FF
pt_s.entries[pt_idx] = pt_s.entries[pt_idx] | t.CUInt64T(PTE_WRITABLE)