[libvirt] [PATCH 02/12] libxl: PCI passthrough support

Marek Marczykowski marmarek at invisiblethingslab.com
Wed Apr 10 01:53:55 UTC 2013


---
 src/libxl/libxl_conf.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/libxl/libxl_conf.h |  2 ++
 2 files changed, 74 insertions(+)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index ffc7bbb..7668305 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -759,6 +759,74 @@ error:
     return -1;
 }
 
+int
+libxlMakePci(virDomainHostdevDefPtr l_hostdev,
+             libxl_device_pci *x_pci)
+{
+    if (l_hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This driver supports only subsystem host device mode (PCI devices only)"));
+        return -1;
+    }
+    if (l_hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("This driver supports only PCI host devices"));
+        return -1;
+    }
+
+    x_pci->bus = l_hostdev->source.subsys.u.pci.bus;
+    x_pci->dev = l_hostdev->source.subsys.u.pci.slot;
+    x_pci->func = l_hostdev->source.subsys.u.pci.function;
+    return 0;
+}
+
+static int
+libxlMakePciList(virDomainDefPtr def,
+                 libxl_domain_config *d_config)
+{
+    virDomainHostdevDefPtr *l_hostdevs = def->hostdevs;
+    int nhostdevs = def->nhostdevs;
+    int npcidevs = 0;
+    libxl_device_pci *x_pcidevs;
+    int i, j;
+
+    if (nhostdevs == 0)
+        return 0;
+
+    /* count PCI devices, ignore others (USB) */
+    for (i = 0; i < nhostdevs; i++) {
+        if (l_hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+                l_hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            npcidevs++;
+    }
+    if (VIR_ALLOC_N(x_pcidevs, npcidevs) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    for (i = 0, j = 0; i < nhostdevs; i++) {
+        if (l_hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
+                l_hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            continue;
+
+        libxl_device_pci_init(&x_pcidevs[j]);
+
+        if (libxlMakePci(l_hostdevs[i], &x_pcidevs[j]) < 0)
+            goto error;
+        j++;
+    }
+
+    d_config->pcidevs = x_pcidevs;
+    d_config->num_pcidevs = npcidevs;
+
+    return 0;
+
+error:
+    for (i = 0; i < npcidevs; i++) {
+        libxl_device_pci_dispose(&x_pcidevs[i]);
+    }
+    VIR_FREE(x_pcidevs);
+    return -1;
+}
+
 virCapsPtr
 libxlMakeCapabilities(libxl_ctx *ctx)
 {
@@ -817,6 +885,10 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
         goto error;
     }
 
+    if (libxlMakePciList(def, d_config) < 0) {
+        goto error;
+    }
+
     d_config->on_reboot = def->onReboot;
     d_config->on_poweroff = def->onPoweroff;
     d_config->on_crash = def->onCrash;
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index f8602b4..b3ab3bf 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -119,6 +119,8 @@ libxlMakeNic(virDomainNetDefPtr l_nic, libxl_device_nic *x_nic);
 int
 libxlMakeVfb(libxlDriverPrivatePtr driver,
              virDomainGraphicsDefPtr l_vfb, libxl_device_vfb *x_vfb);
+int
+libxlMakePci(virDomainHostdevDefPtr l_hostdev, libxl_device_pci *x_pci);
 
 int
 libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
-- 
1.8.1.4





More information about the libvir-list mailing list