• Lai Jiangshan's avatar
    KVM/VMX: Invoke NMI non-IST entry instead of IST entry · a217a659
    Lai Jiangshan authored
    In VMX, the host NMI handler needs to be invoked after NMI VM-Exit.
    Before commit 1a5488ef ("KVM: VMX: Invoke NMI handler via indirect
    call instead of INTn"), this was done by INTn ("int $2"). But INTn
    microcode is relatively expensive, so the commit reworked NMI VM-Exit
    handling to invoke the kernel handler by function call.
    
    But this missed a detail. The NMI entry point for direct invocation is
    fetched from the IDT table and called on the kernel stack.  But on 64-bit
    the NMI entry installed in the IDT expects to be invoked on the IST stack.
    It relies on the "NMI executing" variable on the IST stack to work
    correctly, which is at a fixed position in the IST stack.  When the entry
    point is unexpectedly called on the kernel stack, the RSP-addressed "NMI
    executing" variable is obviously also on the kernel stack and is
    "uninitialized" and can cause the NMI entry code to run in the wrong way.
    
    Provide a non-ist entry point for VMX which shares the C-function with
    the regular NMI entry and invoke the new asm entry point instead.
    
    On 32-bit this just maps to the regular NMI entry point as 32-bit has no
    ISTs and is not affected.
    
    [ tglx: Made it independent for backporting, massaged changelog ]
    
    Fixes: 1a5488ef ("KVM: VMX: Invoke NMI handler via indirect call instead of INTn")
    Signed-off-by: default avatarLai Jiangshan <laijs@linux.alibaba.com>
    Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    Tested-by: default avatarLai Jiangshan <laijs@linux.alibaba.com>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/87r1imi8i1.ffs@nanos.tec.linutronix.de
    a217a659
nmi.c 14.9 KB