diff options
Diffstat (limited to 'virt/kvm/arm/arm.c')
-rw-r--r-- | virt/kvm/arm/arm.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index 4cf9b91e6c9b..772bf74ac2e9 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c | |||
@@ -307,8 +307,7 @@ void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
307 | 307 | ||
308 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | 308 | int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) |
309 | { | 309 | { |
310 | return kvm_timer_should_fire(vcpu_vtimer(vcpu)) || | 310 | return kvm_timer_is_pending(vcpu); |
311 | kvm_timer_should_fire(vcpu_ptimer(vcpu)); | ||
312 | } | 311 | } |
313 | 312 | ||
314 | void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) | 313 | void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) |
@@ -354,18 +353,18 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
354 | vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); | 353 | vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state); |
355 | 354 | ||
356 | kvm_arm_set_running_vcpu(vcpu); | 355 | kvm_arm_set_running_vcpu(vcpu); |
357 | |||
358 | kvm_vgic_load(vcpu); | 356 | kvm_vgic_load(vcpu); |
357 | kvm_timer_vcpu_load(vcpu); | ||
359 | } | 358 | } |
360 | 359 | ||
361 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) | 360 | void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) |
362 | { | 361 | { |
362 | kvm_timer_vcpu_put(vcpu); | ||
363 | kvm_vgic_put(vcpu); | 363 | kvm_vgic_put(vcpu); |
364 | 364 | ||
365 | vcpu->cpu = -1; | 365 | vcpu->cpu = -1; |
366 | 366 | ||
367 | kvm_arm_set_running_vcpu(NULL); | 367 | kvm_arm_set_running_vcpu(NULL); |
368 | kvm_timer_vcpu_put(vcpu); | ||
369 | } | 368 | } |
370 | 369 | ||
371 | static void vcpu_power_off(struct kvm_vcpu *vcpu) | 370 | static void vcpu_power_off(struct kvm_vcpu *vcpu) |
@@ -657,11 +656,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
657 | 656 | ||
658 | kvm_pmu_flush_hwstate(vcpu); | 657 | kvm_pmu_flush_hwstate(vcpu); |
659 | 658 | ||
660 | kvm_timer_flush_hwstate(vcpu); | ||
661 | kvm_vgic_flush_hwstate(vcpu); | ||
662 | |||
663 | local_irq_disable(); | 659 | local_irq_disable(); |
664 | 660 | ||
661 | kvm_vgic_flush_hwstate(vcpu); | ||
662 | |||
665 | /* | 663 | /* |
666 | * If we have a singal pending, or need to notify a userspace | 664 | * If we have a singal pending, or need to notify a userspace |
667 | * irqchip about timer or PMU level changes, then we exit (and | 665 | * irqchip about timer or PMU level changes, then we exit (and |
@@ -686,10 +684,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
686 | if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) || | 684 | if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) || |
687 | kvm_request_pending(vcpu)) { | 685 | kvm_request_pending(vcpu)) { |
688 | vcpu->mode = OUTSIDE_GUEST_MODE; | 686 | vcpu->mode = OUTSIDE_GUEST_MODE; |
689 | local_irq_enable(); | ||
690 | kvm_pmu_sync_hwstate(vcpu); | 687 | kvm_pmu_sync_hwstate(vcpu); |
691 | kvm_timer_sync_hwstate(vcpu); | 688 | kvm_timer_sync_hwstate(vcpu); |
692 | kvm_vgic_sync_hwstate(vcpu); | 689 | kvm_vgic_sync_hwstate(vcpu); |
690 | local_irq_enable(); | ||
693 | preempt_enable(); | 691 | preempt_enable(); |
694 | continue; | 692 | continue; |
695 | } | 693 | } |
@@ -713,6 +711,27 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
713 | kvm_arm_clear_debug(vcpu); | 711 | kvm_arm_clear_debug(vcpu); |
714 | 712 | ||
715 | /* | 713 | /* |
714 | * We must sync the PMU state before the vgic state so | ||
715 | * that the vgic can properly sample the updated state of the | ||
716 | * interrupt line. | ||
717 | */ | ||
718 | kvm_pmu_sync_hwstate(vcpu); | ||
719 | |||
720 | /* | ||
721 | * Sync the vgic state before syncing the timer state because | ||
722 | * the timer code needs to know if the virtual timer | ||
723 | * interrupts are active. | ||
724 | */ | ||
725 | kvm_vgic_sync_hwstate(vcpu); | ||
726 | |||
727 | /* | ||
728 | * Sync the timer hardware state before enabling interrupts as | ||
729 | * we don't want vtimer interrupts to race with syncing the | ||
730 | * timer virtual interrupt state. | ||
731 | */ | ||
732 | kvm_timer_sync_hwstate(vcpu); | ||
733 | |||
734 | /* | ||
716 | * We may have taken a host interrupt in HYP mode (ie | 735 | * We may have taken a host interrupt in HYP mode (ie |
717 | * while executing the guest). This interrupt is still | 736 | * while executing the guest). This interrupt is still |
718 | * pending, as we haven't serviced it yet! | 737 | * pending, as we haven't serviced it yet! |
@@ -735,16 +754,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run) | |||
735 | guest_exit(); | 754 | guest_exit(); |
736 | trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); | 755 | trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu)); |
737 | 756 | ||
738 | /* | ||
739 | * We must sync the PMU and timer state before the vgic state so | ||
740 | * that the vgic can properly sample the updated state of the | ||
741 | * interrupt line. | ||
742 | */ | ||
743 | kvm_pmu_sync_hwstate(vcpu); | ||
744 | kvm_timer_sync_hwstate(vcpu); | ||
745 | |||
746 | kvm_vgic_sync_hwstate(vcpu); | ||
747 | |||
748 | preempt_enable(); | 757 | preempt_enable(); |
749 | 758 | ||
750 | ret = handle_exit(vcpu, run, ret); | 759 | ret = handle_exit(vcpu, run, ret); |