Reputation: 531
I am writing a debugger based on Intel VT.
As the iret instruction's performance in vmx-guest is changed while NMI-Exiting=1. So I should handle NMI in the vmx-host myself,otherwise,guest will have nmi reentrant bugs.
I checked the Intel manual :
While an NMI interrupt handler is executing, the processor disables additional calls to the NMI handler until the next IRET instruction is executed. This blocking of subse-quent NMIs prevents stacking up calls to the NMI handler.
So I am trying to simulate a iret in the vmx-host myself. the CPL remains ring0 and keep stack and code segment no change.
I write a sample code below,it was after vmx-exit caused by NMI:
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":);
Anyone can show some guides?
Upvotes: 3
Views: 1429
Reputation: 1562
Looks like your code is missing pushing SS and RSP. Here is my code for both i386 and x86_64: 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__) */
}
Upvotes: 1