diff options
Diffstat (limited to 'virt/kvm/kvm_main.c')
| -rw-r--r-- | virt/kvm/kvm_main.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index cf0ab8ed3845..a87f45edfae8 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
| @@ -105,14 +105,12 @@ static void kvm_assigned_dev_interrupt_work_handler(struct work_struct *work) | |||
| 105 | */ | 105 | */ |
| 106 | mutex_lock(&assigned_dev->kvm->lock); | 106 | mutex_lock(&assigned_dev->kvm->lock); |
| 107 | kvm_set_irq(assigned_dev->kvm, | 107 | kvm_set_irq(assigned_dev->kvm, |
| 108 | assigned_dev->irq_source_id, | ||
| 108 | assigned_dev->guest_irq, 1); | 109 | assigned_dev->guest_irq, 1); |
| 109 | mutex_unlock(&assigned_dev->kvm->lock); | 110 | mutex_unlock(&assigned_dev->kvm->lock); |
| 110 | kvm_put_kvm(assigned_dev->kvm); | 111 | kvm_put_kvm(assigned_dev->kvm); |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | /* FIXME: Implement the OR logic needed to make shared interrupts on | ||
| 114 | * this line behave properly | ||
| 115 | */ | ||
| 116 | static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) | 114 | static irqreturn_t kvm_assigned_dev_intr(int irq, void *dev_id) |
| 117 | { | 115 | { |
| 118 | struct kvm_assigned_dev_kernel *assigned_dev = | 116 | struct kvm_assigned_dev_kernel *assigned_dev = |
| @@ -134,7 +132,7 @@ static void kvm_assigned_dev_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
| 134 | 132 | ||
| 135 | dev = container_of(kian, struct kvm_assigned_dev_kernel, | 133 | dev = container_of(kian, struct kvm_assigned_dev_kernel, |
| 136 | ack_notifier); | 134 | ack_notifier); |
| 137 | kvm_set_irq(dev->kvm, dev->guest_irq, 0); | 135 | kvm_set_irq(dev->kvm, dev->irq_source_id, dev->guest_irq, 0); |
| 138 | enable_irq(dev->host_irq); | 136 | enable_irq(dev->host_irq); |
| 139 | } | 137 | } |
| 140 | 138 | ||
| @@ -146,6 +144,7 @@ static void kvm_free_assigned_device(struct kvm *kvm, | |||
| 146 | free_irq(assigned_dev->host_irq, (void *)assigned_dev); | 144 | free_irq(assigned_dev->host_irq, (void *)assigned_dev); |
| 147 | 145 | ||
| 148 | kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier); | 146 | kvm_unregister_irq_ack_notifier(kvm, &assigned_dev->ack_notifier); |
| 147 | kvm_free_irq_source_id(kvm, assigned_dev->irq_source_id); | ||
| 149 | 148 | ||
| 150 | if (cancel_work_sync(&assigned_dev->interrupt_work)) | 149 | if (cancel_work_sync(&assigned_dev->interrupt_work)) |
| 151 | /* We had pending work. That means we will have to take | 150 | /* We had pending work. That means we will have to take |
| @@ -215,6 +214,11 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm, | |||
| 215 | match->ack_notifier.gsi = assigned_irq->guest_irq; | 214 | match->ack_notifier.gsi = assigned_irq->guest_irq; |
| 216 | match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; | 215 | match->ack_notifier.irq_acked = kvm_assigned_dev_ack_irq; |
| 217 | kvm_register_irq_ack_notifier(kvm, &match->ack_notifier); | 216 | kvm_register_irq_ack_notifier(kvm, &match->ack_notifier); |
| 217 | r = kvm_request_irq_source_id(kvm); | ||
| 218 | if (r < 0) | ||
| 219 | goto out_release; | ||
| 220 | else | ||
| 221 | match->irq_source_id = r; | ||
| 218 | 222 | ||
| 219 | /* Even though this is PCI, we don't want to use shared | 223 | /* Even though this is PCI, we don't want to use shared |
| 220 | * interrupts. Sharing host devices with guest-assigned devices | 224 | * interrupts. Sharing host devices with guest-assigned devices |
