Add commands to automatically prep devices for pass-through
PATCH v3 1/1 Add commands to automatically prep devices for pass-through
Add commands to automatically prep devices for pass-through
The current method for passing through devices requires users to either modify cryptic Linux boot parameters and reboot, or do a lot of manual reads and writes into sysfs nodes.
This set of patches introduces commands to make this easier. It expands on the concept of "assignable" (from the list_assignable_devices command).
The new xl commands are:
pci_assignable_add: Make a device assignable to guests. This involves unbinding the device from its old driver, creating a slot for it in pciback (if necessary), and binding it to pciback.
pci_assignable_list: List devices assignable to guests. Just renamed from pci_list_assignable.
pci_assignable_remove: Make the device no longer assignable to guests. This involves unbinding the device from pciback and removing the slot. It optionally involves rebinding the device to the driver from which we stole it.
PATCH v3 1/1 libxl: Make a helper function write a BDF to a sysfs path
This functionality will be used several times in subsequent patches.
tools/libxl/libxl_pci.c +34 -19
@@ -327,6 +327,36 @@ static int is_pcidev_in_array(libxl_devireturn 0 ; } +/* Write the standard BDF into the sysfs path given by sysfs_path. */ +static int sysfs_write_bdf (libxl__gc *gc,const char * sysfs_path, +libxl_device_pci *pcidev) +{ +libxl_ctx *ctx =libxl__gc_owner (gc); +int rc, fd; +char *buf; + + fd =open (sysfs_path,O_WRONLY ); +if (fd <0 ) { +LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"Couldn't open %s" , + sysfs_path); +return ERROR_FAIL ; + } + + buf =libxl__sprintf (gc,PCI_BDF , pcidev->domain, pcidev->bus, + pcidev->dev, pcidev->func); + rc =write (fd, buf,strlen (buf)); +/* Annoying to have two if's, but we need the errno */ +if (rc <0 ) +LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR , +"write to %s returned %d" , sysfs_path, rc); +close (fd); + +if (rc <0 ) +return ERROR_FAIL ; + +return 0 ; +} +libxl_device_pci *libxl_device_pci_list_assignable (libxl_ctx *ctx,int *num) {GC_INIT (ctx);
@@ -571,27 +601,12 @@ static int do_pci_add(libxl__gc *gc, uin/* Don't restrict writes to the PCI config space from this VM */ if (pcidev->permissive) { -int fd; -char *buf; - - sysfs_path =libxl__sprintf (gc,SYSFS_PCIBACK_DRIVER "/permissive" ); - fd =open (sysfs_path,O_WRONLY ); -if (fd <0 ) { -LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR ,"Couldn't open %s" , - sysfs_path); +if (sysfs_write_bdf (gc,SYSFS_PCIBACK_DRIVER "/permissive" , + pcidev) <0 ) { +LIBXL__LOG (ctx,LIBXL__LOG_ERROR , +"Setting permissive for device" );return ERROR_FAIL ; } - - buf =libxl__sprintf (gc,PCI_BDF , pcidev->domain, pcidev->bus, - pcidev->dev, pcidev->func); - rc =write (fd, buf,strlen (buf)); -/* Annoying to have two if's, but we need the errno */ -if (rc <0 ) -LIBXL__LOG_ERRNO (ctx,LIBXL__LOG_ERROR , -"write to %s returned %d" , sysfs_path, rc); -close (fd); -if (rc <0 ) -return ERROR_FAIL ; }break ; }
PATCH v3 1/1 libxl: Rename pci_list_assignable to pci_assignable_list
In reply to George Dunlap...to prepare for a consistent "pci_assignable_*" naming scheme.
Also move the man page entry into the PCI PASS-THROUGH section, rather than the XEN HOST section.
No functional changes.
v3:
- Port to xen-unstable tip
docs/man/xl.pod.1 +7 -7
@@ -693,13 +693,6 @@ explanatory. Prints the current uptime of the domains running. -=item B<pci-list-assignable-devices> - -List all the assignable PCI devices. -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. - =back =head1 SCHEDULER SUBCOMMANDS
@@ -1032,6 +1025,13 @@ List virtual network interfaces for a do =over 4 +=item B<pci-assignable-list> + +List all the assignable PCI devices. +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<pci-attach> I<domain-id> I<BDF> Hot-plug a new pass-through pci device to the specified domain.
tools/libxl/libxl.h +1 -1
@@ -722,7 +722,7 @@ libxl_device_pci *libxl_device_pci_list(* 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); +libxl_device_pci *libxl_device_pci_assignable_list (libxl_ctx *ctx,int *num);/* CPUID handling */ int libxl_cpuid_parse_config (libxl_cpuid_policy_list *cpuid,const char * str);
tools/libxl/libxl_pci.c +2 -2
@@ -357,7 +357,7 @@ static int sysfs_write_bdf(libxl__gc *gcreturn 0 ; } -libxl_device_pci *libxl_device_pci_list_assignable (libxl_ctx *ctx,int *num) +libxl_device_pci *libxl_device_pci_assignable_list (libxl_ctx *ctx,int *num) {GC_INIT (ctx);libxl_device_pci *pcidevs =NULL , *new, *assigned;
@@ -684,7 +684,7 @@ static int libxl_pcidev_assignable(libxllibxl_device_pci *pcidevs;int num, i; - pcidevs =libxl_device_pci_list_assignable (ctx, &num); + pcidevs =libxl_device_pci_assignable_list (ctx, &num);for (i =0 ; i < num; i++) { if (pcidevs[i].domain == pcidev->domain && pcidevs[i].bus == pcidev->bus &&
tools/libxl/xl.h +1 -1
@@ -35,9 +35,9 @@ int main_cd_insert(int argc, char **argvint 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_pciassignable_list (int argc,char **argv);int main_restore (int argc,char **argv);int main_migrate_receive (int argc,char **argv);int main_save (int argc,char **argv);
tools/libxl/xl_cmdimpl.c +28 -28
68 lines not on this page · raw message
tools/libxl/xl_cmdtable.c +2 -2
@@ -86,8 +86,8 @@ struct cmd_spec cmd_table[] = {"List pass-through pci devices for a domain" ,"<Domain>" , }, - { "pci-list-assignable-devices", - &main_pcilist_assignable,0 ,0 , + { "pci-assignable-list", + &main_pciassignable_list,0 ,0 ,"List all the assignable pci devices" , "", },
tools/python/xen/lowlevel/xl/xl.c +4 -4
@@ -566,13 +566,13 @@ static PyObject *pyxl_pci_parse(XlObjectreturn (PyObject *)pci; } -static PyObject *pyxl_pci_list_assignable (XlObject *self,PyObject *args) +static PyObject *pyxl_pci_assignable_list (XlObject *self,PyObject *args) {libxl_device_pci *dev;PyObject *list;int nr_dev, i; - dev =libxl_device_pci_list_assignable (self->ctx, &nr_dev); + dev =libxl_device_pci_assignable_list (self->ctx, &nr_dev);if ( dev ==NULL ) {PyErr_SetString (xl_error_obj,"Cannot list assignable devices" );return NULL ;
@@ -662,8 +662,8 @@ static PyMethodDef pyxl_methods[] = { "Parse pass-through PCI device spec (BDF)"}, {"device_pci_list" , (PyCFunction )pyxl_pci_list,METH_VARARGS , "List PCI devices assigned to a domain"}, - {"device_pci_list_assignable", - (PyCFunction )pyxl_pci_list_assignable,METH_NOARGS , + {"device_pci_assignable_list", + (PyCFunction )pyxl_pci_assignable_list,METH_NOARGS , "List assignable PCI devices"}, { NULL, NULL, 0, NULL } };
PATCH v3 1/1 libxl: Introduce pci_assignable_add and pci_assignable_remove
In reply to George DunlapIntroduce libxl helper functions to prepare devices to be passed through to guests. This is meant to replace of all the manual sysfs commands which are currently required.
pci_assignable_add accepts a BDF for a device and will:
* Unbind a device from its current driver, if any
* If "rebind" is set, it will store the path of the driver from which we unplugged it in /libxl/pciback/$BDF/driver_path
* If create a slot for it in pciback if one doesn't yet exist
* Bind the device to pciback
At this point it will show up in pci_assignable_list, and is ready to be passed through to a guest.
pci_assignable_remove accepts a BDF for a device and will:
* Unbind the device from pciback
* Remove the slot from pciback
* If "rebind" is set, and /libx/pciback/$BDF/driver_path exists, it will attempt to rebind the device to its original driver.
Both functions are idempotent: if the desired end state has already been reached, they return SUCCESS.
NB that "$BDF" in this case uses '-' instead of ':' and '.', because ':' and '.' are illegal characters in xenstore paths.
v2:
- sysfs_dev_unbind uses a local var for the path pointer, and sets only at the end
- Actually read pci domain when looking at slots, instead of assuming 0000
- Call LOG_ERRNO after failed sysfs_write_bdf calls, rather than just LOG
- Removed stray FIXME
- Made xenstore reads and writes single operations, and removed transaction infrastructure
- Wrapped a couple of lines that were above 80 characters
- Added a comment explaining the patch's treatment of slots
- Clarified patch description of when it creates slots
v3:
- Fix bug in pciback_dev_has_slot() introduced in v2.
- Raise loglevel to WARNING when pci device is already assigned
- Update comment in libxl.h to make add and remove explicitly idempotent
tools/libxl/libxl.h +22 -3
@@ -718,10 +718,29 @@ int libxl_device_pci_destroy(libxl_ctx *libxl_device_pci *libxl_device_pci_list (libxl_ctx *ctx,uint32_t domid,int *num);/* -* 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. +* Functions related to making devices assignable -- that is, bound to +* the pciback driver, ready to be given to a guest via +* libxl_pci_device_add. +* +* - ..._add() will unbind the device from its current driver (if +* already bound) and re-bind it to pciback; at that point it will be +* ready to be assigned to a VM. If rebind is set, it will store the +* path to the old driver in xenstore so that it can be handed back to +* dom0 on restore. +* +* - ..._remove() will unbind the device from pciback, and if +* rebind is non-zero, attempt to assign it back to the driver +* from whence it came. +* +* - ..._list() will return a list of the PCI devices available to be +* assigned. +* +* add and remove are idempotent: if the device in question is already +* added or is not bound, the functions will emit a warning but return +* SUCCESS. */ +int libxl_device_pci_assignable_add (libxl_ctx *ctx,libxl_device_pci *pcidev,int rebind); +int libxl_device_pci_assignable_remove (libxl_ctx *ctx,libxl_device_pci *pcidev,int rebind);libxl_device_pci *libxl_device_pci_assignable_list (libxl_ctx *ctx,int *num);/* CPUID handling */
tools/libxl/libxl_pci.c +329 -0
341 lines not on this page · raw message
PATCH v3 1/1 xl: Add pci_assignable_add and remove commands
In reply to George Dunlappci-assignable-add will always store the driver rebind path, but pci-assignable-remove will only actually rebind if asked to do so.
v2:
- Use libxl_device_pci_init() instead of memset()
- Call xlu_cfg_destroy() properly
v3:
- Fix typo in failure message
- Specify idempotence in manpage
- Mark add/remove as commands which modify state
docs/man/xl.pod.1 +22 -0
@@ -1032,6 +1032,28 @@ These are devices in the system which ar available for passthrough and are bound to a suitable PCI backend driver in domain 0 rather than a real driver. +=item B<pci-assignable-add> I<BDF> + +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<pci-assignable-remove> [I<-r>] I<BDF> + +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<pci-attach> I<domain-id> I<BDF> Hot-plug a new pass-through pci device to the specified domain.
tools/libxl/xl.h +2 -0
@@ -37,6 +37,8 @@ int main_vncviewer(int argc, char **argvint 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);
tools/libxl/xl_cmdimpl.c +80 -0
86 lines not on this page · raw message
tools/libxl/xl_cmdtable.c +14 -0
@@ -86,6 +86,20 @@ struct cmd_spec cmd_table[] = {"List pass-through pci devices for a domain" ,"<Domain>" , }, + { "pci-assignable-add", + &main_pciassignable_add,0 ,1 , +"Make a device assignable for pci-passthru" , +"<BDF>" , +"-h Print this help.\n" + }, + { "pci-assignable-remove", + &main_pciassignable_remove,0 ,1 , +"Remove a device from being assignable" , +"[options] <BDF>" , +"-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",
Quoted 18 lines · George Dunlap
Add commands to automatically prep devices for pass-through
The current method for passing through devices requires users to either modify cryptic Linux boot parameters and reboot, or do a lot of manual reads and writes into sysfs nodes.
This set of patches introduces commands to make this easier. It expands on the concept of "assignable" (from the
list_assignable_devicescommand).The new xl commands are:
pci_assignable_add: Make a device assignable to guests. This involves unbinding the device from its old driver, creating a slot for it in pciback (if necessary), and binding it to pciback.
pci_assignable_list: List devices assignable to guests. Just renamed frompci_list_assignable.
Quoted 6 lines
pci_assignable_remove: Make the device no longer assignable to guests. This involves unbinding the device from pciback and removing the slot. It optionally involves rebinding the device to the driver from which we stole it.Signed-off-by George Dunlap <[email protected]>
All 4 patches:
Please do watch out for adding trailing whitespace, I cleaned this up in the series and a couple of your other patches which I applied today.
Ian.