diff --git a/hypervisor/arch/x86/guest/virq.c b/hypervisor/arch/x86/guest/virq.c index dfc6a88ac..8c0aa6a1d 100644 --- a/hypervisor/arch/x86/guest/virq.c +++ b/hypervisor/arch/x86/guest/virq.c @@ -222,9 +222,15 @@ int32_t vcpu_queue_exception(struct acrn_vcpu *vcpu, uint32_t vector_arg, uint32 return ret; } -static void vcpu_inject_exception(struct acrn_vcpu *vcpu, uint32_t vector) +/* + * @pre vcpu->arch.exception_info.exception < 0x20U + */ +static bool vcpu_inject_exception(struct acrn_vcpu *vcpu) { + bool injected = false; + if (bitmap_test_and_clear_lock(ACRN_REQUEST_EXCP, &vcpu->arch.pending_req)) { + uint32_t vector = vcpu->arch.exception_info.exception; if ((exception_type[vector] & EXCEPTION_ERROR_CODE_VALID) != 0U) { exec_vmwrite32(VMX_ENTRY_EXCEPTION_ERROR_CODE, @@ -246,31 +252,8 @@ static void vcpu_inject_exception(struct acrn_vcpu *vcpu, uint32_t vector) if (get_exception_type(vector) == EXCEPTION_FAULT) { vcpu_set_rflags(vcpu, vcpu_get_rflags(vcpu) | HV_ARCH_VCPU_RFLAGS_RF); } - } -} -static bool vcpu_inject_hi_exception(struct acrn_vcpu *vcpu) -{ - bool injected = false; - uint32_t vector = vcpu->arch.exception_info.exception; - - if ((vector == IDT_MC) || (vector == IDT_BP) || (vector == IDT_DB)) { - vcpu_inject_exception(vcpu, vector); - injected = true; - } - - return injected; -} - -static bool vcpu_inject_lo_exception(struct acrn_vcpu *vcpu) -{ - uint32_t vector = vcpu->arch.exception_info.exception; - bool injected = false; - - /* high priority exception already be injected */ - if (vector <= NR_MAX_VECTOR) { - vcpu_inject_exception(vcpu, vector); - injected = true; + injected = true; } return injected; @@ -360,7 +343,7 @@ int32_t external_interrupt_vmexit_handler(struct acrn_vcpu *vcpu) return ret; } -static inline bool acrn_inject_pending_intr(struct acrn_vcpu *vcpu, +static inline void acrn_inject_pending_intr(struct acrn_vcpu *vcpu, uint64_t *pending_req_bits, bool injected); int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) @@ -396,9 +379,10 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) vcpu_set_vmcs_eoi_exit(vcpu); } - /* SDM Vol 3 - table 6-2, inject high priority exception before - * maskable hardware interrupt */ - injected = vcpu_inject_hi_exception(vcpu); + /* + * Inject pending exception prior pending interrupt to complete the previous instruction. + */ + injected = vcpu_inject_exception(vcpu); if (!injected) { /* inject NMI before maskable hardware interrupt */ if (bitmap_test_and_clear_lock(ACRN_REQUEST_NMI, pending_req_bits)) { @@ -422,11 +406,7 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) } } - if (!acrn_inject_pending_intr(vcpu, pending_req_bits, injected)) { - /* if there is no eligible vector before this point */ - /* SDM Vol3 table 6-2, inject lowpri exception */ - (void)vcpu_inject_lo_exception(vcpu); - } + acrn_inject_pending_intr(vcpu, pending_req_bits, injected); /* * If "virtual-interrupt delivered" is enabled, CPU will evaluate @@ -455,11 +435,7 @@ int32_t acrn_handle_pending_request(struct acrn_vcpu *vcpu) return ret; } -/* - * @retval true 1 when INT is injected to guest. - * @retval false when there is no eligible pending vector. - */ -static inline bool acrn_inject_pending_intr(struct acrn_vcpu *vcpu, +static inline void acrn_inject_pending_intr(struct acrn_vcpu *vcpu, uint64_t *pending_req_bits, bool injected) { bool ret = injected; @@ -474,10 +450,8 @@ static inline bool acrn_inject_pending_intr(struct acrn_vcpu *vcpu, } if (bitmap_test_and_clear_lock(ACRN_REQUEST_EVENT, pending_req_bits)) { - ret = vlapic_inject_intr(vcpu_vlapic(vcpu), guest_irq_enabled, ret); + vlapic_inject_intr(vcpu_vlapic(vcpu), guest_irq_enabled, ret); } - - return ret; } /* diff --git a/hypervisor/arch/x86/guest/vlapic.c b/hypervisor/arch/x86/guest/vlapic.c index 9ee598d15..510dda8d7 100644 --- a/hypervisor/arch/x86/guest/vlapic.c +++ b/hypervisor/arch/x86/guest/vlapic.c @@ -1736,11 +1736,10 @@ static void ptapic_accept_intr(struct acrn_vlapic *vlapic, uint32_t vector, __un vlapic2vcpu(vlapic)->vm->vm_id, vlapic2vcpu(vlapic)->vcpu_id, vector); } -static bool ptapic_inject_intr(struct acrn_vlapic *vlapic, +static void ptapic_inject_intr(struct acrn_vlapic *vlapic, __unused bool guest_irq_enabled, __unused bool injected) { pr_err("Invalid op %s, VM%u, vCPU%u", __func__, vlapic2vcpu(vlapic)->vm->vm_id, vlapic2vcpu(vlapic)->vcpu_id); - return injected; } static bool ptapic_has_pending_delivery_intr(__unused struct acrn_vcpu *vcpu) @@ -2246,23 +2245,20 @@ vlapic_apicv_get_apic_page_addr(struct acrn_vlapic *vlapic) return hva2hpa(&(vlapic->apic_page)); } -static bool apicv_basic_inject_intr(struct acrn_vlapic *vlapic, +static void apicv_basic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected) { uint32_t vector = 0U; - bool ret = injected; + if (guest_irq_enabled && (!injected)) { vlapic_update_ppr(vlapic); if (vlapic_find_deliverable_intr(vlapic, &vector)) { exec_vmwrite32(VMX_ENTRY_INT_INFO_FIELD, VMX_INT_INFO_VALID | vector); vlapic_get_deliverable_intr(vlapic, vector); - ret = true; } } vlapic_update_tpr_threshold(vlapic); - - return ret; } /* @@ -2332,8 +2328,8 @@ static void vlapic_apicv_inject_pir(struct acrn_vlapic *vlapic) } } -static bool apicv_advanced_inject_intr(struct acrn_vlapic *vlapic, - __unused bool guest_irq_enabled, bool injected) +static void apicv_advanced_inject_intr(struct acrn_vlapic *vlapic, + __unused bool guest_irq_enabled, __unused bool injected) { /* * From SDM Vol3 26.3.2.5: @@ -2349,13 +2345,11 @@ static bool apicv_advanced_inject_intr(struct acrn_vlapic *vlapic, * needed. And then try to handle vmcs event injection. */ vlapic_apicv_inject_pir(vlapic); - - return injected; } -bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected) +void vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected) { - return vlapic->ops->inject_intr(vlapic, guest_irq_enabled, injected); + vlapic->ops->inject_intr(vlapic, guest_irq_enabled, injected); } static bool apicv_basic_has_pending_delivery_intr(struct acrn_vcpu *vcpu) diff --git a/hypervisor/include/arch/x86/guest/vlapic.h b/hypervisor/include/arch/x86/guest/vlapic.h index 6df549068..4a6c6433b 100644 --- a/hypervisor/include/arch/x86/guest/vlapic.h +++ b/hypervisor/include/arch/x86/guest/vlapic.h @@ -89,7 +89,7 @@ struct acrn_vlapic { struct acrn_vcpu; struct acrn_apicv_ops { void (*accept_intr)(struct acrn_vlapic *vlapic, uint32_t vector, bool level); - bool (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected); + void (*inject_intr)(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected); bool (*has_pending_delivery_intr)(struct acrn_vcpu *vcpu); bool (*has_pending_intr)(struct acrn_vcpu *vcpu); bool (*apic_read_access_may_valid)(uint32_t offset); @@ -109,7 +109,7 @@ void vlapic_set_apicv_ops(void); * @{ */ -bool vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected); +void vlapic_inject_intr(struct acrn_vlapic *vlapic, bool guest_irq_enabled, bool injected); bool vlapic_has_pending_delivery_intr(struct acrn_vcpu *vcpu); bool vlapic_has_pending_intr(struct acrn_vcpu *vcpu);