[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [RFC PATCH v3 10/10] tools/libs/light: pcid: implement write_bdf command
From: Dmytro Semenets <dmytro_semenets@xxxxxxxx> Signed-off-by: Dmytro Semenets <dmytro_semenets@xxxxxxxx> --- tools/include/pcid.h | 17 +++++++++ tools/libs/light/libxl_pci.c | 67 ++++++++++++++++++----------------- tools/libs/light/libxl_pcid.c | 38 ++++++++++++++++++++ 3 files changed, 90 insertions(+), 32 deletions(-) diff --git a/tools/include/pcid.h b/tools/include/pcid.h index 833b6c7f3e..2c1bd0727e 100644 --- a/tools/include/pcid.h +++ b/tools/include/pcid.h @@ -181,6 +181,23 @@ #define PCID_RESULT_KEY_IOMEM "iomem" #define PCID_RESULT_KEY_IRQS "irqs" +/* + ******************************************************************************* + * Write BDF values to the pciback sysfs path + * + * This command resets PCI device + * + * Request (see other mandatory fields above): + * - "cmd" field of the request must be set to "write_bdf". + * - "sbdf" SBDF of the device in format defined by PCID_SBDF_FMT. + * - "name" name of sysfs file of pciback driver + * + * Response (see other mandatory fields above): + * - "resp" field of the response must be set to "write_bdf". + */ +#define PCID_CMD_WRITE_BDF "write_bdf" +#define PCID_MSG_FIELD_NAME "name" + /* ******************************************************************************* * Reset PCI device diff --git a/tools/libs/light/libxl_pci.c b/tools/libs/light/libxl_pci.c index 2e7bd2eae5..a9a641829a 100644 --- a/tools/libs/light/libxl_pci.c +++ b/tools/libs/light/libxl_pci.c @@ -94,6 +94,8 @@ static int pci_handle_response(libxl__gc *gc, else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) == 0) *result = (libxl__json_object *)libxl__json_map_get(PCID_MSG_FIELD_RESOURCES, response, JSON_MAP); + else if (strcmp(command_name, PCID_CMD_WRITE_BDF) == 0) + *result = libxl__json_object_alloc(gc, JSON_NULL); return ret; } @@ -511,33 +513,6 @@ static bool is_pci_in_array(libxl_device_pci *pcis, int num, return i < num; } -/* 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 *pci) -{ - int rc, fd; - char *buf; - - fd = open(sysfs_path, O_WRONLY); - if (fd < 0) { - LOGE(ERROR, "Couldn't open %s", sysfs_path); - return ERROR_FAIL; - } - - buf = GCSPRINTF(PCI_BDF, pci->domain, pci->bus, - pci->dev, pci->func); - rc = write(fd, buf, strlen(buf)); - /* Annoying to have two if's, but we need the errno */ - if (rc < 0) - LOGE(ERROR, "write to %s returned %d", sysfs_path, rc); - close(fd); - - if (rc < 0) - return ERROR_FAIL; - - return 0; -} - #define PCI_INFO_PATH "/libxl/pci" static char *pci_info_xs_path(libxl__gc *gc, libxl_device_pci *pci, @@ -1384,6 +1359,36 @@ static bool pci_supp_legacy_irq(void) #endif } +static int pciback_write_bdf(libxl__gc *gc, char *name, libxl_device_pci *pci) +{ + struct vchan_info *vchan; + int rc; + libxl__json_object *args, *result; + + vchan = pci_vchan_get_client(gc); + if (!vchan) { + rc = ERROR_NOT_READY; + goto out; + } + + args = libxl__vchan_start_args(gc); + + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_SBDF, + GCSPRINTF(PCID_SBDF_FMT, pci->domain, + pci->bus, pci->dev, pci->func)); + libxl__vchan_arg_add_string(gc, args, PCID_MSG_FIELD_NAME, name); + + result = vchan_send_command(gc, vchan, PCID_CMD_WRITE_BDF, args); + if (!result) { + rc = ERROR_FAIL; + goto vchan_free; + } +vchan_free: + pci_vchan_free(gc, vchan); +out: + return rc; +} + static void pci_add_dm_done(libxl__egc *egc, pci_add_state *pas, int rc) @@ -1421,8 +1426,9 @@ static void pci_add_dm_done(libxl__egc *egc, libxl__vchan_arg_add_integer(gc, args, PCID_MSG_FIELD_DOMID, domid); result = vchan_send_command(gc, vchan, PCID_CMD_RESOURCE_LIST, args); + pci_vchan_free(gc, vchan); if (!result) - goto vchan_free; + goto out; value = libxl__json_map_get(PCID_RESULT_KEY_IOMEM, result, JSON_ARRAY); /* stubdomain is always running by now, even at create time */ @@ -1483,8 +1489,7 @@ static void pci_add_dm_done(libxl__egc *egc, /* Don't restrict writes to the PCI config space from this VM */ if (pci->permissive) { - if ( sysfs_write_bdf(gc, SYSFS_PCIBACK_DRIVER"/permissive", - pci) < 0 ) { + if (pciback_write_bdf(gc, "permissive", pci)) { LOGD(ERROR, domainid, "Setting permissive for device"); rc = ERROR_FAIL; goto out; @@ -1512,8 +1517,6 @@ out_no_irq: rc = libxl__device_pci_add_xenstore(gc, domid, pci, starting); else rc = 0; -vchan_free: - pci_vchan_free(gc, vchan); out: libxl__ev_time_deregister(gc, &pas->timeout); libxl__ev_time_deregister(gc, &pas->timeout_retries); diff --git a/tools/libs/light/libxl_pcid.c b/tools/libs/light/libxl_pcid.c index d968071224..66b433d2bf 100644 --- a/tools/libs/light/libxl_pcid.c +++ b/tools/libs/light/libxl_pcid.c @@ -257,6 +257,41 @@ static int pciback_dev_is_assigned(libxl__gc *gc, unsigned int domain, return 0; } +static int process_pciback_write_bdf(libxl__gc *gc, yajl_gen gen, + char *command_name, + const struct libxl__json_object *request, + struct libxl__json_object **response) +{ + const struct libxl__json_object *json_o; + unsigned int dom, bus, dev, func; + int rc = 0; + const char *name; + char *spath; + + json_o = libxl__json_map_get(PCID_MSG_FIELD_SBDF, request, JSON_STRING); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'sbdf'", command_name); + return ERROR_FAIL; + } + + if (sscanf(libxl__json_object_get_string(json_o), PCID_SBDF_FMT, + &dom, &bus, &dev, &func) != 4) { + make_error_reply(gc, gen, "Can't parse SBDF", command_name); + return ERROR_FAIL; + } + + json_o = libxl__json_map_get(PCID_MSG_FIELD_NAME, request, JSON_STRING); + if (!json_o) { + make_error_reply(gc, gen, "No mandatory parameter 'rebind'", command_name); + return ERROR_FAIL; + } + + name = libxl__json_object_get_string(json_o); + spath = GCSPRINTF("%s/%s", SYSFS_PCIBACK_DRIVER, name); + LOG(WARN, "sysf_write_bdf(%s, %d, %d, %d, %d)", spath, dom, bus, dev,func); + return rc; +} + #define PCID_INFO_PATH "pcid" #define PCID_BDF_XSPATH "%04x-%02x-%02x-%01x" @@ -746,6 +781,9 @@ static int pcid_handle_request(libxl__gc *gc, yajl_gen gen, else if (strcmp(command_name, PCID_CMD_RESOURCE_LIST) == 0) ret = process_list_resources(gc, gen, command_name, request, &command_response); + else if (strcmp(command_name, PCID_CMD_WRITE_BDF) == 0) + ret = process_pciback_write_bdf(gc, gen, command_name, + request, &command_response); else { /* * This is an unsupported command: make a reply and proceed over -- 2.34.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |