aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm/kvm_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'virt/kvm/kvm_main.c')
-rw-r--r--virt/kvm/kvm_main.c70
1 files changed, 54 insertions, 16 deletions
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index bf36ae9ae7df..54d25e6f6d2d 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -64,6 +64,9 @@
64MODULE_AUTHOR("Qumranet"); 64MODULE_AUTHOR("Qumranet");
65MODULE_LICENSE("GPL"); 65MODULE_LICENSE("GPL");
66 66
67static int msi2intx = 1;
68module_param(msi2intx, bool, 0);
69
67DEFINE_SPINLOCK(kvm_lock); 70DEFINE_SPINLOCK(kvm_lock);
68LIST_HEAD(vm_list); 71LIST_HEAD(vm_list);
69 72
@@ -250,7 +253,8 @@ static int assigned_device_update_intx(struct kvm *kvm,
250 return 0; 253 return 0;
251 254
252 if (irqchip_in_kernel(kvm)) { 255 if (irqchip_in_kernel(kvm)) {
253 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) { 256 if (!msi2intx &&
257 adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) {
254 free_irq(adev->host_irq, (void *)kvm); 258 free_irq(adev->host_irq, (void *)kvm);
255 pci_disable_msi(adev->dev); 259 pci_disable_msi(adev->dev);
256 } 260 }
@@ -285,21 +289,33 @@ static int assigned_device_update_msi(struct kvm *kvm,
285{ 289{
286 int r; 290 int r;
287 291
288 /* x86 don't care upper address of guest msi message addr */ 292 if (airq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI) {
289 adev->guest_msi.address_lo = airq->guest_msi.addr_lo; 293 /* x86 don't care upper address of guest msi message addr */
290 adev->guest_msi.data = airq->guest_msi.data; 294 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_MSI;
291 adev->ack_notifier.gsi = -1; 295 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_INTX;
296 adev->guest_msi.address_lo = airq->guest_msi.addr_lo;
297 adev->guest_msi.data = airq->guest_msi.data;
298 adev->ack_notifier.gsi = -1;
299 } else if (msi2intx) {
300 adev->irq_requested_type |= KVM_ASSIGNED_DEV_GUEST_INTX;
301 adev->irq_requested_type &= ~KVM_ASSIGNED_DEV_GUEST_MSI;
302 adev->guest_irq = airq->guest_irq;
303 adev->ack_notifier.gsi = airq->guest_irq;
304 }
292 305
293 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI) 306 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_MSI)
294 return 0; 307 return 0;
295 308
296 if (irqchip_in_kernel(kvm)) { 309 if (irqchip_in_kernel(kvm)) {
297 if (adev->irq_requested_type & KVM_ASSIGNED_DEV_HOST_INTX) 310 if (!msi2intx) {
298 free_irq(adev->host_irq, (void *)adev); 311 if (adev->irq_requested_type &
299 312 KVM_ASSIGNED_DEV_HOST_INTX)
300 r = pci_enable_msi(adev->dev); 313 free_irq(adev->host_irq, (void *)adev);
301 if (r) 314
302 return r; 315 r = pci_enable_msi(adev->dev);
316 if (r)
317 return r;
318 }
303 319
304 adev->host_irq = adev->dev->irq; 320 adev->host_irq = adev->dev->irq;
305 if (request_irq(adev->host_irq, kvm_assigned_dev_intr, 0, 321 if (request_irq(adev->host_irq, kvm_assigned_dev_intr, 0,
@@ -307,8 +323,10 @@ static int assigned_device_update_msi(struct kvm *kvm,
307 return -EIO; 323 return -EIO;
308 } 324 }
309 325
310 adev->irq_requested_type = KVM_ASSIGNED_DEV_GUEST_MSI | 326 if (!msi2intx)
311 KVM_ASSIGNED_DEV_HOST_MSI; 327 adev->irq_requested_type = KVM_ASSIGNED_DEV_GUEST_MSI;
328
329 adev->irq_requested_type |= KVM_ASSIGNED_DEV_HOST_MSI;
312 return 0; 330 return 0;
313} 331}
314#endif 332#endif
@@ -346,10 +364,19 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
346 goto out_release; 364 goto out_release;
347 else 365 else
348 match->irq_source_id = r; 366 match->irq_source_id = r;
367
368#ifdef CONFIG_X86
369 /* Determine host device irq type, we can know the
370 * result from dev->msi_enabled */
371 if (msi2intx)
372 pci_enable_msi(match->dev);
373#endif
349 } 374 }
350 } 375 }
351 376
352 if (assigned_irq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI) { 377 if ((!msi2intx &&
378 (assigned_irq->flags & KVM_DEV_IRQ_ASSIGN_ENABLE_MSI)) ||
379 (msi2intx && match->dev->msi_enabled)) {
353#ifdef CONFIG_X86 380#ifdef CONFIG_X86
354 r = assigned_device_update_msi(kvm, match, assigned_irq); 381 r = assigned_device_update_msi(kvm, match, assigned_irq);
355 if (r) { 382 if (r) {
@@ -362,8 +389,16 @@ static int kvm_vm_ioctl_assign_irq(struct kvm *kvm,
362#endif 389#endif
363 } else if (assigned_irq->host_irq == 0 && match->dev->irq == 0) { 390 } else if (assigned_irq->host_irq == 0 && match->dev->irq == 0) {
364 /* Host device IRQ 0 means don't support INTx */ 391 /* Host device IRQ 0 means don't support INTx */
365 printk(KERN_WARNING "kvm: wait device to enable MSI!\n"); 392 if (!msi2intx) {
366 r = 0; 393 printk(KERN_WARNING
394 "kvm: wait device to enable MSI!\n");
395 r = 0;
396 } else {
397 printk(KERN_WARNING
398 "kvm: failed to enable MSI device!\n");
399 r = -ENOTTY;
400 goto out_release;
401 }
367 } else { 402 } else {
368 /* Non-sharing INTx mode */ 403 /* Non-sharing INTx mode */
369 r = assigned_device_update_intx(kvm, match, assigned_irq); 404 r = assigned_device_update_intx(kvm, match, assigned_irq);
@@ -2209,6 +2244,9 @@ int kvm_init(void *opaque, unsigned int vcpu_size,
2209 2244
2210 kvm_preempt_ops.sched_in = kvm_sched_in; 2245 kvm_preempt_ops.sched_in = kvm_sched_in;
2211 kvm_preempt_ops.sched_out = kvm_sched_out; 2246 kvm_preempt_ops.sched_out = kvm_sched_out;
2247#ifndef CONFIG_X86
2248 msi2intx = 0;
2249#endif
2212 2250
2213 return 0; 2251 return 0;
2214 2252