fix(vkernel): 补 ISR/调度 call 的 rsi/rdi clobber、rep stosb 内存 clobber,修 mm 别名笔误

N8  paging.vp:AllocPage 的 rep stosb 写 4096B 补 CLOBBER_MEMORY,避免优化器
    重排/消除其前后的内存读写
N9  coroutine.vp / sched.vp:_coro_entry/_thread_entry 的 call rax 补
    CLOBBER_RSI/CLOBBER_RDI(RSP 由 sub rsp,8 / add rsp,8 配对抵消,无需声明)
N15 process.vp:mm_mm.malloc/free → mm.malloc/free(该文件只有 import mm.mm as mm)
N16 elf.vp:读 RAX 的 c.Asm 补 CLOBBER_RAX([DIAG] 探针)
N20 elf.vp / idt.vp(12 处):外部 ELF 入口 / ISR handler 的 call 补
    CLOBBER_RSI/CLOBBER_RDI(被调方破坏全部 caller-saved 寄存器)
This commit is contained in:
TermiNexus committed 2026-09-11 17:40:21 +08:00
1 parent c1dd55d606
commit 6a54373c26
6 files changed
+35 -5

No files matched your search

+8 -1
View File
@@ -133,7 +133,11 @@ def load_elf(path: t.CConst | str, do_map: int = 1) -> t.CPtr:
# [DIAG] read_len 实际值 + call 后 RAX 快照:区分"call 返回错"(rl=0 rax=0)
# vs "store 后 RAX 被覆盖"(rl=0 rax=64)
_rax_v2: uint64 = 0
c.Asm(f"""mov {c.AsmOut(_rax_v2, t.ASM_DESCR.OUTPUT_REG)}, rax""", op=[t.ASM_DESCR.CLOBBER_MEMORY])
# 读 RAX 未声明输入:至少须声明 CLOBBER_RAX,让编译器知道本块不保留
# RAX(此前只声明 ~{memory},编译器可假设 RAX 存活 → 读到的值不保证是
# 紧邻 call 的返回值)。N16。(本块为 [DIAG] 探针,问题定位后建议删除。)
c.Asm(f"""mov {c.AsmOut(_rax_v2, t.ASM_DESCR.OUTPUT_REG)}, rax""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX])
_dbrl: t.CArray[t.CChar, 96]
viperlib.snprintf(c.Addr(_dbrl), 96, "[elf] rl=%lu rax=0x%lx\n", read_len, _rax_v2)
serial.puts(c.Addr(_dbrl))
@@ -302,9 +306,12 @@ def run_elf(path: t.CConst | str) -> int:
serial.puts("[elf] load failed\n")
return -1
serial.puts("[elf] jumping to entry...\n")
# 被调方是任意 ELF 入口(外部代码):`call` 破坏全部 caller-saved 寄存器,
# 除 rax/rcx/rdx/r8~r11 外必须声明 rsi/rdi(N20)。
c.Asm(f"""call {c.AsmInp(entry, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
serial.puts("[elf] returned from entry\n")
+12
View File
@@ -325,6 +325,7 @@ def isr33_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(1)
@@ -336,6 +337,7 @@ def isr34_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler2, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(2)
@@ -347,6 +349,7 @@ def isr35_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler3, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(3)
@@ -358,6 +361,7 @@ def isr36_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler4, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(4)
@@ -369,6 +373,7 @@ def isr37_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler5, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(5)
@@ -380,6 +385,7 @@ def isr38_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler6, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(6)
@@ -393,6 +399,7 @@ def isr39_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler7, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(7)
@@ -404,6 +411,7 @@ def isr40_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler8, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(8)
@@ -415,6 +423,7 @@ def isr41_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler9, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(9)
@@ -426,6 +435,7 @@ def isr42_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler10, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(10)
@@ -437,6 +447,7 @@ def isr43_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler11, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(11)
@@ -447,6 +458,7 @@ def isr44_handler() -> t.CExport | t.CVoid:
c.Asm(f"""call {c.AsmInp(handler, t.ASM_DESCR.REG_ANY)}""",
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
pic.eoi(12)
+4 -1
View File
@@ -65,11 +65,14 @@ def AllocPage() -> t.CPtr:
if pt_pool_used >= uint64(PT_POOL_PAGES): return None
page: t.CPtr = t.CVoid(pt_pool_start + pt_pool_used * uint64(4096), t.CPtr)
pt_pool_used = pt_pool_used + uint64(1)
# rep stosb 向 [rdi] 写 4096 字节:必须声明 CLOBBER_MEMORY,否则优化器
# 无法得知本块改写了内存,可能把其前后的内存读写重排/消除(N8)。
c.Asm(f"""mov al, 0
mov ecx, 4096
mov rdi, {c.AsmInp(page, t.ASM_DESCR.REG_ANY)}
rep stosb""",
op = [t.ASM_DESCR.CLOBBER_AL, t.ASM_DESCR.CLOBBER_ECX, t.ASM_DESCR.CLOBBER_RDI])
op = [t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_AL,
t.ASM_DESCR.CLOBBER_ECX, t.ASM_DESCR.CLOBBER_RDI])
AllocatedPages = AllocatedPages + uint64(1)
return page
+4
View File
@@ -197,8 +197,12 @@ def _coro_entry():
mov dword ptr [rax + rcx + 40], 3
mov dword ptr [rax + rcx + 56], eax
add rsp, 8""",
# `call rax` 破坏全部 caller-saved 寄存器(x64 SysV):除 RAX/RCX/RDX/
# R8-R11 外,RSI 与 RDI 也必须声明,否则编译器可能假设其值存活(N9)。
# RSP 由 `sub rsp,8` / `add rsp,8` 配对抵消,净变化为 0,无需声明。
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
Coroutine._yield()
+3 -3
View File
@@ -190,7 +190,7 @@ class ProcessManager:
for j in range(PROC_MAX_DIRS):
p.dir_used[j] = 0
p.dir_table[j] = t.CVoid(0, t.CPtr)
ks: t.CPtr = mm_mm.malloc(KERN_STACK_SIZE)
ks: t.CPtr = mm.malloc(KERN_STACK_SIZE)
# [DIAG] 定位跨模块 malloc 返回值(mm 成功但调用方收到 None)
_dbg_ks: t.CArray[t.CChar, 64]
viperlib.snprintf(c.Addr(_dbg_ks), 64, "[proc] ks=0x%lx\n", uint64(ks))
@@ -201,14 +201,14 @@ class ProcessManager:
return None
ks_size: uint64 = KERN_STACK_SIZE
p.kern_stack = uint64(ks) + ks_size
us: t.CPtr = mm_mm.malloc(USER_STACK_SIZE)
us: t.CPtr = mm.malloc(USER_STACK_SIZE)
# [DIAG] 定位 user_stack 收到 None(mm 内部打印成功但此处收 0x0)
_dbg_us: t.CArray[t.CChar, 64]
viperlib.snprintf(c.Addr(_dbg_us), 64, "[proc] us=0x%lx\n", uint64(us))
serial.puts(c.Addr(_dbg_us))
if us is None:
serial.puts("[process] user stack alloc failed\n")
mm_mm.free(ks)
mm.free(ks)
m.count = m.count - 1
return None
us_size: uint64 = USER_STACK_SIZE
+4
View File
@@ -278,8 +278,12 @@ def _thread_entry():
imul rcx, rcx, 56
mov dword ptr [rax + rcx + 40], 3
add rsp, 8""",
# `call rax` 破坏全部 caller-saved 寄存器(x64 SysV):除 RAX/RCX/RDX/
# R8-R11 外,RSI 与 RDI 也必须声明,否则编译器可能假设其值存活(N9)。
# RSP 由 `sub rsp,8` / `add rsp,8` 配对抵消,净变化为 0,无需声明。
op=[t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX,
t.ASM_DESCR.CLOBBER_RCX, t.ASM_DESCR.CLOBBER_RDX,
t.ASM_DESCR.CLOBBER_RSI, t.ASM_DESCR.CLOBBER_RDI,
t.ASM_DESCR.CLOBBER_R8, t.ASM_DESCR.CLOBBER_R9,
t.ASM_DESCR.CLOBBER_R10, t.ASM_DESCR.CLOBBER_R11])
Scheduler._yield()