From 3c119e124a36f5a98526808ae7596d79963c2874 Mon Sep 17 00:00:00 2001 From: Yonghua Huang Date: Tue, 17 Apr 2018 21:11:54 +0800 Subject: [PATCH] check validity of 'VM-exit Int-Info' before extracting vector 1. exception vector and other information can be extracted from 'VM-Exit Interrupt-Information' field of VMCS only if bit31 (Valid) is set. -Intel SDM 24.9.2, Vol3 2. Rename 'exit-interrupt_info' to 'idt_vectoring_info' in 'struct vcpu_arch', which is consistent with SDM 24.9.3, Vol3 3. 'IDT-vectoring information' in VMCS is 32bit -Intel SDM 24.9.3, Vol3 Update the type of 'idt_vectoring_info' in 'struct vcpu_arch'from 'uint32_t' to 'uint64_t'. Signed-off-by: Yonghua Huang --- hypervisor/arch/x86/interrupt.c | 40 ++++++++++++------------ hypervisor/arch/x86/vmexit.c | 2 +- hypervisor/include/arch/x86/guest/vcpu.h | 2 +- hypervisor/include/arch/x86/vmx.h | 1 + 4 files changed, 23 insertions(+), 22 deletions(-) diff --git a/hypervisor/arch/x86/interrupt.c b/hypervisor/arch/x86/interrupt.c index f19db3880..989e798ab 100644 --- a/hypervisor/arch/x86/interrupt.c +++ b/hypervisor/arch/x86/interrupt.c @@ -309,9 +309,9 @@ int acrn_do_intr_process(struct vcpu *vcpu) /* handling pending vector injection: * there are many reason inject failed, we need re-inject again */ - if (vcpu->arch_vcpu.exit_interrupt_info & VMX_INT_INFO_VALID) { + if (vcpu->arch_vcpu.idt_vectoring_info & VMX_INT_INFO_VALID) { exec_vmwrite(VMX_ENTRY_INT_INFO_FIELD, - vcpu->arch_vcpu.exit_interrupt_info); + vcpu->arch_vcpu.idt_vectoring_info); goto INTR_WIN; } @@ -419,8 +419,8 @@ void cancel_event_injection(struct vcpu *vcpu) int exception_vmexit_handler(struct vcpu *vcpu) { - uint32_t intinfo, int_err_code; - uint32_t exception_vector; + uint32_t intinfo, int_err_code = 0; + int32_t exception_vector = -1; uint32_t cpl; int status = 0; @@ -436,24 +436,24 @@ int exception_vmexit_handler(struct vcpu *vcpu) /* Obtain VM-Exit information field pg 2912 */ intinfo = exec_vmread(VMX_EXIT_INT_INFO); - exception_vector = intinfo & 0xFF; - /* Check if exception caused by the guest is a HW exception. If the - * exit occurred due to a HW exception obtain the error code to be - * conveyed to get via the stack - */ - if (intinfo & VMX_INT_INFO_ERR_CODE_VALID) { - int_err_code = exec_vmread(VMX_EXIT_INT_EC); + if (intinfo & VMX_INT_INFO_VALID) { + exception_vector = intinfo & 0xFF; + /* Check if exception caused by the guest is a HW exception. + * If the exit occurred due to a HW exception obtain the + * error code to be conveyed to get via the stack + */ + if (intinfo & VMX_INT_INFO_ERR_CODE_VALID) { + int_err_code = exec_vmread(VMX_EXIT_INT_EC); - /* get current privilege level and fault address */ - cpl = exec_vmread(VMX_GUEST_CS_ATTR); - cpl = (cpl >> 5) & 3; + /* get current privilege level and fault address */ + cpl = exec_vmread(VMX_GUEST_CS_ATTR); + cpl = (cpl >> 5) & 3; - if (cpl < 3) - int_err_code &= ~4; - else - int_err_code |= 4; - } else { - int_err_code = 0; + if (cpl < 3) + int_err_code &= ~4; + else + int_err_code |= 4; + } } /* Handle all other exceptions */ diff --git a/hypervisor/arch/x86/vmexit.c b/hypervisor/arch/x86/vmexit.c index 89077b339..0349110d1 100644 --- a/hypervisor/arch/x86/vmexit.c +++ b/hypervisor/arch/x86/vmexit.c @@ -162,7 +162,7 @@ struct vm_exit_dispatch *vmexit_handler(struct vcpu *vcpu) uint16_t basic_exit_reason; /* Obtain interrupt info */ - vcpu->arch_vcpu.exit_interrupt_info = + vcpu->arch_vcpu.idt_vectoring_info = exec_vmread(VMX_IDT_VEC_INFO_FIELD); /* Calculate basic exit reason (low 16-bits) */ diff --git a/hypervisor/include/arch/x86/guest/vcpu.h b/hypervisor/include/arch/x86/guest/vcpu.h index c8cc1ab8e..5f6423aac 100644 --- a/hypervisor/include/arch/x86/guest/vcpu.h +++ b/hypervisor/include/arch/x86/guest/vcpu.h @@ -215,7 +215,7 @@ struct vcpu_arch { /* VCPU context state information */ uint32_t exit_reason; - uint64_t exit_interrupt_info; + uint32_t idt_vectoring_info; uint64_t exit_qualification; uint32_t inst_len; diff --git a/hypervisor/include/arch/x86/vmx.h b/hypervisor/include/arch/x86/vmx.h index 670854565..c05d2dc53 100644 --- a/hypervisor/include/arch/x86/vmx.h +++ b/hypervisor/include/arch/x86/vmx.h @@ -376,6 +376,7 @@ /* VMX entry/exit Interrupt info */ #define VMX_INT_INFO_ERR_CODE_VALID (1<<11) #define VMX_INT_INFO_VALID (1<<31) +#define VMX_INT_TYPE_MASK (0x700) #define VMX_INT_TYPE_EXT_INT 0 #define VMX_INT_TYPE_NMI 2 #define VMX_INT_TYPE_HW_EXP 3