|
@@ -654,11 +654,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
|
|
|
kvm_pmu_flush_hwstate(vcpu);
|
|
|
|
|
|
+ local_irq_disable();
|
|
|
+
|
|
|
kvm_timer_flush_hwstate(vcpu);
|
|
|
kvm_vgic_flush_hwstate(vcpu);
|
|
|
|
|
|
- local_irq_disable();
|
|
|
-
|
|
|
/*
|
|
|
* If we have a singal pending, or need to notify a userspace
|
|
|
* irqchip about timer or PMU level changes, then we exit (and
|
|
@@ -683,10 +683,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
if (ret <= 0 || need_new_vmid_gen(vcpu->kvm) ||
|
|
|
kvm_request_pending(vcpu)) {
|
|
|
vcpu->mode = OUTSIDE_GUEST_MODE;
|
|
|
- local_irq_enable();
|
|
|
kvm_pmu_sync_hwstate(vcpu);
|
|
|
kvm_timer_sync_hwstate(vcpu);
|
|
|
kvm_vgic_sync_hwstate(vcpu);
|
|
|
+ local_irq_enable();
|
|
|
preempt_enable();
|
|
|
continue;
|
|
|
}
|
|
@@ -709,6 +709,16 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
|
|
|
kvm_arm_clear_debug(vcpu);
|
|
|
|
|
|
+ /*
|
|
|
+ * We must sync the PMU and timer state before the vgic state so
|
|
|
+ * that the vgic can properly sample the updated state of the
|
|
|
+ * interrupt line.
|
|
|
+ */
|
|
|
+ kvm_pmu_sync_hwstate(vcpu);
|
|
|
+ kvm_timer_sync_hwstate(vcpu);
|
|
|
+
|
|
|
+ kvm_vgic_sync_hwstate(vcpu);
|
|
|
+
|
|
|
/*
|
|
|
* We may have taken a host interrupt in HYP mode (ie
|
|
|
* while executing the guest). This interrupt is still
|
|
@@ -732,16 +742,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
guest_exit();
|
|
|
trace_kvm_exit(ret, kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
|
|
|
|
|
|
- /*
|
|
|
- * We must sync the PMU and timer state before the vgic state so
|
|
|
- * that the vgic can properly sample the updated state of the
|
|
|
- * interrupt line.
|
|
|
- */
|
|
|
- kvm_pmu_sync_hwstate(vcpu);
|
|
|
- kvm_timer_sync_hwstate(vcpu);
|
|
|
-
|
|
|
- kvm_vgic_sync_hwstate(vcpu);
|
|
|
-
|
|
|
preempt_enable();
|
|
|
|
|
|
ret = handle_exit(vcpu, run, ret);
|