arm/arm64: KVM: Fix ordering of timer/GIC on guest entry
authorMarc Zyngier <marc.zyngier@arm.com>
Fri, 5 Jun 2015 08:33:28 +0000 (09:33 +0100)
committerMarc Zyngier <marc.zyngier@arm.com>
Wed, 12 Aug 2015 10:28:23 +0000 (11:28 +0100)
As we now inject the timer interrupt when we're about to enter
the guest, it makes a lot more sense to make sure this happens
before the vgic code queues the pending interrupts.

Otherwise, we get the interrupt on the following exit, which is
not great for latency (and leads to all kind of bizarre issues
when using with active interrupts at the HW level).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
arch/arm/kvm/arm.c

index 9ce5cf02ed178a55894aefd70c7b8da92407afa7..1141d21b7e3c3bbc6bb2729a87f9f3b10c8f6b3d 100644 (file)
@@ -523,8 +523,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                if (vcpu->arch.pause)
                        vcpu_pause(vcpu);
 
-               kvm_vgic_flush_hwstate(vcpu);
                kvm_timer_flush_hwstate(vcpu);
+               kvm_vgic_flush_hwstate(vcpu);
 
                preempt_disable();
                local_irq_disable();
@@ -540,8 +540,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                if (ret <= 0 || need_new_vmid_gen(vcpu->kvm)) {
                        local_irq_enable();
                        preempt_enable();
-                       kvm_timer_sync_hwstate(vcpu);
                        kvm_vgic_sync_hwstate(vcpu);
+                       kvm_timer_sync_hwstate(vcpu);
                        continue;
                }
 
@@ -587,9 +587,8 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
                trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
                preempt_enable();
 
-
-               kvm_timer_sync_hwstate(vcpu);
                kvm_vgic_sync_hwstate(vcpu);
+               kvm_timer_sync_hwstate(vcpu);
 
                ret = handle_exit(vcpu, run, ret);
        }