Linux内核vmlaunch测试代码:VM退出后执行哪条指令?incq作用是什么?
关于Linux内核vmlaunch测试代码的疑问解答
问题回顾
这是Linux内核中vmlaunch的测试代码。我的理解是,lea 1f(%%rip), %%rax; 将标签1的地址存入%rax寄存器。随后vmwrite %%rax, %[host_rip];会把%rax的值写入VMCS中的host rip字段。接下来执行vmlaunch进入VM。想咨询:
- VM退出后会执行哪条指令?若
%rip指向待执行的下一条指令,那么接下来应执行incq (%%rsp);还是1: pop %%rax;? - 这段代码中的
incq (%%rsp);作用是什么?
代码片段
__asm__ __volatile__("push %%rbp;" "push %%rcx;" "push %%rdx;" "push %%rsi;" "push %%rdi;" "push $0;" "vmwrite %%rsp, %[host_rsp];" "lea 1f(%%rip), %%rax;" "vmwrite %%rax, %[host_rip];" "vmlaunch;" "incq (%%rsp);" "1: pop %%rax;" "pop %%rdi;" "pop %%rsi;" "pop %%rdx;" "pop %%rcx;" "pop %%rbp;" : [ret]"=&a"(ret) : [host_rsp]"r"((uint64_t)HOST_RSP), [host_rip]"r"((uint64_t)HOST_RIP) : "memory", "cc", "rbx", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15");
解答
1. VM退出后执行的指令
VM退出后直接执行1: pop %%rax;,不会走到incq (%%rsp);。
原因是你已经通过vmwrite把标签1的地址写入了VMCS的host_rip字段。当VM因任何原因退出时,CPU会自动将VMCS中保存的host_rip加载到%rip寄存器,所以会直接跳转到标签1处执行pop %%rax。
只有当vmlaunch本身执行失败(比如VMCS配置有误,根本没成功进入VM)时,CPU才会继续执行vmlaunch的下一条指令,也就是incq (%%rsp);。
2. incq (%%rsp);的作用
这条指令是用来区分vmlaunch的两种结果:
- 代码开头
push $0把0压入栈顶,正常VM退出后执行pop %%rax,会把这个0弹到%rax,最终作为返回值ret返回给上层,标识“成功进入VM后退出”。 - 如果
vmlaunch执行失败,CPU走到incq (%%rsp);,会把栈顶的0改成1,之后执行pop %%rax时,%rax拿到的就是1,上层通过这个返回值就能知道vmlaunch根本没成功启动VM。
内容的提问来源于stack exchange,提问作者Zhongshu
相关产品推荐
相关产品推荐

