尝试从环0转到环3时非常奇怪的sigquit
我正在努力在没有本机环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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我最终通过为所有内核代码/数据页面设置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 !