fix(sched): 通过 rdi 传递用户线程入口参数

用户线程入口的第一个形参在 rdi,但 drop_to_user_mode 这条路径从未设置过 rdi,
thread_create(fn, arg) 的 arg 在用户侧一直是垃圾值。iretq 只恢复
RIP/CS/RFLAGS/RSP/SS,因此在 iretq 前显式 mov rdi 即可。
This commit is contained in:
TermiNexus committed 2026-10-26 22:40:10 +08:00
1 parent 1ccacf8204
commit 624554df01
2 files changed
+8 -2

No files matched your search

+7 -1
View File
@@ -256,7 +256,7 @@ def get_pid(tid: int) -> int:
return p.pid
return -1
def drop_to_user_mode(entry: rawptr, user_rsp: uint64, kern_rsp: uint64):
def drop_to_user_mode(entry: rawptr, user_rsp: uint64, kern_rsp: uint64, arg: rawptr = None):
# NOTE: Do NOT swapgs here. This OS uses reverse GS convention:
# GS_BASE = 0 (kernel & user), KERNEL_GS_BASE = &_per_cpu
# syscall/ISR entry does swapgs to get GS_BASE = &_per_cpu
@@ -270,6 +270,11 @@ def drop_to_user_mode(entry: rawptr, user_rsp: uint64, kern_rsp: uint64):
# the stack pointer becomes garbage, and even the page-fault frame cannot be pushed
# => triple fault with zero output (not even the ISR entry probe can fire).
# Swapgs only when GS_BASE != 0 (idempotent; same idiom as the handler's GS restore).
# 【修复】用户线程入口的第一个形参在 rdi —— 这条路径原来**从没设过 rdi**,于是
# `thread_create(fn, arg)` 的用户参数在用户侧永远是垃圾值。iretq 只恢复
# RIP/CS/RFLAGS/RSP/SS,其余通用寄存器原样保留,所以在这里设 rdi 即可传递。
arg_val: uint64 = 0
if arg is not None: arg_val = uint64(arg)
__asm__(f"""cli
mov rsp, {asminp(kern_rsp, ASM_DESCR.REG_ANY)}
mov ecx, 0xC0000101
@@ -280,6 +285,7 @@ def drop_to_user_mode(entry: rawptr, user_rsp: uint64, kern_rsp: uint64):
jz 1f
swapgs
1:
mov rdi, {asminp(arg_val, ASM_DESCR.REG_ANY)}
mov rdx, {asminp(user_rsp, ASM_DESCR.REG_ANY)}
mov rcx, {asminp(entry, ASM_DESCR.REG_ANY)}
mov r11, 0x202
+1 -1
View File
@@ -438,7 +438,7 @@ def _user_thread_entry(arg: rawptr) -> int:
proc.switch_pid(ctx.pid)
gdt.set_tss_rsp0(ctx.kern_stack)
cpu.set_kernel_rsp0(ctx.kern_stack)
proc.drop_to_user_mode(ctx.entry, ctx.user_stack_entry_rsp, ctx.kern_stack)
proc.drop_to_user_mode(ctx.entry, ctx.user_stack_entry_rsp, ctx.kern_stack, ctx.arg)
return 0
def thread_current() -> int: