aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 19:50:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 19:50:56 -0400
commit3dddebe059d81a39aa1135b6e6d18ebfa4d25384 (patch)
tree6925b4a2de099ab2d679a038b9b6f1538701489f
parente626d177fcb7d8eb759da49c652a68ff90a59fba (diff)
parent899649b7d4ead76c19e39251ca886eebe3f811a8 (diff)
Merge tag 'vfio-for-v3.7-rc1' of git://github.com/awilliam/linux-vfio
Pull vfio fixes from Alex Williamson: "This includes a fix for PCI BAR mmaps after recent mm changes, fixing an interrupt race, and fixing a consistency bug in interrupt state when switching interrupt modes." * tag 'vfio-for-v3.7-rc1' of git://github.com/awilliam/linux-vfio: vfio: Fix PCI INTx disable consistency vfio: Move PCI INTx eventfd setting earlier vfio: Fix PCI mmap after b3b9c293
-rw-r--r--drivers/vfio/pci/vfio_pci.c7
-rw-r--r--drivers/vfio/pci/vfio_pci_intrs.c18
2 files changed, 18 insertions, 7 deletions
diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 6d369fe9d30b..6c119944bbb6 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -408,7 +408,7 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
408 struct vfio_pci_device *vdev = device_data; 408 struct vfio_pci_device *vdev = device_data;
409 struct pci_dev *pdev = vdev->pdev; 409 struct pci_dev *pdev = vdev->pdev;
410 unsigned int index; 410 unsigned int index;
411 u64 phys_len, req_len, pgoff, req_start, phys; 411 u64 phys_len, req_len, pgoff, req_start;
412 int ret; 412 int ret;
413 413
414 index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT); 414 index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
@@ -463,10 +463,9 @@ static int vfio_pci_mmap(void *device_data, struct vm_area_struct *vma)
463 vma->vm_private_data = vdev; 463 vma->vm_private_data = vdev;
464 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP; 464 vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
465 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 465 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
466 vma->vm_pgoff = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff;
466 467
467 phys = (pci_resource_start(pdev, index) >> PAGE_SHIFT) + pgoff; 468 return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
468
469 return remap_pfn_range(vma, vma->vm_start, phys,
470 req_len, vma->vm_page_prot); 469 req_len, vma->vm_page_prot);
471} 470}
472 471
diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
index d8dedc7d3910..3639371fa697 100644
--- a/drivers/vfio/pci/vfio_pci_intrs.c
+++ b/drivers/vfio/pci/vfio_pci_intrs.c
@@ -366,6 +366,17 @@ static int vfio_intx_enable(struct vfio_pci_device *vdev)
366 return -ENOMEM; 366 return -ENOMEM;
367 367
368 vdev->num_ctx = 1; 368 vdev->num_ctx = 1;
369
370 /*
371 * If the virtual interrupt is masked, restore it. Devices
372 * supporting DisINTx can be masked at the hardware level
373 * here, non-PCI-2.3 devices will have to wait until the
374 * interrupt is enabled.
375 */
376 vdev->ctx[0].masked = vdev->virq_disabled;
377 if (vdev->pci_2_3)
378 pci_intx(vdev->pdev, !vdev->ctx[0].masked);
379
369 vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX; 380 vdev->irq_type = VFIO_PCI_INTX_IRQ_INDEX;
370 381
371 return 0; 382 return 0;
@@ -400,25 +411,26 @@ static int vfio_intx_set_signal(struct vfio_pci_device *vdev, int fd)
400 return PTR_ERR(trigger); 411 return PTR_ERR(trigger);
401 } 412 }
402 413
414 vdev->ctx[0].trigger = trigger;
415
403 if (!vdev->pci_2_3) 416 if (!vdev->pci_2_3)
404 irqflags = 0; 417 irqflags = 0;
405 418
406 ret = request_irq(pdev->irq, vfio_intx_handler, 419 ret = request_irq(pdev->irq, vfio_intx_handler,
407 irqflags, vdev->ctx[0].name, vdev); 420 irqflags, vdev->ctx[0].name, vdev);
408 if (ret) { 421 if (ret) {
422 vdev->ctx[0].trigger = NULL;
409 kfree(vdev->ctx[0].name); 423 kfree(vdev->ctx[0].name);
410 eventfd_ctx_put(trigger); 424 eventfd_ctx_put(trigger);
411 return ret; 425 return ret;
412 } 426 }
413 427
414 vdev->ctx[0].trigger = trigger;
415
416 /* 428 /*
417 * INTx disable will stick across the new irq setup, 429 * INTx disable will stick across the new irq setup,
418 * disable_irq won't. 430 * disable_irq won't.
419 */ 431 */
420 spin_lock_irqsave(&vdev->irqlock, flags); 432 spin_lock_irqsave(&vdev->irqlock, flags);
421 if (!vdev->pci_2_3 && (vdev->ctx[0].masked || vdev->virq_disabled)) 433 if (!vdev->pci_2_3 && vdev->ctx[0].masked)
422 disable_irq_nosync(pdev->irq); 434 disable_irq_nosync(pdev->irq);
423 spin_unlock_irqrestore(&vdev->irqlock, flags); 435 spin_unlock_irqrestore(&vdev->irqlock, flags);
424 436