Support PCI passthrough in libxl driver.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
src/libxl/libxl_conf.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_conf.h | 5 ++++-
src/libxl/libxl_driver.c | 16 ++++++++++++++++
3 files changed, 64 insertions(+), 1 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 2705e65..223f7cb 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -814,6 +814,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.domain;
+ pcidev.bus = hostdev->source.subsys.u.pci.bus;
+ pcidev.dev = hostdev->source.subsys.u.pci.slot;
+ pcidev.func = hostdev->source.subsys.u.pci.function;
+
+ d_config->pcidevs[d_config->num_pcidevs] = pcidev;
+ d_config->num_pcidevs ++;
+ }
+
+ return 0;
+}
+
virCapsPtr
libxlMakeCapabilities(libxl_ctx *ctx)
{
@@ -863,6 +903,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 c8808a1..704d8b8 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -35,7 +35,7 @@
# include "capabilities.h"
# include "configmake.h"
# include "virbitmap.h"
-
+# include "pci.h"
# define LIBXL_VNC_PORT_MIN 5900
# define LIBXL_VNC_PORT_MAX 65535
@@ -76,6 +76,9 @@ struct _libxlDriverPrivate {
char *stateDir;
char *libDir;
char *saveDir;
+
+ pciDeviceList *activePciHostdevs;
+ pciDeviceList *inactivePciHostdevs;
};
typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index a956188..4670fee 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -42,6 +42,7 @@
#include "libxl.h"
#include "libxl_driver.h"
#include "libxl_conf.h"
+#include "libxl_hostdev.h"
#include "xen_xm.h"
#include "virtypedparam.h"
#include "viruri.h"
@@ -514,6 +515,8 @@ libxlVmReap(libxlDriverPrivatePtr driver,
return -1;
}
+ libxlDomainReAttachHostDevices(driver, vm->def);
+
libxlVmCleanup(driver, vm, reason);
return 0;
}
@@ -756,6 +759,10 @@ libxlVmStart(libxlDriverPrivatePtr driver, virDomainObjPtr vm,
VIR_FREE(managed_save_path);
}
+ VIR_DEBUG("Preparing host PCI devices");
+ if (libxlPrepareHostDevices(driver, vm->def) < 0)
+ goto error;
+
libxl_domain_config_init(&d_config);
if (libxlBuildDomainConfig(driver, vm->def, &d_config) < 0)
@@ -931,6 +938,8 @@ libxlShutdown(void)
VIR_FREE(libxl_driver->stateDir);
VIR_FREE(libxl_driver->libDir);
VIR_FREE(libxl_driver->saveDir);
+ pciDeviceListFree(libxl_driver->activePciHostdevs);
+ pciDeviceListFree(libxl_driver->inactivePciHostdevs);
virDomainEventStateFree(libxl_driver->domainEventState);
@@ -1077,6 +1086,12 @@ libxlStartup(bool privileged,
libxl_driver->caps->privateDataAllocFunc = libxlDomainObjPrivateAlloc;
libxl_driver->caps->privateDataFreeFunc = libxlDomainObjPrivateFree;
+ if ((libxl_driver->activePciHostdevs = pciDeviceListNew()) == NULL)
+ goto error;
+
+ if ((libxl_driver->inactivePciHostdevs = pciDeviceListNew()) == NULL)
+ goto error;
+
/* Load running domains first. */
if (virDomainLoadAllConfigs(libxl_driver->caps,
&libxl_driver->domains,
@@ -1549,6 +1564,7 @@ libxlDomainShutdownFlags(virDomainPtr dom, unsigned int flags)
/* vm is marked shutoff (or removed from domains list if not persistent)
* in shutdown event handler.
*/
+ libxlDomainReAttachHostDevices(driver, vm->def);
ret = 0;
cleanup:
--
1.7.3.4