acrn-hypervisor/hypervisor/arch/x86/guest
Shuo A Liu 0397cb7174 hv: Fix the interrupts lost issue with PI support
Currently, not all platforms support posted interrupt processing of both
VT-x and VT-d. On EHL, VT-d doesn't support posted interrupt processing.
So in such scenario, is_pi_capable() in vcpu_handle_pi_notification()
will bypass the PIR pending bits check which might cause a self-NV-IPI
lost.

With commit "bf1ff8c98 (hv: Offload syncing PIR to vIRR to processor
hardware)", the syncing PIR to vIRR is postponed and it is handled by a
self-NV-IPI in the following VMEnter. The process looks like,
a) vcpu A accepts a virtual interrupt ->
   1) ACRN_REQUEST_EVENT is set
   2) corresponding bit in PIR is set
   3) Posted Interrupt ON bit is set
b) vcpu A does virtual interrupt injection on resume path due to
   the pending ACRN_REQUEST_EVENT ->
   1) hypervisor disables host interrupt
   2) ACRN_REQUEST_EVENT is cleared
   3) a self-NV-IPI is sent via ICR of LAPIC.
   4) IRR bit of the self-NV-IPI is set
c) (VM-ENTRY) vcpu A returns into non-root mode
   1) host interrupt enable(by HW)
   2) posted interrupt processing clears the ON bit, sync PIR to vIRR
   3) deliver the virtual interrupt if guest rflags.IF=1
d) (VM-EXIT) vcpu A traps due to a instruction execution (e.g. HLT)
   1) host interrupt disable(by HW)
   2) hypervisor enable host interrupt

Above illustrates a normal process of the virtual interrupt injection
with cpu PI support. However, a failing case is observed. The failing
case is that the self-NV-IPI from b-3 is not accepted by the core until
a timing between d-1 and d-2. b-4 happening between d-1 and d-2 is
observed by debug trace. So the self-NV-IPI will be handled in root-mode
which cannot do the syncing PIR to vIRR processing. Due to the bug
described in the first paragraph, vcpu_handle_pi_notification() cannot
succeed the virtual interrupt injection request. This patch fix it by
removing the wrong check in vcpu_handle_pi_notification() because
vcpu_handle_pi_notification() only happens on platform with cpu PI
support.

Here are some cost data for sending IPI via LAPIC ICR regsiter.
Normally, the cycles between ICR write and IRR got set is 140~260,
which is not accurate due to the MSR read overhead.
And from b-3 to c is about 560 cycles. So b-4 happens during this
period. But in bad case, b-4 doesn't happen even c is triggered.
The worse case i captured is that ICR write and IRR got set costs more
than 1900 cycles. Now, the best GUESS of the huge cost of IPI via ICR is
the ACPI bus arbitration(refer to SDM 10.6.3, 10.7 and Figure 10-17).

Tracked-On: #4937
Signed-off-by: Shuo A Liu <shuo.a.liu@intel.com>
Acked-by: Eddie Dong <eddie.dong@intel.com>
2020-06-28 10:33:22 +08:00
..
assign.c rename vm_lock/vlapic_state in VM structure 2020-06-19 16:13:20 +08:00
ept.c hv: ept: wrap a function to do guest ept flush 2020-06-22 16:25:03 +08:00
guest_memory.c gpa2hva: add INVAVLID_HPA return value check 2020-05-06 11:29:30 +08:00
hyperv.c hv: rename the ACRN_DBG_XXX 2020-01-14 10:21:23 +08:00
instr_emul.c hv: instr_emul: use cs segment when fetching instructions 2019-11-11 13:55:24 +08:00
pm.c hv: move out pause_vm from shutdown_vm 2020-04-16 21:59:03 +08:00
trusty.c hv: support xsave in context switch 2019-12-02 09:31:12 +08:00
ucode.c remove spin lock for micro code update 2020-06-19 16:13:20 +08:00
vcpu.c hv: Fix the interrupts lost issue with PI support 2020-06-28 10:33:22 +08:00
vcpuid.c hv: remove check for OSXSAVE in host 2020-06-18 14:05:56 +08:00
ve820.c HV: fix wrong gpa start of hpa2 in ve820.c 2020-04-17 14:08:54 +08:00
virq.c hv: pause all other vCPUs in same VM when do wbinvd emulation 2020-05-21 15:21:29 +08:00
virtual_cr.c hv: iommu: remove snoop related code 2020-04-16 08:40:17 +08:00
vlapic_priv.h hv: add ops to vlapic structure 2019-07-19 16:47:06 +08:00
vlapic.c hv:cleanup vcpu state 2020-05-21 15:08:49 +08:00
vm_reset.c hv: vpci: hv: vpci: refine pci device assignment logic 2020-06-03 22:00:43 +08:00
vm.c rename vm_lock/vlapic_state in VM structure 2020-06-19 16:13:20 +08:00
vmcall.c hv: vPCI: remove passthrough PCI device unuse code 2020-02-24 16:17:38 +08:00
vmcs.c hv: remove unnecessary debug symbols 2020-06-18 14:05:56 +08:00
vmexit.c hv: pause all other vCPUs in same VM when do wbinvd emulation 2020-05-21 15:21:29 +08:00
vmsr.c HV: emulate MSR_TEST_CTL 2020-04-17 09:53:59 +08:00
vmtrr.c hv: vmtrr: remove vcpu structure pointer from vmtrr 2020-03-31 10:57:47 +08:00
vmx_asm.S hv:remove some unnecessary includes 2019-05-07 09:10:13 +08:00
vmx_io.c hv: rename BOOT_CPU_ID to BSP_CPU_ID 2020-02-25 09:08:14 +08:00