qemu-ppc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-ppc] [PATCH 3/6] VFIO: EEH address mapping


From: Gavin Shan
Subject: [Qemu-ppc] [PATCH 3/6] VFIO: EEH address mapping
Date: Wed, 14 May 2014 14:27:26 +1000

For PCI devices that have been passed through from host to guest,
their PCI config address could be different. In order to support
EEH functionality, the host need know the address mapping.

Signed-off-by: Gavin Shan <address@hidden>
---
 hw/misc/vfio.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 0796abf..fdeba9e 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -32,6 +32,7 @@
 #include "hw/pci/msi.h"
 #include "hw/pci/msix.h"
 #include "hw/pci/pci.h"
+#include "hw/pci/pci_bus.h"
 #include "qemu-common.h"
 #include "qemu/error-report.h"
 #include "qemu/event_notifier.h"
@@ -3945,6 +3946,29 @@ static void vfio_unregister_err_notifier(VFIODevice 
*vdev)
     event_notifier_cleanup(&vdev->err_notifier);
 }
 
+static void vfio_eeh_addr_map(VFIODevice *vdev, bool map)
+{
+    PCIDevice *pdev = &vdev->pdev;
+    PCIBus *rootbus = pci_device_root_bus(pdev);
+    struct vfio_eeh_info info;
+
+    info.argsz = sizeof(info);
+    info.op = map ? VFIO_EEH_OP_MAP : VFIO_EEH_OP_UNMAP;
+
+    if (map) {
+        info.map.host_domain = vdev->host.domain;
+        info.map.host_cfg_addr = (vdev->host.bus << 8) |
+                       PCI_DEVFN(vdev->host.slot, vdev->host.function);
+        info.map.guest_buid = rootbus->sysdata;
+        info.map.guest_cfg_addr = (pci_bus_num(pdev->bus) << 8) | pdev->devfn;
+    } else {
+        info.unmap.buid = rootbus->sysdata;
+        info.unmap.cfg_addr = (pci_bus_num(pdev->bus) << 8) | pdev->devfn;
+    }
+
+    ioctl(vdev->group->container->fd, VFIO_EEH_INFO, &info);
+}
+
 static int vfio_initfn(PCIDevice *pdev)
 {
     VFIODevice *pvdev, *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
@@ -4085,6 +4109,7 @@ static int vfio_initfn(PCIDevice *pdev)
 
     add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL);
     vfio_register_err_notifier(vdev);
+    vfio_eeh_addr_map(vdev, true);
 
     return 0;
 
@@ -4104,6 +4129,7 @@ static void vfio_exitfn(PCIDevice *pdev)
     VFIODevice *vdev = DO_UPCAST(VFIODevice, pdev, pdev);
     VFIOGroup *group = vdev->group;
 
+    vfio_eeh_addr_map(vdev, false);
     vfio_unregister_err_notifier(vdev);
     pci_device_set_intx_routing_notifier(&vdev->pdev, NULL);
     vfio_disable_interrupts(vdev);
-- 
1.8.3.2




reply via email to

[Prev in Thread] Current Thread [Next in Thread]