On Tue, Apr 27 2021 at 07:09, Lai Jiangshan wrote: > From: Lai Jiangshan <laijs@xxxxxxxxxxxxxxxxx> > > In VMX, the NMI handler needs to be invoked after NMI VM-Exit. > > Before the commit 1a5488ef0dcf6 ("KVM: VMX: Invoke NMI handler via > indirect call instead of INTn"), the work is 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. > And INTn doesn't set the NMI blocked flag required by the linux kernel > NMI entry. So moving away from INTn are very reasonable. > > Yet some details were missed. After the said commit applied, the NMI > entry pointer is fetched from the IDT table and called from the kernel > stack. But the NMI entry pointer installed on the IDT table is > asm_exc_nmi() which expects to be invoked on the IST stack by the ISA. > And it relies on the "NMI executing" variable on the IST stack to work > correctly. When it is unexpectedly called from the kernel stack, the > RSP-located "NMI executing" variable is also on the kernel stack and > is "uninitialized" and can cause the NMI entry to run in the wrong way. > > So we should not used the NMI entry installed on the IDT table. Rather, > we should use the NMI entry allowed to be used on the kernel stack which > is asm_noist_exc_nmi() which is also used for XENPV and early booting. It's not used by XENPV. XENPV only uses the C entry point, but the ASM entry is separate. Thanks, tglx