summaryrefslogtreecommitdiffstats
path: root/virt/kvm/arm/arch_timer.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2018-08-22 14:07:56 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2018-08-22 14:07:56 +0200
commit631989303b06b8fdb15ec3b88aee2d25e80d4cec (patch)
tree25c00dc9392cb7b25e5c9355a6176f6f4be36924 /virt/kvm/arm/arch_timer.c
parentad1d69735878a6bf797705b5d2a20316d35e1113 (diff)
parent976d34e2dab10ece5ea8fe7090b7692913f89084 (diff)
downloadlinux-stable-631989303b06b8fdb15ec3b88aee2d25e80d4cec.tar.gz
linux-stable-631989303b06b8fdb15ec3b88aee2d25e80d4cec.tar.bz2
linux-stable-631989303b06b8fdb15ec3b88aee2d25e80d4cec.zip
Merge tag 'kvmarm-for-v4.19' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm updates for 4.19 - Support for Group0 interrupts in guests - Cache management optimizations for ARMv8.4 systems - Userspace interface for RAS, allowing error retrival and injection - Fault path optimization - Emulated physical timer fixes - Random cleanups
Diffstat (limited to 'virt/kvm/arm/arch_timer.c')
-rw-r--r--virt/kvm/arm/arch_timer.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index bd3d57f40f1b..17cecc96f735 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -295,9 +295,9 @@ static void phys_timer_emulate(struct kvm_vcpu *vcpu)
struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
/*
- * If the timer can fire now we have just raised the IRQ line and we
- * don't need to have a soft timer scheduled for the future. If the
- * timer cannot fire at all, then we also don't need a soft timer.
+ * If the timer can fire now, we don't need to have a soft timer
+ * scheduled for the future. If the timer cannot fire at all,
+ * then we also don't need a soft timer.
*/
if (kvm_timer_should_fire(ptimer) || !kvm_timer_irq_can_fire(ptimer)) {
soft_timer_cancel(&timer->phys_timer, NULL);
@@ -332,10 +332,10 @@ static void kvm_timer_update_state(struct kvm_vcpu *vcpu)
level = kvm_timer_should_fire(vtimer);
kvm_timer_update_irq(vcpu, level, vtimer);
+ phys_timer_emulate(vcpu);
+
if (kvm_timer_should_fire(ptimer) != ptimer->irq.level)
kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);
-
- phys_timer_emulate(vcpu);
}
static void vtimer_save_state(struct kvm_vcpu *vcpu)
@@ -487,6 +487,7 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
{
struct arch_timer_cpu *timer = &vcpu->arch.timer_cpu;
struct arch_timer_context *vtimer = vcpu_vtimer(vcpu);
+ struct arch_timer_context *ptimer = vcpu_ptimer(vcpu);
if (unlikely(!timer->enabled))
return;
@@ -502,6 +503,10 @@ void kvm_timer_vcpu_load(struct kvm_vcpu *vcpu)
/* Set the background timer for the physical timer emulation. */
phys_timer_emulate(vcpu);
+
+ /* If the timer fired while we weren't running, inject it now */
+ if (kvm_timer_should_fire(ptimer) != ptimer->irq.level)
+ kvm_timer_update_irq(vcpu, !ptimer->irq.level, ptimer);
}
bool kvm_timer_should_notify_user(struct kvm_vcpu *vcpu)