mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
libxl / libxlu: support 'xl pci-attach/detach' by name
This patch adds a 'name' field into the idl for 'libxl_device_pci' and libxlu_pci_parse_spec_string() is modified to parse the new 'name' parameter of PCI_SPEC_STRING detailed in the updated documention in xl-pci-configuration(5). If the 'name' field is non-NULL then both libxl_device_pci_add() and libxl_device_pci_remove() will use it to look up the device BDF in the list of assignable devices. Signed-off-by: Paul Durrant <pdurrant@amazon.com> Acked-by: Wei Liu <wl@xen.org>
This commit is contained in:
1 parent
e1141654c3
commit
8bf0fab142
4 files changed
+75
-6
No files matched your search
@@ -476,6 +476,12 @@
|
||||
*/
|
||||
#define LIBXL_HAVE_PCI_ASSIGNABLE_BDF 1
|
||||
|
||||
/*
|
||||
* LIBXL_HAVE_DEVICE_PCI_NAME indicates that the 'name' field of
|
||||
* libxl_device_pci is defined.
|
||||
*/
|
||||
#define LIBXL_HAVE_DEVICE_PCI_NAME 1
|
||||
|
||||
/*
|
||||
* libxl ABI compatibility
|
||||
*
|
||||
|
||||
@@ -60,6 +60,10 @@ static void libxl_create_pci_backend_device(libxl__gc *gc,
|
||||
int num,
|
||||
const libxl_device_pci *pci)
|
||||
{
|
||||
if (pci->name) {
|
||||
flexarray_append(back, GCSPRINTF("name-%d", num));
|
||||
flexarray_append(back, GCSPRINTF("%s", pci->name));
|
||||
}
|
||||
flexarray_append(back, GCSPRINTF("key-%d", num));
|
||||
flexarray_append(back, GCSPRINTF(PCI_BDF, pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func));
|
||||
flexarray_append(back, GCSPRINTF("dev-%d", num));
|
||||
@@ -284,6 +288,7 @@ retry_transaction:
|
||||
|
||||
retry_transaction2:
|
||||
t = xs_transaction_start(ctx->xsh);
|
||||
xs_rm(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, i));
|
||||
xs_rm(ctx->xsh, t, GCSPRINTF("%s/state-%d", be_path, i));
|
||||
xs_rm(ctx->xsh, t, GCSPRINTF("%s/key-%d", be_path, i));
|
||||
xs_rm(ctx->xsh, t, GCSPRINTF("%s/dev-%d", be_path, i));
|
||||
@@ -322,6 +327,12 @@ retry_transaction2:
|
||||
xs_write(ctx->xsh, t, GCSPRINTF("%s/vdevfn-%d", be_path, j - 1), tmp, strlen(tmp));
|
||||
xs_rm(ctx->xsh, t, tmppath);
|
||||
}
|
||||
tmppath = GCSPRINTF("%s/name-%d", be_path, j);
|
||||
tmp = libxl__xs_read(gc, t, tmppath);
|
||||
if (tmp) {
|
||||
xs_write(ctx->xsh, t, GCSPRINTF("%s/name-%d", be_path, j - 1), tmp, strlen(tmp));
|
||||
xs_rm(ctx->xsh, t, tmppath);
|
||||
}
|
||||
}
|
||||
if (!xs_transaction_end(ctx->xsh, t, 0))
|
||||
if (errno == EAGAIN)
|
||||
@@ -1610,6 +1621,23 @@ void libxl__device_pci_add(libxl__egc *egc, uint32_t domid,
|
||||
pas->starting = starting;
|
||||
pas->callback = device_pci_add_stubdom_done;
|
||||
|
||||
if (pci->name) {
|
||||
libxl_pci_bdf *pcibdf =
|
||||
libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
|
||||
|
||||
if (!pcibdf) {
|
||||
rc = ERROR_FAIL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
|
||||
pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
|
||||
|
||||
libxl_pci_bdf_copy(CTX, &pci->bdf, pcibdf);
|
||||
libxl_pci_bdf_dispose(pcibdf);
|
||||
free(pcibdf);
|
||||
}
|
||||
|
||||
if (libxl__domain_type(gc, domid) == LIBXL_DOMAIN_TYPE_HVM) {
|
||||
rc = xc_test_assign_device(ctx->xch, domid,
|
||||
pci_encode_bdf(&pci->bdf));
|
||||
@@ -1758,11 +1786,19 @@ static void device_pci_add_done(libxl__egc *egc,
|
||||
libxl_device_pci *pci = &pas->pci;
|
||||
|
||||
if (rc) {
|
||||
LOGD(ERROR, domid,
|
||||
"libxl__device_pci_add failed for "
|
||||
"PCI device %x:%x:%x.%x (rc %d)",
|
||||
pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
|
||||
rc);
|
||||
if (pci->name) {
|
||||
LOGD(ERROR, domid,
|
||||
"libxl__device_pci_add failed for "
|
||||
"PCI device '%s' (rc %d)",
|
||||
pci->name,
|
||||
rc);
|
||||
} else {
|
||||
LOGD(ERROR, domid,
|
||||
"libxl__device_pci_add failed for "
|
||||
"PCI device %x:%x:%x.%x (rc %d)",
|
||||
pci->bdf.domain, pci->bdf.bus, pci->bdf.dev, pci->bdf.func,
|
||||
rc);
|
||||
}
|
||||
pci_info_xs_remove(gc, &pci->bdf, "domid");
|
||||
}
|
||||
libxl_device_pci_dispose(pci);
|
||||
@@ -2279,6 +2315,23 @@ static void libxl__device_pci_remove_common(libxl__egc *egc,
|
||||
libxl__ev_time_init(&prs->timeout);
|
||||
libxl__ev_time_init(&prs->retry_timer);
|
||||
|
||||
if (pci->name) {
|
||||
libxl_pci_bdf *pcibdf =
|
||||
libxl_pci_bdf_assignable_name2bdf(CTX, pci->name);
|
||||
|
||||
if (!pcibdf) {
|
||||
rc = ERROR_FAIL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
LOGD(DETAIL, domid, "'%s' -> %04x:%02x:%02x.%u", pci->name,
|
||||
pcibdf->domain, pcibdf->bus, pcibdf->dev, pcibdf->func);
|
||||
|
||||
libxl_pci_bdf_copy(CTX, &prs->pci.bdf, pcibdf);
|
||||
libxl_pci_bdf_dispose(pcibdf);
|
||||
free(pcibdf);
|
||||
}
|
||||
|
||||
prs->orig_vdev = pci->vdevfn & ~7U;
|
||||
|
||||
if ( pci->vfunc_mask == LIBXL_PCI_FUNC_ALL ) {
|
||||
@@ -2413,6 +2466,10 @@ static int libxl__device_pci_from_xs_be(libxl__gc *gc,
|
||||
} while ((p = strtok_r(NULL, ",=", &saveptr)) != NULL);
|
||||
}
|
||||
|
||||
s = libxl__xs_read(gc, XBT_NULL, GCSPRINTF("%s/name-%d", be_path, nr));
|
||||
if (s)
|
||||
pci->name = strdup(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -779,6 +779,7 @@ libxl_pci_bdf = Struct("pci_bdf", [
|
||||
|
||||
libxl_device_pci = Struct("device_pci", [
|
||||
("bdf", libxl_pci_bdf),
|
||||
("name", string),
|
||||
("vdevfn", uint32),
|
||||
("vfunc_mask", uint32),
|
||||
("msitranslate", bool),
|
||||
|
||||
@@ -151,6 +151,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
|
||||
{
|
||||
const char *ptr = str;
|
||||
bool bdf_present = false;
|
||||
bool name_present = false;
|
||||
int ret;
|
||||
|
||||
/* Attempt to parse 'bdf' as positional parameter */
|
||||
@@ -193,6 +194,10 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
|
||||
pcidev->power_mgmt = atoi(val);
|
||||
} else if (!strcmp(key, "rdm_policy")) {
|
||||
ret = parse_rdm_policy(cfg, &pcidev->rdm_policy, val);
|
||||
} else if (!strcmp(key, "name")) {
|
||||
name_present = true;
|
||||
pcidev->name = strdup(val);
|
||||
if (!pcidev->name) ret = ERROR_NOMEM;
|
||||
} else {
|
||||
XLU__PCI_ERR(cfg, "Unknown PCI_SPEC_STRING option: %s", key);
|
||||
ret = ERROR_INVAL;
|
||||
@@ -205,7 +210,7 @@ int xlu_pci_parse_spec_string(XLU_Config *cfg, libxl_device_pci *pcidev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!bdf_present)
|
||||
if (!(bdf_present ^ name_present))
|
||||
return ERROR_INVAL;
|
||||
|
||||
return 0;
|
||||
|
||||