vfio/pci: Implement the DMA fault handler
Whenever the eventfd is triggered, we retrieve the DMA fault(s) from the mmapped fault region and inject them in the iommu memory region. Signed-off-by: Eric Auger <eric.auger@redhat.com> Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
This commit is contained in:
parent
58476d1b47
commit
93c6df7e5a
96
vfio-pci-Implement-the-DMA-fault-handler.patch
Normal file
96
vfio-pci-Implement-the-DMA-fault-handler.patch
Normal file
@ -0,0 +1,96 @@
|
||||
From 139d0b3474c29427fea4a0ed47f51c01a76a8636 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Auger <eric.auger@redhat.com>
|
||||
Date: Tue, 5 Mar 2019 16:35:32 +0100
|
||||
Subject: [PATCH] vfio/pci: Implement the DMA fault handler
|
||||
|
||||
Whenever the eventfd is triggered, we retrieve the DMA fault(s)
|
||||
from the mmapped fault region and inject them in the iommu
|
||||
memory region.
|
||||
|
||||
Signed-off-by: Eric Auger <eric.auger@redhat.com>
|
||||
Signed-off-by: Kunkun Jiang <jiangkunkun@huawei.com>
|
||||
---
|
||||
hw/vfio/pci.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
hw/vfio/pci.h | 1 +
|
||||
2 files changed, 51 insertions(+)
|
||||
|
||||
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
|
||||
index 0db7d68258..d1198c8a23 100644
|
||||
--- a/hw/vfio/pci.c
|
||||
+++ b/hw/vfio/pci.c
|
||||
@@ -2922,10 +2922,60 @@ static PCIPASIDOps vfio_pci_pasid_ops = {
|
||||
static void vfio_dma_fault_notifier_handler(void *opaque)
|
||||
{
|
||||
VFIOPCIExtIRQ *ext_irq = opaque;
|
||||
+ VFIOPCIDevice *vdev = ext_irq->vdev;
|
||||
+ PCIDevice *pdev = &vdev->pdev;
|
||||
+ AddressSpace *as = pci_device_iommu_address_space(pdev);
|
||||
+ IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(as->root);
|
||||
+ struct vfio_region_dma_fault header;
|
||||
+ struct iommu_fault *queue;
|
||||
+ char *queue_buffer = NULL;
|
||||
+ ssize_t bytes;
|
||||
|
||||
if (!event_notifier_test_and_clear(&ext_irq->notifier)) {
|
||||
return;
|
||||
}
|
||||
+
|
||||
+ bytes = pread(vdev->vbasedev.fd, &header, sizeof(header),
|
||||
+ vdev->dma_fault_region.fd_offset);
|
||||
+ if (bytes != sizeof(header)) {
|
||||
+ error_report("%s unable to read the fault region header (0x%lx)",
|
||||
+ __func__, bytes);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Normally the fault queue is mmapped */
|
||||
+ queue = (struct iommu_fault *)vdev->dma_fault_region.mmaps[0].mmap;
|
||||
+ if (!queue) {
|
||||
+ size_t queue_size = header.nb_entries * header.entry_size;
|
||||
+
|
||||
+ error_report("%s: fault queue not mmapped: slower fault handling",
|
||||
+ vdev->vbasedev.name);
|
||||
+
|
||||
+ queue_buffer = g_malloc(queue_size);
|
||||
+ bytes = pread(vdev->vbasedev.fd, queue_buffer, queue_size,
|
||||
+ vdev->dma_fault_region.fd_offset + header.offset);
|
||||
+ if (bytes != queue_size) {
|
||||
+ error_report("%s unable to read the fault queue (0x%lx)",
|
||||
+ __func__, bytes);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ queue = (struct iommu_fault *)queue_buffer;
|
||||
+ }
|
||||
+
|
||||
+ while (vdev->fault_tail_index != header.head) {
|
||||
+ memory_region_inject_faults(iommu_mr, 1,
|
||||
+ &queue[vdev->fault_tail_index]);
|
||||
+ vdev->fault_tail_index =
|
||||
+ (vdev->fault_tail_index + 1) % header.nb_entries;
|
||||
+ }
|
||||
+ bytes = pwrite(vdev->vbasedev.fd, &vdev->fault_tail_index, 4,
|
||||
+ vdev->dma_fault_region.fd_offset);
|
||||
+ if (bytes != 4) {
|
||||
+ error_report("%s unable to write the fault region tail index (0x%lx)",
|
||||
+ __func__, bytes);
|
||||
+ }
|
||||
+ g_free(queue_buffer);
|
||||
}
|
||||
|
||||
static int vfio_register_ext_irq_handler(VFIOPCIDevice *vdev,
|
||||
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
|
||||
index 815154656c..e31bc0173a 100644
|
||||
--- a/hw/vfio/pci.h
|
||||
+++ b/hw/vfio/pci.h
|
||||
@@ -142,6 +142,7 @@ typedef struct VFIOPCIDevice {
|
||||
EventNotifier req_notifier;
|
||||
VFIOPCIExtIRQ *ext_irqs;
|
||||
VFIORegion dma_fault_region;
|
||||
+ uint32_t fault_tail_index;
|
||||
int (*resetfn)(struct VFIOPCIDevice *);
|
||||
uint32_t vendor_id;
|
||||
uint32_t device_id;
|
||||
--
|
||||
2.27.0
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user