linux/virt/kvm/arm
Marc Zyngier bae561c0cf KVM: arm/arm64: arch_timer: Mark physical interrupt active when a virtual interrupt is pending
When a guest gets scheduled, KVM performs a "load" operation,
which for the timer includes evaluating the virtual "active" state
of the interrupt, and replicating it on the physical side. This
ensures that the deactivation in the guest will also take place
in the physical GIC distributor.

If the interrupt is not yet active, we flag it as inactive on the
physical side.  This means that on restoring the timer registers,
if the timer has expired, we'll immediately take an interrupt.
That's absolutely fine, as the interrupt will then be flagged as
active on the physical side. What this assumes though is that we'll
enter the guest right after having taken the interrupt, and that
the guest will quickly ACK the interrupt, making it active at on
the virtual side.

It turns out that quite often, this assumption doesn't really hold.
The guest may be preempted on the back on this interrupt, either
from kernel space or whilst running at EL1 when a host interrupt
fires. When this happens, we repeat the whole sequence on the
next load (interrupt marked as inactive, timer registers restored,
interrupt fires). And if it takes a really long time for a guest
to activate the interrupt (as it does with nested virt), we end-up
with many such events in quick succession, leading to the guest only
making very slow progress.

This can also be seen with the number of virtual timer interrupt on the
host being far greater than the same number in the guest.

An easy way to fix this is to evaluate the timer state when performing
the "load" operation, just like we do when the interrupt actually fires.
If the timer has a pending virtual interrupt at this stage, then we
can safely flag the physical interrupt as being active, which prevents
spurious exits.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
2019-02-19 21:05:50 +00:00
..
hyp KVM: arm64: Fix ICH_ELRSR_EL2 sysreg naming 2019-02-19 21:05:39 +00:00
vgic arm/arm64: KVM: Introduce kvm_call_hyp_ret() 2019-02-19 21:05:24 +00:00
aarch32.c kvm/arm: use PSR_AA32 definitions 2018-07-05 17:24:15 +01:00
arch_timer.c KVM: arm/arm64: arch_timer: Mark physical interrupt active when a virtual interrupt is pending 2019-02-19 21:05:50 +00:00
arm.c KVM: arm/arm64: Simplify bg_timer programming 2019-02-19 21:05:36 +00:00
mmio.c arm64: KVM: Skip MMIO insn after emulation 2018-12-18 14:10:36 +00:00
mmu.c KVM: arm/arm64: Move kvm_is_write_fault to header file 2019-02-19 21:05:45 +00:00
perf.c KVM: arm/arm64: Move shared files to virt/kvm/arm 2017-05-04 13:57:26 +02:00
pmu.c KVM: arm64: Rewrite system register accessors to read/write functions 2018-03-19 10:53:16 +00:00
psci.c sched/swait: Rename to exclusive 2018-06-20 11:35:56 +02:00
trace.h KVM: arm/arm64: Rework the timer code to use a timer_map 2019-02-19 21:05:43 +00:00