KVM: x86/xen: Stop Xen timer before changing IRQ
[linux-2.6-microblaze.git] / arch / x86 / kvm / xen.c
index 6e55404..280cb5d 100644 (file)
@@ -707,26 +707,25 @@ int kvm_xen_vcpu_set_attr(struct kvm_vcpu *vcpu, struct kvm_xen_vcpu_attr *data)
                break;
 
        case KVM_XEN_VCPU_ATTR_TYPE_TIMER:
-               if (data->u.timer.port) {
-                       if (data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) {
-                               r = -EINVAL;
-                               break;
-                       }
-                       vcpu->arch.xen.timer_virq = data->u.timer.port;
-
-                       if (!vcpu->arch.xen.timer.function)
-                               kvm_xen_init_timer(vcpu);
-
-                       /* Restart the timer if it's set */
-                       if (data->u.timer.expires_ns)
-                               kvm_xen_start_timer(vcpu, data->u.timer.expires_ns,
-                                                   data->u.timer.expires_ns -
-                                                   get_kvmclock_ns(vcpu->kvm));
-               } else if (kvm_xen_timer_enabled(vcpu)) {
-                       kvm_xen_stop_timer(vcpu);
-                       vcpu->arch.xen.timer_virq = 0;
+               if (data->u.timer.port &&
+                   data->u.timer.priority != KVM_IRQ_ROUTING_XEN_EVTCHN_PRIO_2LEVEL) {
+                       r = -EINVAL;
+                       break;
                }
 
+               if (!vcpu->arch.xen.timer.function)
+                       kvm_xen_init_timer(vcpu);
+
+               /* Stop the timer (if it's running) before changing the vector */
+               kvm_xen_stop_timer(vcpu);
+               vcpu->arch.xen.timer_virq = data->u.timer.port;
+
+               /* Start the timer if the new value has a valid vector+expiry. */
+               if (data->u.timer.port && data->u.timer.expires_ns)
+                       kvm_xen_start_timer(vcpu, data->u.timer.expires_ns,
+                                           data->u.timer.expires_ns -
+                                           get_kvmclock_ns(vcpu->kvm));
+
                r = 0;
                break;