diff --git a/hypervisor/Makefile b/hypervisor/Makefile index b6d663a29..5efcf4fbb 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -215,6 +215,8 @@ HW_C_SRCS += arch/x86/page.c HW_C_SRCS += arch/x86/notify.c HW_C_SRCS += arch/x86/vtd.c HW_C_SRCS += arch/x86/gdt.c +HW_C_SRCS += arch/x86/nmi.c +HW_C_SRCS += arch/x86/exception.c HW_C_SRCS += arch/x86/irq.c HW_C_SRCS += arch/x86/timer.c HW_C_SRCS += arch/x86/vmx.c diff --git a/hypervisor/arch/x86/exception.c b/hypervisor/arch/x86/exception.c new file mode 100644 index 000000000..9b8151a6f --- /dev/null +++ b/hypervisor/arch/x86/exception.c @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include + +void dispatch_exception(struct intr_excp_ctx *ctx) +{ + uint16_t pcpu_id = get_pcpu_id(); + + /* Dump exception context */ + dump_exception(ctx, pcpu_id); + + /* Halt the CPU */ + cpu_dead(); +} diff --git a/hypervisor/arch/x86/irq.c b/hypervisor/arch/x86/irq.c index f9e79280a..e23361783 100644 --- a/hypervisor/arch/x86/irq.c +++ b/hypervisor/arch/x86/irq.c @@ -212,51 +212,9 @@ void dispatch_interrupt(const struct intr_excp_ctx *ctx) } } -void dispatch_exception(struct intr_excp_ctx *ctx) -{ - uint16_t pcpu_id = get_pcpu_id(); - - /* Dump exception context */ - dump_exception(ctx, pcpu_id); - - /* Halt the CPU */ - cpu_dead(); -} - -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); -} - +/* + * descs[] must have NR_IRQS entries + */ void init_irq_descs_arch(struct irq_desc descs[]) { uint32_t i; diff --git a/hypervisor/arch/x86/nmi.c b/hypervisor/arch/x86/nmi.c new file mode 100644 index 000000000..e75ff1c32 --- /dev/null +++ b/hypervisor/arch/x86/nmi.c @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2018 Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include + +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); +}