mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
libxl: add 'name' field to 'libxl_device_pci' in the IDL...
... and modify libxl_pci_bdf_assignable_add/remove/list() to make use of it.
libxl_pci_bdf_assignable_add() will store the name of the device in xenstore
if the field is specified (i.e. non-NULL) and libxl_pci_bdf_assignable_remove()
will remove devices specified only by name, looking up the BDF as necessary.
libxl_pci_bdf_assignable_list() will also populate the 'name' field if a name
was stored by libxl_pci_bdf_assignable_add().
NOTE: This patch also fixes whitespace in the declaration of 'libxl_device_pci'
in the IDL.
Signed-off-by: Paul Durrant <pdurrant@amazon.com>
Acked-by: Wei Liu <wl@xen.org>
This commit is contained in:
1 parent
d473d74af3
commit
57bff091f4
3 files changed
+87
-9
No files matched your search
@@ -463,6 +463,12 @@
|
||||
*/
|
||||
#define LIBXL_HAVE_DEVICE_PCI_ASSIGNABLE_LIST_FREE 1
|
||||
|
||||
/*
|
||||
* LIBXL_HAVE_DEVICE_PCI_NAME indicates that the libxl_device_pci type
|
||||
* has a name field.
|
||||
*/
|
||||
#define LIBXL_HAVE_DEVICE_PCI_NAME 1
|
||||
|
||||
/*
|
||||
* libxl ABI compatibility
|
||||
*
|
||||
|
||||
@@ -438,7 +438,9 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
|
||||
}
|
||||
|
||||
while((de = readdir(dir))) {
|
||||
unsigned dom, bus, dev, func;
|
||||
unsigned int dom, bus, dev, func;
|
||||
char *name;
|
||||
|
||||
if (sscanf(de->d_name, PCI_BDF, &dom, &bus, &dev, &func) != 4)
|
||||
continue;
|
||||
|
||||
@@ -455,6 +457,9 @@ libxl_device_pci *libxl_device_pci_assignable_list(libxl_ctx *ctx, int *num)
|
||||
if (pci_info_xs_read(gc, new, "domid")) /* already assigned */
|
||||
continue;
|
||||
|
||||
name = pci_info_xs_read(gc, new, "name");
|
||||
if (name) new->name = strdup(name);
|
||||
|
||||
(*num)++;
|
||||
}
|
||||
|
||||
@@ -742,6 +747,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
|
||||
libxl_ctx *ctx = libxl__gc_owner(gc);
|
||||
unsigned dom, bus, dev, func;
|
||||
char *spath, *driver_path = NULL;
|
||||
const char *name;
|
||||
int rc;
|
||||
struct stat st;
|
||||
|
||||
@@ -750,6 +756,24 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
|
||||
bus = pci->bus;
|
||||
dev = pci->dev;
|
||||
func = pci->func;
|
||||
name = pci->name;
|
||||
|
||||
/* Sanitise any name that is set */
|
||||
if (name) {
|
||||
unsigned int i, n = strlen(name);
|
||||
|
||||
if (n > 64) { /* Reasonable upper bound on name length */
|
||||
LOG(ERROR, "Name too long");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!isgraph(name[i])) {
|
||||
LOG(ERROR, "Names may only include printable characters");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* See if the device exists */
|
||||
spath = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF, dom, bus, dev, func);
|
||||
@@ -765,7 +789,7 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
|
||||
}
|
||||
if ( rc ) {
|
||||
LOG(WARN, PCI_BDF" already assigned to pciback", dom, bus, dev, func);
|
||||
goto quarantine;
|
||||
goto name;
|
||||
}
|
||||
|
||||
/* Check to see if there's already a driver that we need to unbind from */
|
||||
@@ -796,7 +820,12 @@ static int libxl__device_pci_assignable_add(libxl__gc *gc,
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
quarantine:
|
||||
name:
|
||||
if (name)
|
||||
pci_info_xs_write(gc, pci, "name", name);
|
||||
else
|
||||
pci_info_xs_remove(gc, pci, "name");
|
||||
|
||||
/*
|
||||
* DOMID_IO is just a sentinel domain, without any actual mappings,
|
||||
* so always pass XEN_DOMCTL_DEV_RDM_RELAXED to avoid assignment being
|
||||
@@ -812,6 +841,40 @@ quarantine:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int name2bdf(libxl__gc *gc, libxl_device_pci *pci)
|
||||
{
|
||||
char **bdfs;
|
||||
unsigned int i, n;
|
||||
int rc = ERROR_NOTFOUND;
|
||||
|
||||
bdfs = libxl__xs_directory(gc, XBT_NULL, PCI_INFO_PATH, &n);
|
||||
if (!n)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
unsigned dom, bus, dev, func;
|
||||
char *name;
|
||||
|
||||
if (sscanf(bdfs[i], PCI_BDF_XSPATH, &dom, &bus, &dev, &func) != 4)
|
||||
continue;
|
||||
|
||||
pci_struct_fill(pci, dom, bus, dev, func);
|
||||
|
||||
name = pci_info_xs_read(gc, pci, "name");
|
||||
if (name && !strcmp(name, pci->name)) {
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
if (!rc)
|
||||
LOG(DETAIL, "'%s' -> " PCI_BDF, pci->name, pci->domain,
|
||||
pci->bus, pci->dev, pci->func);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int libxl__device_pci_assignable_remove(libxl__gc *gc,
|
||||
libxl_device_pci *pci,
|
||||
int rebind)
|
||||
@@ -820,6 +883,12 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
|
||||
int rc;
|
||||
char *driver_path;
|
||||
|
||||
/* If the device is named then we need to look up the BDF */
|
||||
if (pci->name) {
|
||||
rc = name2bdf(gc, pci);
|
||||
if (rc) return rc;
|
||||
}
|
||||
|
||||
/* De-quarantine */
|
||||
rc = xc_deassign_device(ctx->xch, DOMID_IO, pci_encode_bdf(pci));
|
||||
if ( rc < 0 ) {
|
||||
@@ -860,6 +929,8 @@ static int libxl__device_pci_assignable_remove(libxl__gc *gc,
|
||||
}
|
||||
}
|
||||
|
||||
pci_info_xs_remove(gc, pci, "name");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -771,17 +771,18 @@ libxl_device_nic = Struct("device_nic", [
|
||||
])
|
||||
|
||||
libxl_device_pci = Struct("device_pci", [
|
||||
("func", uint8),
|
||||
("dev", uint8),
|
||||
("bus", uint8),
|
||||
("domain", integer),
|
||||
("vdevfn", uint32),
|
||||
("func", uint8),
|
||||
("dev", uint8),
|
||||
("bus", uint8),
|
||||
("domain", integer),
|
||||
("vdevfn", uint32),
|
||||
("vfunc_mask", uint32),
|
||||
("msitranslate", bool),
|
||||
("power_mgmt", bool),
|
||||
("permissive", bool),
|
||||
("seize", bool),
|
||||
("rdm_policy", libxl_rdm_reserve_policy),
|
||||
("rdm_policy", libxl_rdm_reserve_policy),
|
||||
("name", string),
|
||||
])
|
||||
|
||||
libxl_device_rdm = Struct("device_rdm", [
|
||||
|
||||