|
@@ -523,10 +523,20 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
if (vcpu->arch.pause)
|
|
|
vcpu_pause(vcpu);
|
|
|
|
|
|
+ /*
|
|
|
+ * Disarming the background timer must be done in a
|
|
|
+ * preemptible context, as this call may sleep.
|
|
|
+ */
|
|
|
kvm_timer_flush_hwstate(vcpu);
|
|
|
- kvm_vgic_flush_hwstate(vcpu);
|
|
|
|
|
|
+ /*
|
|
|
+ * Preparing the interrupts to be injected also
|
|
|
+ * involves poking the GIC, which must be done in a
|
|
|
+ * non-preemptible context.
|
|
|
+ */
|
|
|
preempt_disable();
|
|
|
+ kvm_vgic_flush_hwstate(vcpu);
|
|
|
+
|
|
|
local_irq_disable();
|
|
|
|
|
|
/*
|
|
@@ -539,8 +549,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_vgic_sync_hwstate(vcpu);
|
|
|
+ preempt_enable();
|
|
|
kvm_timer_sync_hwstate(vcpu);
|
|
|
continue;
|
|
|
}
|
|
@@ -585,9 +595,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
*/
|
|
|
kvm_guest_exit();
|
|
|
trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
|
|
|
- preempt_enable();
|
|
|
|
|
|
kvm_vgic_sync_hwstate(vcpu);
|
|
|
+
|
|
|
+ preempt_enable();
|
|
|
+
|
|
|
kvm_timer_sync_hwstate(vcpu);
|
|
|
|
|
|
ret = handle_exit(vcpu, run, ret);
|