|
@@ -531,6 +531,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
kvm_vgic_flush_hwstate(vcpu);
|
|
|
kvm_timer_flush_hwstate(vcpu);
|
|
|
|
|
|
+ preempt_disable();
|
|
|
local_irq_disable();
|
|
|
|
|
|
/*
|
|
@@ -543,6 +544,7 @@ 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);
|
|
|
continue;
|
|
@@ -558,8 +560,10 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
|
|
|
|
|
|
vcpu->mode = OUTSIDE_GUEST_MODE;
|
|
|
- __kvm_guest_exit();
|
|
|
- trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
|
|
|
+ /*
|
|
|
+ * Back from guest
|
|
|
+ *************************************************************/
|
|
|
+
|
|
|
/*
|
|
|
* We may have taken a host interrupt in HYP mode (ie
|
|
|
* while executing the guest). This interrupt is still
|
|
@@ -573,8 +577,17 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
|
|
|
local_irq_enable();
|
|
|
|
|
|
/*
|
|
|
- * Back from guest
|
|
|
- *************************************************************/
|
|
|
+ * We do local_irq_enable() before calling kvm_guest_exit() so
|
|
|
+ * that if a timer interrupt hits while running the guest we
|
|
|
+ * account that tick as being spent in the guest. We enable
|
|
|
+ * preemption after calling kvm_guest_exit() so that if we get
|
|
|
+ * preempted we make sure ticks after that is not counted as
|
|
|
+ * guest time.
|
|
|
+ */
|
|
|
+ kvm_guest_exit();
|
|
|
+ trace_kvm_exit(kvm_vcpu_trap_get_class(vcpu), *vcpu_pc(vcpu));
|
|
|
+ preempt_enable();
|
|
|
+
|
|
|
|
|
|
kvm_timer_sync_hwstate(vcpu);
|
|
|
kvm_vgic_sync_hwstate(vcpu);
|