我正在编写一个基于 Intel VT 的调试器。
由于当 NMI-Exiting=1 时,iret 指令在 vmx-guest 中的性能发生了变化。
所以我应该自己处理vmx主机中的NMI,否则,guest会出现nmi可重入错误。
我查了英特尔手册:
当 NMI 中断处理程序正在执行时,处理器会禁用
对 NMI 处理程序的额外调用,直到下一个 IRET 指令
被执行。这种对后续 NMI 的阻止可以防止堆叠
调用 NMI 处理程序。
所以我尝试自己在 vmx-host 中模拟 iret。
CPL 保留ring0 并保持堆栈和代码段不变。
我在下面编写了一个示例代码,它是在 NMI 导致 vmx-exit 之后:
asm volatile(
"pushfq \n\t"
"mov %%cs.%%ax \n\t"
"push %%rax\n\t"
"mov $._restart_code,%%rax \n\t"
"push %%rax \n\t"
"iret \n\t"/*manully iret in the host before vmx-entry.*/
"._restart_code:"
"nop":);
任何人都可以展示一些指南吗?
看起来您的代码缺少推动 SS 和 RSP。这是我的 i386 和 x86_64 代码:https://github.com/lxylxy123456/uberxmhf/blob/6b56acef71528b29e503ec66a2d305ba1b0c65f9/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.c#L500 https://github.com/lxylxy123456/uberxmhf/blob/6b56acef71528b29e503ec66a2d305ba1b0c65f9/xmhf/src/xmhf-core/xmhf-runtime/xmhf-smpguest/arch/x86/vmx/smpg-x86vmx.c#L500
void xmhf_smpguest_arch_x86vmx_unblock_nmi(void) {
#ifdef __AMD64__
asm volatile (
"movq %%rsp, %%rsi \r\n"
"xorq %%rax, %%rax \r\n"
"movw %%ss, %%ax \r\n"
"pushq %%rax \r\n"
"pushq %%rsi \r\n"
"pushfq \r\n"
"xorq %%rax, %%rax \r\n"
"movw %%cs, %%ax \r\n"
"pushq %%rax \r\n"
"pushq $1f \r\n"
"iretq \r\n"
"1: nop \r\n"
: // no output
: // no input
: "%rax", "%rsi", "cc", "memory");
#elif defined(__I386__)
asm volatile (
"pushfl \r\n"
"xorl %%eax, %%eax \r\n"
"movw %%cs, %%ax \r\n"
"pushl %%eax \r\n"
"pushl $1f \r\n"
"iretl \r\n"
"1: nop \r\n"
: // no output
: // no input
: "%eax", "cc", "memory");
#else /* !defined(__I386__) && !defined(__AMD64__) */
#error "Unsupported Arch"
#endif /* !defined(__I386__) && !defined(__AMD64__) */
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)