]> xenbits.xensource.com Git - xen.git/commitdiff
libxl: passthrough: avoid passing through devices not owned by pciback
authorXudong Hao <xudong.hao@intel.com>
Wed, 25 Apr 2012 10:18:45 +0000 (11:18 +0100)
committerXudong Hao <xudong.hao@intel.com>
Wed, 25 Apr 2012 10:18:45 +0000 (11:18 +0100)
This patch makes sure the passthrough device belongs to pciback before
allow them passthrough to the guest.  There are still many other
checks missing.

xm terminates the guest startup process when this type of condition is
found.  This patch just allows the guest to continue to boot but with
no device passthrough.

Signed-off-by: Allen Kay <allen.m.kay@intel.com>
Signed-off-by: Xudong Hao <xudong.hao@intel.com>
Acked-by: Ian Jackson <ian.jackson@eu.citrix.com>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
tools/libxl/libxl_pci.c

index e8b88398478963216de6a202984d1d5b2fae7fad..3856bd99e7dcb3fd32b7f0f221f3fee3b08b9a20 100644 (file)
@@ -664,6 +664,24 @@ int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcide
     return rc;
 }
 
+static int libxl_pcidev_assignable(libxl_ctx *ctx, libxl_device_pci *pcidev)
+{
+    libxl_device_pci *pcidevs;
+    int num, i;
+
+    pcidevs = libxl_device_pci_list_assignable(ctx, &num);
+    for (i = 0; i < num; i++) {
+        if (pcidevs[i].domain == pcidev->domain &&
+            pcidevs[i].bus == pcidev->bus &&
+            pcidevs[i].dev == pcidev->dev &&
+            pcidevs[i].func == pcidev->func)
+        {
+            return 1;
+        }
+    }
+    return 0;
+}
+
 int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
@@ -675,6 +693,13 @@ int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcide
     rc = libxl__device_pci_setdefault(gc, pcidev);
     if (rc) goto out;
 
+    if (!libxl_pcidev_assignable(ctx, pcidev)) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "PCI device %x:%x:%x.%x is not assignable",
+                   pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func);
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
     rc = get_all_assigned_devices(gc, &assigned, &num_assigned);
     if ( rc ) {
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot determine if device is assigned, refusing to continue");