WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH 23 of 23] libxl: convert PCI device handling to devic

To: xen-devel@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] [PATCH 23 of 23] libxl: convert PCI device handling to device API
From: Ian Campbell <ian.campbell@xxxxxxxxxx>
Date: Fri, 30 Sep 2011 14:33:36 +0100
Cc: Jim Fehlig <jfehlig@xxxxxxxxxx>, Mike McClurg <mike.mcclurg@xxxxxxxxxx>, Dave Scott <Dave.Scott@xxxxxxxxxxxxx>, Jonathan Ludlam <Jonathan.Ludlam@xxxxxxxxxxxxx>
Delivery-date: Fri, 30 Sep 2011 07:03:10 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1317389593@xxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <patchbomb.1317389593@xxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.6.4
# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxx>
# Date 1317389278 -3600
# Node ID f0ab7f2102b37968da2181825ac492b14bc4b449
# Parent  dc967a4691d5a7e05eac3522ab78c573a084b63c
libxl: convert PCI device handling to device API

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>

diff -r dc967a4691d5 -r f0ab7f2102b3 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c       Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/libxl/libxl.c       Fri Sep 30 14:27:58 2011 +0100
@@ -754,7 +754,7 @@ int libxl_domain_destroy(libxl_ctx *ctx,
         goto out;
     }
 
-    if (libxl_device_pci_shutdown(ctx, domid) < 0)
+    if (libxl__device_pci_force_remove_all(&gc, domid) < 0)
         LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "pci shutdown failed for domid %d", 
domid);
     rc = xc_domain_pause(ctx->xch, domid);
     if (rc < 0) {
diff -r dc967a4691d5 -r f0ab7f2102b3 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/libxl/libxl.h       Fri Sep 30 14:27:58 2011 +0100
@@ -498,12 +498,28 @@ int libxl_device_vfb_add(libxl_ctx *ctx,
 int libxl_device_vfb_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_vfb 
*vfb);
 int libxl_device_vfb_force_remove(libxl_ctx *ctx, uint32_t domid, 
libxl_device_vfb *vfb);
 
+/* PCI Passthrough */
+int libxl_device_pci_init(libxl_ctx *ctx, libxl_device_pci *pci);
 int libxl_device_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev);
-int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev, int force);
-int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid);
-int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, 
uint32_t domid, int *num);
-int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, 
int *num);
-int libxl_device_pci_parse_bdf(libxl_ctx *ctx, libxl_device_pci *pcidev, const 
char *str);
+int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev);
+int libxl_device_pci_force_remove(libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev);
+libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int 
*num);
+
+/*
+ * Parse a PCI BDF into a PCI device structure.
+ */
+int libxl_device_pci_parse_bdf(libxl_ctx *ctx,
+                               libxl_device_pci *pcidev,
+                               const char *str);
+
+/*
+ * Similar to libxl_device_pci_list but returns all devices which
+ * could be assigned to a domain (i.e. are bound to the backend
+ * driver) but are not currently.
+ */
+libxl_device_pci *libxl_device_pci_list_assignable(libxl_ctx *ctx, int *num);
+
+/* CPUID handling */
 int libxl_cpuid_parse_config(libxl_cpuid_policy_list *cpuid, const char* str);
 int libxl_cpuid_parse_config_xend(libxl_cpuid_policy_list *cpuid,
                                   const char* str);
diff -r dc967a4691d5 -r f0ab7f2102b3 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h      Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/libxl/libxl_internal.h      Fri Sep 30 14:27:58 2011 +0100
@@ -252,6 +252,7 @@ _hidden int libxl__wait_for_backend(libx
 _hidden int libxl__device_pci_add(libxl__gc *gc, uint32_t domid, 
libxl_device_pci *pcidev, int starting);
 _hidden int libxl__create_pci_backend(libxl__gc *gc, uint32_t domid,
                                       libxl_device_pci *pcidev, int num);
+_hidden int libxl__device_pci_force_remove_all(libxl__gc *gc, uint32_t domid);
 
 /* xl_exec */
 
diff -r dc967a4691d5 -r f0ab7f2102b3 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/libxl/libxl_pci.c   Fri Sep 30 14:27:58 2011 +0100
@@ -486,7 +486,7 @@ static int is_assigned(libxl_device_pci 
     return 0;
 }
 
-int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, 
int *num)
+libxl_device_pci *libxl_device_pci_list_assignable(libxl_ctx *ctx, int *num)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
     libxl_device_pci *pcidevs = NULL, *new, *assigned;
@@ -495,13 +495,10 @@ int libxl_device_pci_list_assignable(lib
     int rc, num_assigned;
 
     *num = 0;
-    *list = NULL;
 
     rc = get_all_assigned_devices(&gc, &assigned, &num_assigned);
-    if ( rc ) {
-        libxl__free_all(&gc);
-        return rc;
-    }
+    if ( rc )
+        goto out;
 
     dir = opendir(SYSFS_PCIBACK_DRIVER);
     if ( NULL == dir ) {
@@ -510,8 +507,7 @@ int libxl_device_pci_list_assignable(lib
         }else{
             LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "Couldn't open %s", 
SYSFS_PCIBACK_DRIVER);
         }
-        libxl__free_all(&gc);
-        return ERROR_FAIL;
+        goto out_closedir;
     }
 
     while( (de = readdir(dir)) ) {
@@ -534,10 +530,11 @@ int libxl_device_pci_list_assignable(lib
         (*num)++;
     }
 
+out_closedir:
     closedir(dir);
-    *list = pcidevs;
+out:
     libxl__free_all(&gc);
-    return 0;
+    return pcidevs;
 }
 
 /*
@@ -846,21 +843,25 @@ static int do_pci_remove(libxl__gc *gc, 
     int hvm = 0, rc, num;
     int stubdomid = 0;
 
-    if ( !libxl_device_pci_list_assigned(ctx, &assigned, domid, &num) ) {
-        if ( !is_assigned(assigned, num, pcidev->domain,
-                         pcidev->bus, pcidev->dev, pcidev->func) ) {
-            LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "PCI device not attached to this 
domain");
-            return ERROR_INVAL;
-        }
+    assigned = libxl_device_pci_list(ctx, domid, &num);
+    if ( assigned == NULL )
+        return ERROR_FAIL;
+
+    rc = ERROR_INVAL;
+    if ( !is_assigned(assigned, num, pcidev->domain,
+                      pcidev->bus, pcidev->dev, pcidev->func) ) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "PCI device not attached to this 
domain");
+        goto out_fail;
     }
 
+    rc = ERROR_FAIL;
     switch (libxl__domain_type(gc, domid)) {
     case LIBXL_DOMAIN_TYPE_HVM:
         hvm = 1;
         if (libxl__wait_for_device_model(gc, domid, "running",
-                                         NULL, NULL, NULL) < 0) {
-            return ERROR_FAIL;
-        }
+                                         NULL, NULL, NULL) < 0)
+            goto out_fail;
+
         path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
         state = libxl__xs_read(gc, XBT_NULL, path);
         path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/parameter", 
domid);
@@ -879,7 +880,7 @@ static int do_pci_remove(libxl__gc *gc, 
                  * SCI, if it doesn't respond in time then we may wish to
                  * force the removal.
                  */
-                return ERROR_FAIL;
+                goto out_fail;
             }
         }
         path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", 
domid);
@@ -955,25 +956,31 @@ out:
     stubdomid = libxl_get_stubdom_id(ctx, domid);
     if (stubdomid != 0) {
         libxl_device_pci pcidev_s = *pcidev;
-        libxl_device_pci_remove(ctx, stubdomid, &pcidev_s, force);
+        if (force)
+                libxl_device_pci_force_remove(ctx, stubdomid, &pcidev_s);
+        else
+                libxl_device_pci_remove(ctx, stubdomid, &pcidev_s);
     }
 
     libxl__device_pci_remove_xenstore(gc, domid, pcidev);
 
-    return 0;
+    rc = 0;
+out_fail:
+    free(assigned);
+    return rc;
+
 }
 
-int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid,
-                            libxl_device_pci *pcidev, int force)
+static int libxl__device_pci_remove_common(libxl__gc *gc, uint32_t domid,
+                                           libxl_device_pci *pcidev, int force)
 {
-    libxl__gc gc = LIBXL_INIT_GC(ctx);
     unsigned int orig_vdev, pfunc_mask;
     int i, rc;
 
     orig_vdev = pcidev->vdevfn & ~7U;
 
     if ( pcidev->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
-        if ( pci_multifunction_check(&gc, pcidev, &pfunc_mask) ) {
+        if ( pci_multifunction_check(gc, pcidev, &pfunc_mask) ) {
             rc = ERROR_FAIL;
             goto out;
         }
@@ -990,81 +997,118 @@ int libxl_device_pci_remove(libxl_ctx *c
             }else{
                 pcidev->vdevfn = orig_vdev;
             }
-            if ( do_pci_remove(&gc, domid, pcidev, force) )
+            if ( do_pci_remove(gc, domid, pcidev, force) )
                 rc = ERROR_FAIL;
         }
     }
 
 out:
+    return rc;
+}
+
+int libxl_device_pci_remove(libxl_ctx *ctx, uint32_t domid, libxl_device_pci 
*pcidev)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int rc;
+
+    rc = libxl__device_pci_remove_common(&gc, domid, pcidev, 0);
+
     libxl__free_all(&gc);
     return rc;
 }
 
-int libxl_device_pci_list_assigned(libxl_ctx *ctx, libxl_device_pci **list, 
uint32_t domid, int *num)
+int libxl_device_pci_force_remove(libxl_ctx *ctx, uint32_t domid,
+                                  libxl_device_pci *pcidev)
 {
     libxl__gc gc = LIBXL_INIT_GC(ctx);
-    char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
+    int rc;
+
+    rc = libxl__device_pci_remove_common(&gc, domid, pcidev, 1);
+
+    libxl__free_all(&gc);
+    return rc;
+}
+
+static void libxl__device_pci_from_xs_be(libxl__gc *gc,
+                                         const char *be_path,
+                                         libxl_device_pci *pci,
+                                         int nr)
+{
+    char *s;
+    unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
+
+    s = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/dev-%d", be_path, 
nr));
+    sscanf(s, PCI_BDF, &domain, &bus, &dev, &func);
+
+    s = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/vdevfn-%d", 
be_path, nr));
+    if (s)
+        vdevfn = strtol(s, (char **) NULL, 16);
+
+    pcidev_init(pci, domain, bus, dev, func, vdevfn);
+
+    s = libxl__xs_read(gc, XBT_NULL, libxl__sprintf(gc, "%s/opts-%d", be_path, 
nr));
+    if (s) {
+        char *saveptr;
+        char *p = strtok_r(s, ",=", &saveptr);
+        do {
+            while (*p == ' ')
+                p++;
+            if (!strcmp(p, "msitranslate")) {
+                p = strtok_r(NULL, ",=", &saveptr);
+                pci->msitranslate = atoi(p);
+            } else if (!strcmp(p, "power_mgmt")) {
+                p = strtok_r(NULL, ",=", &saveptr);
+                pci->power_mgmt = atoi(p);
+            }
+        } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
+    }
+}
+
+libxl_device_pci *libxl_device_pci_list(libxl_ctx *ctx, uint32_t domid, int 
*num)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char *be_path, *num_devs;
     int n, i;
-    unsigned int domain = 0, bus = 0, dev = 0, func = 0, vdevfn = 0;
-    libxl_device_pci *pcidevs;
+    libxl_device_pci *pcidevs = NULL;
+
+    *num = 0;
 
     be_path = libxl__sprintf(&gc, "%s/backend/pci/%d/0", 
libxl__xs_get_dompath(&gc, 0), domid);
     num_devs = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, 
"%s/num_devs", be_path));
-    if (!num_devs) {
-        *num = 0;
-        *list = NULL;
-        libxl__free_all(&gc);
-        return 0;
-    }
+    if (!num_devs)
+        goto out;
+
     n = atoi(num_devs);
     pcidevs = calloc(n, sizeof(libxl_device_pci));
+
+    for (i = 0; i < n; i++)
+        libxl__device_pci_from_xs_be(&gc, be_path, pcidevs + i, i);
+
     *num = n;
-
-    for (i = 0; i < n; i++) {
-        xsdev = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/dev-%d", 
be_path, i));
-        sscanf(xsdev, PCI_BDF, &domain, &bus, &dev, &func);
-        xsvdevfn = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, 
"%s/vdevfn-%d", be_path, i));
-        if (xsvdevfn)
-            vdevfn = strtol(xsvdevfn, (char **) NULL, 16);
-        pcidev_init(pcidevs + i, domain, bus, dev, func, vdevfn);
-        xsopts = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, 
"%s/opts-%d", be_path, i));
-        if (xsopts) {
-            char *saveptr;
-            char *p = strtok_r(xsopts, ",=", &saveptr);
-            do {
-                while (*p == ' ')
-                    p++;
-                if (!strcmp(p, "msitranslate")) {
-                    p = strtok_r(NULL, ",=", &saveptr);
-                    pcidevs[i].msitranslate = atoi(p);
-                } else if (!strcmp(p, "power_mgmt")) {
-                    p = strtok_r(NULL, ",=", &saveptr);
-                    pcidevs[i].power_mgmt = atoi(p);
-                }
-            } while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
-        }
-    }
-    *list = pcidevs;
+out:
     libxl__free_all(&gc);
-    return 0;
+    return pcidevs;
 }
 
-int libxl_device_pci_shutdown(libxl_ctx *ctx, uint32_t domid)
+int libxl__device_pci_force_remove_all(libxl__gc *gc, uint32_t domid)
 {
+    libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *pcidevs;
-    int num, i, rc;
+    int num, i, rc = 0;
 
-    rc = libxl_device_pci_list_assigned(ctx, &pcidevs, domid, &num);
-    if ( rc )
-        return rc;
+    pcidevs = libxl_device_pci_list(ctx, domid, &num);
+    if ( pcidevs == NULL )
+        return ERROR_FAIL;
+
     for (i = 0; i < num; i++) {
         /* Force remove on shutdown since, on HVM, qemu will not always
          * respond to SCI interrupt because the guest kernel has shut down the
          * devices by the time we even get here!
          */
-        if (libxl_device_pci_remove(ctx, domid, pcidevs + i, 1) < 0)
-            return ERROR_FAIL;
+        if (libxl_device_pci_force_remove(ctx, domid, pcidevs + i) < 0)
+            rc = ERROR_FAIL;
     }
+
     free(pcidevs);
     return 0;
 }
diff -r dc967a4691d5 -r f0ab7f2102b3 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Fri Sep 30 14:27:58 2011 +0100
@@ -2078,11 +2078,14 @@ static void pcilist_assignable(void)
     libxl_device_pci *pcidevs;
     int num, i;
 
-    if ( libxl_device_pci_list_assignable(ctx, &pcidevs, &num) )
+    pcidevs = libxl_device_pci_list_assignable(ctx, &num);
+
+    if ( pcidevs == NULL )
         return;
     for (i = 0; i < num; i++) {
         printf("%04x:%02x:%02x.%01x\n",
-                pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, 
pcidevs[i].func);
+               pcidevs[i].domain, pcidevs[i].bus, pcidevs[i].dev, 
pcidevs[i].func);
+        libxl_device_pci_destroy(&pcidevs[i]);
     }
     free(pcidevs);
 }
@@ -2105,7 +2108,8 @@ static void pcilist(const char *dom)
 
     find_domain(dom);
 
-    if (libxl_device_pci_list_assigned(ctx, &pcidevs, domid, &num))
+    pcidevs = libxl_device_pci_list(ctx, domid, &num);
+    if (pcidevs == NULL)
         return;
     printf("Vdev Device\n");
     for (i = 0; i < num; i++) {
@@ -2142,7 +2146,10 @@ static void pcidetach(const char *dom, c
         fprintf(stderr, "pci-detach: malformed BDF specification \"%s\"\n", 
bdf);
         exit(2);
     }
-    libxl_device_pci_remove(ctx, domid, &pcidev, force);
+    if (force)
+        libxl_device_pci_force_remove(ctx, domid, &pcidev);
+    else
+        libxl_device_pci_remove(ctx, domid, &pcidev);
     libxl_device_pci_destroy(&pcidev);
 }
 
diff -r dc967a4691d5 -r f0ab7f2102b3 tools/python/xen/lowlevel/xl/xl.c
--- a/tools/python/xen/lowlevel/xl/xl.c Fri Sep 30 14:27:28 2011 +0100
+++ b/tools/python/xen/lowlevel/xl/xl.c Fri Sep 30 14:27:58 2011 +0100
@@ -521,9 +521,16 @@ static PyObject *pyxl_pci_del(XlObject *
         return NULL;
     }
     pci = (Py_device_pci *)obj;
-    if ( libxl_device_pci_remove(self->ctx, domid, &pci->obj, force) ) {
-        PyErr_SetString(xl_error_obj, "cannot remove pci device");
-        return NULL;
+    if ( force ) {
+        if ( libxl_device_pci_force_remove(self->ctx, domid, &pci->obj) ) {
+            PyErr_SetString(xl_error_obj, "cannot remove pci device");
+            return NULL;
+        }
+    } else {
+        if ( libxl_device_pci_remove(self->ctx, domid, &pci->obj) ) {
+            PyErr_SetString(xl_error_obj, "cannot remove pci device");
+            return NULL;
+        }
     }
     Py_INCREF(Py_None);
     return Py_None;
@@ -558,7 +565,8 @@ static PyObject *pyxl_pci_list_assignabl
     PyObject *list;
     int nr_dev, i;
 
-    if ( libxl_device_pci_list_assignable(self->ctx, &dev, &nr_dev) ) {
+    dev = libxl_device_pci_list_assignable(self->ctx, &nr_dev);
+    if ( dev == NULL ) {
         PyErr_SetString(xl_error_obj, "Cannot list assignable devices");
         return NULL;
     }
@@ -594,7 +602,8 @@ static PyObject *pyxl_pci_list(XlObject 
     if ( !PyArg_ParseTuple(args, "i", &domid) )
         return NULL;
 
-    if ( libxl_device_pci_list_assigned(self->ctx, &dev, domid, &nr_dev) ) {
+    dev = libxl_device_pci_list(self->ctx, domid, &nr_dev);
+    if ( dev == NULL ) {
         PyErr_SetString(xl_error_obj, "Cannot list assignable devices");
         return NULL;
     }

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel