acrn-hypervisor/hypervisor/arch/x86/nmi.c

43 lines
1.4 KiB
C

/*
* Copyright (C) 2018 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm/irq.h>
#include <asm/vmx.h>
void handle_nmi(__unused struct intr_excp_ctx *ctx)
{
uint32_t value32;
/*
* There is a window where we may miss the current request in this
* notification period when the work flow is as the following:
*
* CPUx + + CPUr
* | |
* | +--+
* | | | Handle pending req
* | <--+
* +--+ |
* | | Set req flag |
* <--+ |
* +------------------>---+
* | Send NMI | | Handle NMI
* | <--+
* | |
* | |
* | +--> vCPU enter
* | |
* + +
*
* So, here we enable the NMI-window exiting to trigger the next vmexit
* once there is no "virtual-NMI blocking" after vCPU enter into VMX non-root
* mode. Then we can process the pending request on time.
*/
value32 = exec_vmread32(VMX_PROC_VM_EXEC_CONTROLS);
value32 |= VMX_PROCBASED_CTLS_NMI_WINEXIT;
exec_vmwrite32(VMX_PROC_VM_EXEC_CONTROLS, value32);
}