[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 9/9] tools/libs/light: Add "reset" and "remove" PCI dev commands to xl pcid daemon and libxl PCI
From: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx> Add "reset" command processing to xl pcid daemon. Make possible sending "reset"/"remove" PCI device requests from libxl PCI to xl pcid daemon instead of using sysfs on libxl side. Signed-off-by: Anastasiia Lukianenko <anastasiia_lukianenko@xxxxxxxx> --- tools/include/pcid.h | 1 + tools/libs/light/libxl_pci.c | 94 +++++++++++++++++++---------------- tools/libs/light/libxl_pcid.c | 63 +++++++++++++++++++++++ 3 files changed, 115 insertions(+), 43 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 3153bafb19..38ea06c602 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -30,6 +30,7 @@ #define PCID_CMD_LIST "ls" #define PCID_CMD_UNBIND "unbind" +#define PCID_CMD_RESET "reset" #define PCID_CMD_DIR_ID "dir_id" #define PCID_CMD_WRITE "write" diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 3d9bf4830b..0498baa47e 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -1635,37 +1635,26 @@ static int libxl__device_pci_reset(libxl__gc *gc, unsigned int domain, unsigned unsigned int dev, unsigned int func) { char *reset; - int fd, rc; - - reset = GCSPRINTF("%s/do_flr", SYSFS_PCIBACK_DRIVER); - fd = open(reset, O_WRONLY); - if (fd >= 0) { - char *buf = GCSPRINTF(PCI_BDF, domain, bus, dev, func); - rc = write(fd, buf, strlen(buf)); - if (rc < 0) - LOGD(ERROR, domain, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno != ENOENT) - LOGED(ERROR, domain, "Failed to access pciback path %s", reset); - reset = GCSPRINTF("%s/"PCI_BDF"/reset", SYSFS_PCI_DEV, domain, bus, dev, func); - fd = open(reset, O_WRONLY); - if (fd >= 0) { - rc = write(fd, "1", 1); - if (rc < 0) - LOGED(ERROR, domain, "write to %s returned %d", reset, rc); - close(fd); - return rc < 0 ? rc : 0; - } - if (errno == ENOENT) { - LOGD(ERROR, domain, - "The kernel doesn't support reset from sysfs for PCI device "PCI_BDF, - domain, bus, dev, func); - } else { - LOGED(ERROR, domain, "Failed to access reset path %s", reset); + char *buf; + struct vchan_info *vchan; + libxl__json_object *args = NULL, *result = NULL; + + vchan = pci_prepare_vchan(gc); + if (!vchan) + return -1; + + reset = GCSPRINTF("%s", "/do_flr"); + buf = GCSPRINTF(PCI_BDF, domain, bus, dev, func); + + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_PATH, reset); + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, buf); + result = vchan_send_command(gc, vchan, PCID_CMD_RESET, args); + if (!result) { + LOGD(ERROR, domain, "write to %s returned error", reset); + return -1; } - return -1; + + return 0; } int libxl__device_pci_setdefault(libxl__gc *gc, uint32_t domid, @@ -2085,20 +2074,35 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs) goto out_fail; } } else { - char *sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/resource", pci->domain, + char *sysfs_path = GCSPRINTF("/"PCI_BDF"/resource", pci->domain, pci->bus, pci->dev, pci->func); - FILE *f = fopen(sysfs_path, "r"); unsigned int start = 0, end = 0, flags = 0, size = 0; int irq = 0; int i; + struct vchan_info *vchan; + libxl__json_object *args = NULL, *result = NULL; + const libxl__json_object *addr; + int j = 0; - if (f == NULL) { - LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); + vchan = pci_prepare_vchan(gc); + if (!vchan) + goto out_fail; + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, sysfs_path); + result = vchan_send_command(gc, vchan, PCID_CMD_READ_RESOURCES, args); + if (!result) { + LOGED(ERROR, domainid, "Couldn't get resources from %s", sysfs_path); + rc = ERROR_FAIL; goto skip1; } + for (i = 0; i < PROC_PCI_NUM_RESOURCES; i++) { - if (fscanf(f, "0x%x 0x%x 0x%x\n", &start, &end, &flags) != 3) - continue; + addr = libxl__json_array_get(result, j++); + start = libxl__json_object_get_integer(addr); + addr = libxl__json_array_get(result, j++); + end = libxl__json_object_get_integer(addr); + addr = libxl__json_array_get(result, j++); + flags = libxl__json_object_get_integer(addr); + size = end - start + 1; if (start) { if (flags & PCI_BAR_IO) { @@ -2119,16 +2123,21 @@ static void do_pci_remove(libxl__egc *egc, pci_remove_state *prs) } } } - fclose(f); + skip1: - sysfs_path = GCSPRINTF(SYSFS_PCI_DEV"/"PCI_BDF"/irq", pci->domain, + sysfs_path = GCSPRINTF("/"PCI_BDF"/irq", pci->domain, pci->bus, pci->dev, pci->func); - f = fopen(sysfs_path, "r"); - if (f == NULL) { - LOGED(ERROR, domainid, "Couldn't open %s", sysfs_path); + libxl__vchan_param_add_string(gc, &args, PCID_CMD_PCI_INFO, sysfs_path); + libxl__vchan_param_add_string(gc, &args, PCID_CMD_DIR_ID, PCID_PCI_DEV); + result = vchan_send_command(gc, vchan, PCID_CMD_READ_HEX, args); + if (!result) { + LOGED(ERROR, domainid, "Couldn't get irq from %s", sysfs_path); + rc = ERROR_FAIL; goto skip_irq; } - if ((fscanf(f, "%u", &irq) == 1) && irq) { + + irq = libxl__json_object_get_integer(result); + if (irq) { rc = xc_physdev_unmap_pirq(ctx->xch, domid, irq); if (rc < 0) { LOGED(ERROR, domainid, "xc_physdev_unmap_pirq irq=%d", irq); @@ -2138,7 +2147,6 @@ skip1: LOGED(ERROR, domainid, "xc_domain_irq_permission irq=%d", irq); } } - fclose(f); } skip_irq: rc = 0; diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index 7dd8f53f78..a4669b9533 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -348,6 +348,67 @@ out: return result; } +static libxl__json_object *process_reset_cmd(libxl__gc *gc, + const struct libxl__json_object *resp) +{ + libxl__json_object *result = NULL; + const libxl__json_object *args, *pci_path, *pci_info; + char *reset; + int rc, fd; + + args = libxl__json_map_get(PCID_MSG_FIELD_ARGS, resp, JSON_MAP); + if (!args) + goto out; + pci_info = libxl__json_map_get(PCID_CMD_PCI_INFO, args, JSON_ANY); + if (!pci_info) + goto out; + pci_path = libxl__json_map_get(PCID_CMD_PCI_PATH, args, JSON_ANY); + + reset = libxl__sprintf(gc, SYSFS_PCIBACK_DRIVER"%s", pci_path->u.string); + fd = open(reset, O_WRONLY); + if (fd >= 0) { + rc = write(fd, pci_info->u.string, strlen(pci_info->u.string)); + if (rc < 0) { + LOGE(ERROR, "write to %s returned %d\n", reset, rc); + goto out; + } + close(fd); + goto success; + } + if (errno != ENOENT) + LOGE(ERROR, "Failed to access pciback path %s\n", reset); + + reset = libxl__sprintf(gc, "%s/%s/reset", SYSFS_PCI_DEV, pci_info->u.string); + fd = open(reset, O_WRONLY); + if (fd >= 0) { + rc = write(fd, "1", 1); + if (rc < 0) { + LOGE(ERROR, "write to %s returned %d\n", reset, rc); + goto out; + } + close(fd); + goto success; + } + if (errno == ENOENT) + LOGE(ERROR, + "The kernel doesn't support reset from sysfs for PCI device %s\n", + pci_info->u.string); + else + LOGE(ERROR, "Failed to access reset path %s\n", reset); + goto out; + +success: + result = libxl__json_object_alloc(gc, JSON_STRING); + if (!result) { + LOGE(ERROR, "Memory allocation failed\n"); + goto out; + } + result->u.string = pci_path->u.string; + +out: + return result; +} + static int pcid_handle_message(libxl__gc *gc, const libxl__json_object *request, libxl__json_object **result) { @@ -373,6 +434,8 @@ static int pcid_handle_message(libxl__gc *gc, const libxl__json_object *request, *result = process_read_rsc_cmd(gc, request); else if (strcmp(command_name, PCID_CMD_UNBIND) == 0) *result = process_unbind_cmd(gc, request); + else if (strcmp(command_name, PCID_CMD_RESET) == 0) + *result = process_reset_cmd(gc, request); else return ERROR_NOTFOUND; -- 2.17.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |