尝试从环0转到环3时非常奇怪的sigquit

发布于 2025-02-05 16:12:10 字数 1376 浏览 3 评论 0原文

我正在努力在没有本机环3支撑的Unikernel上启用Intel SGX。因此,为了调用用户模式SGX指令,我需要实现环形开关例程。我遵循Jamesm的教程( 10.- 10.- 10.- 10.- 10.-用户模式(JamesMolloy.co.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk.uk ),这是一个32位解决方案),用于起草一个长模式版本:

void switch_to_ring3()
{
    asm volatile("  \
      mov $0x23, %rax; \
      mov %rax, %ds; \
      mov %rax, %es; \
      mov %rsp, %rax; \
      push $0x23; \
      push %rax; \
      pushf; \
      push $0x1B; \
      push $1f; \
      iretq; \
    1: \
      "); 
        return;
}

我确定我已经正确设置了GDT条目,而0x23/0x1b正是用户模式代码/数据描述符的索引代码描述符值为0xAFFB0000FFFF,数据描述符值为0xAFF3000000FFFFF

奇怪的是,iRETQ可以成功执行,并且RIP寄存器可以转到IRETQ的下一个指令,即代码> nop 如果我禁用优化,并且如果启用了优化,则ret。但是,在执行下一条指令时,它将死亡而无需任何输出(我的Unikernel有一个例外处理程序,即使对于未经手的例外,它也会输出某些内容)。我尝试使用GDB进行调试,而GDB表示该计划获得了sigquit。

我检查了寄存器,但没有发现错误,CS是0x1b,SS,DS和ES是0x23,RIP正确地指向iRETQ的下一个指令。

我真的很困惑它会收到sigquit。如果发生了一些例外,则应输出转储消息,或者至少QEMU日志会跟踪一些“ check_exception”消息,但日志为空。一切似乎都可以,正确的段寄存器,正确的RSP/RBP/RIP,内核代码段是通过设置其描述符的符合位的用户访问,并且所有描述符中的高/低基础地址是指向0x0。

整天都被困在这个问题中,但找不到任何解决方案。我希望这里有人可以挽救我的生命T_T

I am working on enabling Intel SGX on a unikernel that does not have a native ring 3 support. Hence in order to invoke the user-mode SGX instruction I need to implement a ring switch routine. I followed the JamesM's tutorial( 10.-User Mode (jamesmolloy.co.uk) , which is a 32-bit solution) to drafted a long-mode version:

void switch_to_ring3()
{
    asm volatile("  \
      mov $0x23, %rax; \
      mov %rax, %ds; \
      mov %rax, %es; \
      mov %rsp, %rax; \
      push $0x23; \
      push %rax; \
      pushf; \
      push $0x1B; \
      push $1f; \
      iretq; \
    1: \
      "); 
        return;
}

I am sure that I have set up GDT entries properly and 0x23/0x1B is exactly the indexes of user-mode code/data descriptors, in which the code descriptor value is 0xaffb000000ffff and the data descriptor value is 0xaff3000000ffff.

What's strange is that the iretq can be executed successfully, and the rip register could go to the next instruction of the iretq, which is a nop if I disabled the optimization and a ret if I enabled the optimization. However, when executing the next instruction, it will die without any output (my unikernel has an exception handler, even if for unhandled exceptions, it will output something). I try to use GDB to debug and GDB said that the program received SIGQUIT.

I checked the registers but find nothing wrong, cs is 0x1b, ss, ds and es are 0x23, and rip points correctly to the next instruction of iretq.

I am really confused about why it receives SIGQUIT. If some exception happened, it should output the dump message, or at least qemu log will track some 'check_exception' message, but the log is empty. Everything seems okay, correct segment registers, correct rsp/rbp/rip, the kernel code segment is user-accessible by setting the conformed bit of its descriptor, and the high/low base address in all descriptors are pointed to 0x0.

Being trapped in this problem for a whole day but cannot find any solution. I hope someone here could save my life T_T

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

摇划花蜜的午后 2025-02-12 16:12:11

我最终通过为所有内核代码/数据页面设置u/s位修复了它。感谢您的所有评论@prl @petercordes!

I finally fixed it by setting U/S bit for all kernel code/data pages. Thanks for all of your comments @prl @PeterCordes !

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文