diff --git a/VKernel/Kernel/intr/isr.s b/VKernel/Kernel/intr/isr.s index c4b5420..8284d3d 100644 --- a/VKernel/Kernel/intr/isr.s +++ b/VKernel/Kernel/intr/isr.s @@ -189,10 +189,20 @@ isr\num\()_ret_user: mov al, 0x4E # 'N' marker = NT was set (now cleared) out dx, al 1: - cmp r9, 0x1B - jne 8f + # 用户态 CS 必须同时接受两个值(本内核两条入口路径给的不一样): + # 0x1B — drop_to_user_mode 首次 iretq 进用户态时压的 CS(= USER_CODE_SEG 0x18 | RPL3) + # 0x2B — syscall 返回走 sysretq:STAR[63:48]=0x1B ⇒ 硬件算 CS=+16=0x2B、SS=+8=0x23 + # 原来只认 0x1B:app 只要发过一次 syscall,之后任何用户态**中断/异常**(例如定时器抢占) + # 都被判“坏 CS/SS”,打印 "B 2B 23" 后 cli;hlt 死机 —— 既假死,又掩盖真正的用户态异常现场。 + # (另注:0x2B 指向 GDT 第 5 项,见 gdt.vp —— 那里目前放的是 TSS,属于 GDT/STAR 布局的 + # 隐患,QEMU 不校验 SYSRET 的目标描述符类型才没暴露;要根治需把用户代码段挪到第 5 项。) cmp r11, 0x23 jne 8f + cmp r9, 0x1B + je 6f + cmp r9, 0x2B + jne 8f +6: push r11 # SS push rax # RSP push r10 # RFLAGS