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
|