From: George Dunlap Date: Tue, 15 May 2012 15:28:16 +0000 (+0100) Subject: xl: Add pci_assignable_add and remove commands X-Git-Tag: 4.2.0-rc1~340 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=6596e73b77afdf1daac9dfa78dfba42ed698c92c;p=xen.git xl: Add pci_assignable_add and remove commands pci-assignable-add will always store the driver rebind path, but pci-assignable-remove will only actually rebind if asked to do so. Signed-off-by: George Dunlap Committed-by: Ian Campbell --- diff --git a/docs/man/xl.pod.1 b/docs/man/xl.pod.1 index 2b6e7ac924..e31259b62d 100644 --- a/docs/man/xl.pod.1 +++ b/docs/man/xl.pod.1 @@ -1050,6 +1050,28 @@ These are devices in the system which are configured to be available for passthrough and are bound to a suitable PCI backend driver in domain 0 rather than a real driver. +=item B I + +Make the device at PCI Bus/Device/Function BDF assignable to guests. +This will bind the device to the pciback driver. If it is already +bound to a driver, it will first be unbound, and the original driver +stored so that it can be re-bound to the same driver later if desired. +If the device is already bound, it will return success. + +CAUTION: This will make the device unusable by Domain 0 until it is +returned with pci-assignable-remove. Care should therefore be taken +not to do this on a device critical to domain 0's operation, such as +storage controllers, network interfaces, or GPUs that are currently +being used. + +=item B [I<-r>] I + +Make the device at PCI Bus/Device/Function BDF assignable to guests. This +will at least unbind the device from pciback. If the -r option is specified, +it will also attempt to re-bind the device to its original driver, making it +usable by Domain 0 again. If the device is not bound to pciback, it will +return success. + =item B I I Hot-plug a new pass-through pci device to the specified domain. diff --git a/tools/libxl/xl.h b/tools/libxl/xl.h index f267d9b673..9b4cb259e8 100644 --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -37,6 +37,8 @@ int main_vncviewer(int argc, char **argv); int main_pcilist(int argc, char **argv); int main_pcidetach(int argc, char **argv); int main_pciattach(int argc, char **argv); +int main_pciassignable_add(int argc, char **argv); +int main_pciassignable_remove(int argc, char **argv); int main_pciassignable_list(int argc, char **argv); int main_restore(int argc, char **argv); int main_migrate_receive(int argc, char **argv); diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c index 4f3aec50ac..167b75d7a9 100644 --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -2440,6 +2440,86 @@ int main_pciassignable_list(int argc, char **argv) return 0; } +static void pciassignable_add(const char *bdf, int rebind) +{ + libxl_device_pci pcidev; + XLU_Config *config; + + libxl_device_pci_init(&pcidev); + + config = xlu_cfg_init(stderr, "command line"); + if (!config) { perror("xlu_cfg_init"); exit(-1); } + + if (xlu_pci_parse_bdf(config, &pcidev, bdf)) { + fprintf(stderr, "pci-assignable-add: malformed BDF specification \"%s\"\n", bdf); + exit(2); + } + libxl_device_pci_assignable_add(ctx, &pcidev, rebind); + + libxl_device_pci_dispose(&pcidev); + xlu_cfg_destroy(config); +} + +int main_pciassignable_add(int argc, char **argv) +{ + int opt; + const char *bdf = NULL; + + while ((opt = def_getopt(argc, argv, "", "pci-assignable-add", 1)) != -1) { + switch (opt) { + case 0: case 2: + return opt; + } + } + + bdf = argv[optind]; + + pciassignable_add(bdf, 1); + return 0; +} + +static void pciassignable_remove(const char *bdf, int rebind) +{ + libxl_device_pci pcidev; + XLU_Config *config; + + libxl_device_pci_init(&pcidev); + + config = xlu_cfg_init(stderr, "command line"); + if (!config) { perror("xlu_cfg_init"); exit(-1); } + + if (xlu_pci_parse_bdf(config, &pcidev, bdf)) { + fprintf(stderr, "pci-assignable-remove: malformed BDF specification \"%s\"\n", bdf); + exit(2); + } + libxl_device_pci_assignable_remove(ctx, &pcidev, rebind); + + libxl_device_pci_dispose(&pcidev); + xlu_cfg_destroy(config); +} + +int main_pciassignable_remove(int argc, char **argv) +{ + int opt; + const char *bdf = NULL; + int rebind = 0; + + while ((opt = def_getopt(argc, argv, "r", "pci-assignable-remove", 1)) != -1) { + switch (opt) { + case 0: case 2: + return opt; + case 'r': + rebind=1; + break; + } + } + + bdf = argv[optind]; + + pciassignable_remove(bdf, rebind); + return 0; +} + static void pause_domain(const char *p) { find_domain(p); diff --git a/tools/libxl/xl_cmdtable.c b/tools/libxl/xl_cmdtable.c index 193d6a3a46..896b3990a6 100644 --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -89,6 +89,20 @@ struct cmd_spec cmd_table[] = { "List pass-through pci devices for a domain", "", }, + { "pci-assignable-add", + &main_pciassignable_add, 0, 1, + "Make a device assignable for pci-passthru", + "", + "-h Print this help.\n" + }, + { "pci-assignable-remove", + &main_pciassignable_remove, 0, 1, + "Remove a device from being assignable", + "[options] ", + "-h Print this help.\n" + "-r Attempt to re-assign the device to the\n" + " original driver" + }, { "pci-assignable-list", &main_pciassignable_list, 0, 0, "List all the assignable pci devices",