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 2 of 3] xl, implement pci-list-assignable-devices

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH 2 of 3] xl, implement pci-list-assignable-devices
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Tue, 27 Jul 2010 17:24:32 +0100
Cc: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <Stefano.Stabellini@xxxxxxxxxxxxx>
Delivery-date: Tue, 27 Jul 2010 09:31:16 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
In-reply-to: <patchbomb.1280247870@xxxxxxxxxxxxxxxxxxxxxx>
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.1280247870@xxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mercurial-patchbomb/1.4.3
 tools/libxl/libxl.h       |    1 +
 tools/libxl/libxl_pci.c   |  123 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/xl.h          |    1 +
 tools/libxl/xl_cmdimpl.c  |   34 ++++++++++++
 tools/libxl/xl_cmdtable.c |    5 +
 5 files changed, 164 insertions(+), 0 deletions(-)


diff -r 20b2e15131c7 -r 214733749470 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h       Tue Jul 27 17:13:35 2010 +0100
+++ b/tools/libxl/libxl.h       Tue Jul 27 17:17:31 2010 +0100
@@ -496,6 +496,7 @@ int libxl_device_pci_add(struct libxl_ct
 int libxl_device_pci_remove(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev);
 int libxl_device_pci_shutdown(struct libxl_ctx *ctx, uint32_t domid);
 libxl_device_pci *libxl_device_pci_list(struct libxl_ctx *ctx, uint32_t domid, 
int *num);
+libxl_device_pci *libxl_device_pci_list_assignable(struct libxl_ctx *ctx, int 
*num);
 int libxl_device_pci_init(libxl_device_pci *pcidev, unsigned int domain,
                           unsigned int bus, unsigned int dev,
                           unsigned int func, unsigned int vdevfn);
diff -r 20b2e15131c7 -r 214733749470 tools/libxl/libxl_pci.c
--- a/tools/libxl/libxl_pci.c   Tue Jul 27 17:13:35 2010 +0100
+++ b/tools/libxl/libxl_pci.c   Tue Jul 27 17:17:31 2010 +0100
@@ -28,6 +28,7 @@
 #include <unistd.h> /* for write, unlink and close */
 #include <stdint.h>
 #include <inttypes.h>
+#include <dirent.h>
 #include <assert.h>
 
 #include "libxl.h"
@@ -258,6 +259,75 @@ retry_transaction2:
     return 0;
 }
 
+static libxl_device_pci *get_all_assigned_devices(struct libxl_ctx *ctx, int 
*num)
+{
+    libxl_device_pci *new, *pcidevs = NULL;
+    char **domlist;
+    unsigned int nd, i;
+
+    *num = 0;
+
+    domlist = libxl_xs_directory(ctx, XBT_NULL, "/local/domain", &nd);
+    for(i = 0; i < nd; i++) {
+        char *path, *num_devs;
+
+        path = libxl_sprintf(ctx, "/local/domain/0/backend/pci/%s/0/num_devs", 
domlist[i]);
+        num_devs = libxl_xs_read(ctx, XBT_NULL, path);
+        if ( num_devs ) {
+            int ndev = atoi(num_devs), j;
+            char *devpath, *bdf;
+
+            for(j = 0; j < ndev; j++) {
+                devpath = libxl_sprintf(ctx, 
"/local/domain/0/backend/pci/%s/0/dev-%u",
+                                        domlist[i], j);
+                bdf = libxl_xs_read(ctx, XBT_NULL, devpath);
+                if ( bdf ) {
+                    unsigned dom, bus, dev, func;
+                    if ( sscanf(bdf, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
+                        continue;
+
+                    new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
+                    if ( NULL == new )
+                        continue;
+
+                    pcidevs = new;
+                    new = pcidevs + *num;
+
+                    libxl_device_pci_init(new, dom, bus, dev, func, ~0);
+                    (*num)++;
+                }
+                libxl_free(ctx, bdf);
+                libxl_free(ctx, devpath);
+            }
+            libxl_free(ctx, num_devs);
+        }
+        libxl_free(ctx, path);
+    }
+    libxl_free(ctx, domlist);
+
+    return pcidevs;
+}
+
+static int is_assigned(libxl_device_pci *assigned, int num_assigned,
+                       int dom, int bus, int dev, int func)
+{
+    int i;
+
+    for(i = 0; i < num_assigned; i++) {
+        if ( assigned[i].domain != dom )
+            continue;
+        if ( assigned[i].bus != bus )
+            continue;
+        if ( assigned[i].dev != dev )
+            continue;
+        if ( assigned[i].func != func )
+            continue;
+        return 1;
+    }
+
+    return 0;
+}
+
 int libxl_device_pci_add(struct libxl_ctx *ctx, uint32_t domid, 
libxl_device_pci *pcidev)
 {
     char *path;
@@ -466,6 +536,59 @@ out:
     return 0;
 }
 
+static libxl_device_pci *scan_sys_pcidir(libxl_device_pci *pcidevs, 
libxl_device_pci *assigned,
+                                         int num_assigned, const char *path, 
int *num)
+{
+    libxl_device_pci *new;
+    struct dirent *de;
+    DIR *dir;
+
+    dir = opendir(path);
+    if ( NULL == dir )
+        return pcidevs;
+
+    while( (de = readdir(dir)) ) {
+        unsigned dom, bus, dev, func;
+        if ( sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4 )
+            continue;
+
+        if ( is_assigned(assigned, num_assigned, dom, bus, dev, func) )
+            continue;
+
+        new = realloc(pcidevs, ((*num) + 1) * sizeof(*new));
+        if ( NULL == new )
+            continue;
+
+        pcidevs = new;
+        new = pcidevs + *num;
+
+        libxl_device_pci_init(new, dom, bus, dev, func, ~0);
+        (*num)++;
+    }
+
+    closedir(dir);
+    return pcidevs;
+}
+
+libxl_device_pci *libxl_device_pci_list_assignable(struct libxl_ctx *ctx, int 
*num)
+{
+    libxl_device_pci *pcidevs = NULL;
+    libxl_device_pci *assigned;
+    int num_assigned;
+
+    *num = 0;
+
+    assigned = get_all_assigned_devices(ctx, &num_assigned);
+
+    pcidevs = scan_sys_pcidir(pcidevs, assigned, num_assigned,
+                              "/sys/bus/pci/drivers/pciback", num);
+    pcidevs = scan_sys_pcidir(pcidevs, assigned, num_assigned,
+                              "/sys/bus/pci/drivers/pcistub", num);
+
+    free(assigned);
+    return pcidevs;
+}
+
 libxl_device_pci *libxl_device_pci_list(struct libxl_ctx *ctx, uint32_t domid, 
int *num)
 {
     char *be_path, *num_devs, *xsdev, *xsvdevfn, *xsopts;
diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl.h
--- a/tools/libxl/xl.h  Tue Jul 27 17:13:35 2010 +0100
+++ b/tools/libxl/xl.h  Tue Jul 27 17:17:31 2010 +0100
@@ -32,6 +32,7 @@ int main_cd_insert(int argc, char **argv
 int main_console(int argc, char **argv);
 int main_vncviewer(int argc, char **argv);
 int main_pcilist(int argc, char **argv);
+int main_pcilist_assignable(int argc, char **argv);
 int main_pcidetach(int argc, char **argv);
 int main_pciattach(int argc, char **argv);
 int main_restore(int argc, char **argv);
diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Tue Jul 27 17:13:35 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Tue Jul 27 17:17:31 2010 +0100
@@ -1706,6 +1706,40 @@ int main_vncviewer(int argc, char **argv
     exit(0);
 }
 
+void pcilist_assignable(void)
+{
+    libxl_device_pci *pcidevs;
+    int num, i;
+
+    pcidevs = libxl_device_pci_list_assignable(&ctx, &num);
+    if (!num)
+        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);
+    }
+    free(pcidevs);
+}
+
+int main_pcilist_assignable(int argc, char **argv)
+{
+    int opt;
+
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("pci-list-assignable-devices");
+            exit(0);
+        default:
+            fprintf(stderr, "option not supported\n");
+            break;
+        }
+    }
+
+    pcilist_assignable();
+    exit(0);
+}
+
 void pcilist(char *dom)
 {
     libxl_device_pci *pcidevs;
diff -r 20b2e15131c7 -r 214733749470 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Tue Jul 27 17:13:35 2010 +0100
+++ b/tools/libxl/xl_cmdtable.c Tue Jul 27 17:17:31 2010 +0100
@@ -68,6 +68,11 @@ struct cmd_spec cmd_table[] = {
       "List pass-through pci devices for a domain",
       "<Domain>",
     },
+    { "pci-list-assignable-devices",
+      &main_pcilist_assignable,
+      "List all the assignable pci devices",
+      "",
+    },
     { "pause",
       &main_pause,
       "Pause execution of a domain",

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