From 7f2b9a1c7d8bb93613bc099c9d42708da0955b19 Mon Sep 17 00:00:00 2001 From: Yu Wang Date: Wed, 10 Oct 2018 05:49:31 +0000 Subject: [PATCH] hv: virq: update apicv irr/rvi before handle vmcs event injection From SDM Vol3 26.3.2.5: Once the virtual interrupt is recognized, it will be delivered in VMX non-root operation immediately after VM entry(including any specified event injection) completes. So the hardware can handle vmcs event injection and evaluation/delivery of apicv virtual interrupts in one time vm-entry. This patch move the apicv irr/rvi sync before handle vmcs events injection. The old code cause the apicv virtual interrupt evaluation and delivery be handled until next vm-exit if met pending exceptions. Tracked-On: #1443 Signed-off-by: Yu Wang Acked-by: Eddie Dong --- hypervisor/arch/x86/virq.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/hypervisor/arch/x86/virq.c b/hypervisor/arch/x86/virq.c index 614b4de51..2f10adaf1 100644 --- a/hypervisor/arch/x86/virq.c +++ b/hypervisor/arch/x86/virq.c @@ -430,6 +430,25 @@ int acrn_handle_pending_request(struct vcpu *vcpu) goto INTR_WIN; } + /* + * From SDM Vol3 26.3.2.5: + * Once the virtual interrupt is recognized, it will be delivered + * in VMX non-root operation immediately after VM entry(including + * any specified event injection) completes. + * + * So the hardware can handle vmcs event injection and + * evaluation/delivery of apicv virtual interrupts in one time + * vm-entry. + * + * Here to sync the pending interrupts to irr and update rvi if + * needed. And then try to handle vmcs event injection. + */ + if (is_apicv_intr_delivery_supported() && + bitmap_test_and_clear_lock(ACRN_REQUEST_EVENT, + pending_req_bits)) { + vlapic_apicv_inject_pir(vlapic); + } + /* SDM Vol 3 - table 6-2, inject high priority exception before * maskable hardware interrupt */ if (vcpu_inject_hi_exception(vcpu) != 0) { @@ -458,19 +477,6 @@ int acrn_handle_pending_request(struct vcpu *vcpu) goto INTR_WIN; } - /* - * If the "virtual-interrupt delivery" is enabled, - * sync the pending interrupts to irr and update rvi if needed. - * Then CPU will start evaluate the pending virtual interrupts - * in the later vm-entry. - * - */ - if (is_apicv_intr_delivery_supported() && - bitmap_test_and_clear_lock(ACRN_REQUEST_EVENT, - pending_req_bits)) { - vlapic_apicv_inject_pir(vlapic); - } - /* Guest interruptable or not */ if (is_guest_irq_enabled(vcpu)) { /* Inject external interrupt first */