aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxl/libxl_pci.c
diff options
context:
space:
mode:
authorGianni Tedesco <gianni.tedesco@citrix.com>2010-08-04 14:43:46 +0100
committerGianni Tedesco <gianni.tedesco@citrix.com>2010-08-04 14:43:46 +0100
commit072186cf673d593478aced4614be65d19f459818 (patch)
tree70e6abc97b305b221a8b76e63ed5528a6ec99216 /tools/libxl/libxl_pci.c
parentd6353658b26249c50f8ae5c3b9861693f64e3446 (diff)
downloadxen-072186cf673d593478aced4614be65d19f459818.tar.gz
xen-072186cf673d593478aced4614be65d19f459818.tar.bz2
xen-072186cf673d593478aced4614be65d19f459818.zip
xl: detect pci-insert-failed dm status on pci-passthrough
NOTE: This functionality depends on a corresponding qemu-dm patch to work as expected. Should be safe to use with an un-patched qemu-dm as before. libxl_wait_for_device_model can only wait for one status value, re-work the API so that a callback function can chose between several different possible status values for qemu-dm and fix up all callers appropriately. In the case of PCI device insert we succeed if qemu-dm reports "pci-device-inserted" and error out instead of hanging forever if it fails since qemu-dm now reports a status of "pci-insert-failed". Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com> Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Diffstat (limited to 'tools/libxl/libxl_pci.c')
-rw-r--r--tools/libxl/libxl_pci.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 20f4a00218..c4dc0e4146 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -531,6 +531,20 @@ int libxl_device_pci_list_assignable(libxl_ctx *ctx, libxl_device_pci **list, in
return 0;
}
+static int pci_ins_check(libxl_ctx *ctx, uint32_t domid, const char *state, void *priv)
+{
+ char *orig_state = priv;
+
+ if ( !strcmp(state, "pci-insert-failed") )
+ return -1;
+ if ( !strcmp(state, "pci-inserted") )
+ return 0;
+ if ( !strcmp(state, orig_state) )
+ return 1;
+
+ return 1;
+}
+
static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
{
char *path;
@@ -553,13 +567,17 @@ static int do_pci_add(libxl_ctx *ctx, uint32_t domid, libxl_device_pci *pcidev)
pcidev->bus, pcidev->dev, pcidev->func);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/command", domid);
xs_write(ctx->xsh, XBT_NULL, path, "pci-ins", strlen("pci-ins"));
- if (libxl_wait_for_device_model(ctx, domid, "pci-inserted", NULL, NULL) < 0)
- XL_LOG(ctx, XL_LOG_ERROR, "Device Model didn't respond in time");
+ rc = libxl_wait_for_device_model(ctx, domid, NULL, pci_ins_check, state);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/parameter", domid);
vdevfn = libxl_xs_read(ctx, XBT_NULL, path);
- sscanf(vdevfn + 2, "%x", &pcidev->vdevfn);
path = libxl_sprintf(ctx, "/local/domain/0/device-model/%d/state", domid);
+ if ( rc < 0 )
+ XL_LOG(ctx, XL_LOG_ERROR, "qemu refused to add device: %s", vdevfn);
+ else if ( sscanf(vdevfn, "0x%x", &pcidev->vdevfn) != 1 )
+ rc = -1;
xs_write(ctx->xsh, XBT_NULL, path, state, strlen(state));
+ if ( rc )
+ return ERROR_FAIL;
} else {
char *sysfs_path = libxl_sprintf(ctx, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
pcidev->bus, pcidev->dev, pcidev->func);