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:
1 parent
1ccacf8204
commit
624554df01
2 files changed
+8
-2
No files matched your search
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user