hellolwq
hellolwq

Reputation: 531

how to simulate a iret on linux x86_64

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

Answers (1)

Eric Stdlib
Eric Stdlib

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

Related Questions