[libvirt] [PATCH] add pci passthrough impl to libxl

Chunyan Liu cyliu at suse.com
Thu May 16 05:58:54 UTC 2013


Add pci passthrough implementation to libxl driver, using hostdev common library.

---
 src/libxl/libxl_conf.c   |   44 ++++++++++++++++++++++++++++++++++++++++++++
 src/libxl/libxl_driver.c |   21 ++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 1a7e430..61dfe85 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -708,6 +708,46 @@ error:
     return -1;
 }
 
+static int
+libxlMakePciList(virDomainDefPtr def, libxl_domain_config *d_config)
+{
+    virDomainHostdevDefPtr *l_hostdevs = def->hostdevs;
+    int nhostdevs = def->nhostdevs;
+    libxl_device_pci *x_pcidevs;
+    int i;
+
+    if (nhostdevs == 0)
+        return 0;
+
+    if (VIR_ALLOC_N(x_pcidevs, nhostdevs) < 0) {
+        virReportOOMError();
+        return -1;
+    }
+
+    d_config->num_pcidevs = 0;
+    d_config->pcidevs = x_pcidevs;
+
+    for (i = 0 ; i < nhostdevs ; i++) {
+        virDomainHostdevDefPtr hostdev = l_hostdevs[i];
+        libxl_device_pci pcidev;
+
+        if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
+            continue;
+        if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+            continue;
+
+        pcidev.domain = hostdev->source.subsys.u.pci.addr.domain;
+        pcidev.bus = hostdev->source.subsys.u.pci.addr.bus;
+        pcidev.dev = hostdev->source.subsys.u.pci.addr.slot;
+        pcidev.func = hostdev->source.subsys.u.pci.addr.function;
+
+        d_config->pcidevs[d_config->num_pcidevs] = pcidev;
+        d_config->num_pcidevs ++;
+    }
+
+    return 0;
+}
+
 virCapsPtr
 libxlMakeCapabilities(libxl_ctx *ctx)
 {
@@ -766,6 +806,10 @@ libxlBuildDomainConfig(libxlDriverPrivatePtr driver,
         return -1;
     }
 
+    if (libxlMakePciList(def, d_config) < 0) {
+        return -1;
+    }
+
     d_config->on_reboot = def->onReboot;
     d_config->on_poweroff = def->onPoweroff;
     d_config->on_crash = def->onCrash;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index b39e005..d6db98a 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -45,6 +45,7 @@
 #include "virtypedparam.h"
 #include "viruri.h"
 #include "virstring.h"
+#include "virhostdevmanager.h"
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
@@ -685,13 +686,17 @@ libxlVmReap(libxlDriverPrivatePtr driver,
             virDomainShutoffReason reason)
 {
     libxlDomainObjPrivatePtr priv = vm->privateData;
-
+    virHostdevManagerPtr hostdev_mgr;
+ 
     if (libxl_domain_destroy(priv->ctx, vm->def->id, NULL) < 0) {
         virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("Unable to cleanup domain %d"), vm->def->id);
         return -1;
     }
 
+    hostdev_mgr = virHostdevManagerGetDefault();
+    virHostdevManagerReAttachHostdevs(hostdev_mgr, "xenlight", vm->def, VIR_SP_PCI_HOSTDEV);
+
     libxlVmCleanup(driver, vm, reason);
     return 0;
 }
@@ -902,6 +907,7 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
     char *managed_save_path = NULL;
     int managed_save_fd = -1;
     libxlDomainObjPrivatePtr priv = vm->privateData;
+    virHostdevManagerPtr hostdev_mgr;
 
     /* If there is a managed saved state restore it instead of starting
      * from scratch. The old state is removed once the restoring succeeded. */
@@ -956,6 +962,12 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
         goto error;
     }
 
+    VIR_DEBUG("Preparing host PCI devices");
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (virHostdevManagerPrepareHostdevs(hostdev_mgr, "xenlight", vm->def, VIR_SP_PCI_HOSTDEV ) < 0)
+        goto error;
+
+
     /* use as synchronous operations => ao_how = NULL and no intermediate reports => ao_progress = NULL */
 
     if (restore_fd < 0)
@@ -1049,6 +1061,7 @@ libxlReconnectDomain(virDomainObjPtr vm,
     libxl_dominfo d_info;
     int len;
     uint8_t *data = NULL;
+    virHostdevManagerPtr hostdev_mgr;
 
     virObjectLock(vm);
 
@@ -1071,6 +1084,12 @@ libxlReconnectDomain(virDomainObjPtr vm,
 
     /* Update domid in case it changed (e.g. reboot) while we were gone? */
     vm->def->id = d_info.domid;
+
+    /* Update hostdev state */
+    hostdev_mgr = virHostdevManagerGetDefault();
+    if (virHostdevManagerPrepareHostdevs(hostdev_mgr, "xenlight", vm->def, VIR_SP_PCI_HOSTDEV ) < 0)
+        goto out;
+
     virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_UNKNOWN);
 
     if (!driver->nactive && driver->inhibitCallback)
-- 
1.6.0.2




More information about the libvir-list mailing list