diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 19:50:56 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-10-10 19:50:56 -0400 |
commit | 3dddebe059d81a39aa1135b6e6d18ebfa4d25384 (patch) | |
tree | 6925b4a2de099ab2d679a038b9b6f1538701489f | |
parent | e626d177fcb7d8eb759da49c652a68ff90a59fba (diff) | |
parent | 899649b7d4ead76c19e39251ca886eebe3f811a8 (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.c | 7 | ||||
-rw-r--r-- | drivers/vfio/pci/vfio_pci_intrs.c | 18 |
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 | ||