@@ -142,7 +142,8 @@ static void deassign_guest_irq(struct kvm *kvm,
kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier);
assigned_dev->ack_notifier.gsi = -1;
- if (assigned_dev->irq_source_id != -1)
+ if (assigned_dev->irq_source_id != -1
+ && assigned_dev->irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID)
kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id);
assigned_dev->irq_source_id = -1;
assigned_dev->irq_requested_type &= ~(KVM_DEV_IRQ_GUEST_MASK);
@@ -396,20 +397,17 @@ static int assign_guest_irq(struct kvm *kvm,
struct kvm_assigned_irq *irq,
unsigned long guest_irq_type)
{
- int id;
+ int id = KVM_USERSPACE_IRQ_SOURCE_ID;
int r = -EEXIST;
if (dev->irq_requested_type & KVM_DEV_IRQ_GUEST_MASK)
return r;
- id = kvm_request_irq_source_id(kvm);
- if (id < 0)
- return id;
-
- dev->irq_source_id = id;
-
switch (guest_irq_type) {
case KVM_DEV_IRQ_GUEST_INTX:
+ id = kvm_request_irq_source_id(kvm);
+ if (id < 0)
+ return id;
r = assigned_device_enable_guest_intx(kvm, dev, irq);
break;
#ifdef __KVM_HAVE_MSI
@@ -426,11 +424,15 @@ static int assign_guest_irq(struct kvm *kvm,
r = -EINVAL;
}
+ dev->irq_source_id = id;
+
if (!r) {
dev->irq_requested_type |= guest_irq_type;
kvm_register_irq_ack_notifier(kvm, &dev->ack_notifier);
- } else
- kvm_free_irq_source_id(kvm, dev->irq_source_id);
+ } else {
+ if (dev->irq_source_id != KVM_USERSPACE_IRQ_SOURCE_ID)
+ kvm_free_irq_source_id(kvm, dev->irq_source_id);
+ }
return r;
}