Add pci passthrough implementation to libxl driver, using hostdev common library.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
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