aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Levon <john.levon@nutanix.com>2021-04-14 13:14:13 +0100
committerGitHub <noreply@github.com>2021-04-14 13:14:13 +0100
commit2e50c5667ce8724b0b7963255d3016efbb1f568a (patch)
tree9df7b544d28eafb18be94e03a43a66a347c41ffb
parent29dbda6cfcbd4093103f5c032b69ecf109b1eccb (diff)
downloadlibvfio-user-2e50c5667ce8724b0b7963255d3016efbb1f568a.zip
libvfio-user-2e50c5667ce8724b0b7963255d3016efbb1f568a.tar.gz
libvfio-user-2e50c5667ce8724b0b7963255d3016efbb1f568a.tar.bz2
libvfio-user.c: use ERROR_INT() (#433)
Reviewed-by: Thanos Makatos <thanos.makatos@nutanix.com>
-rw-r--r--lib/dma.h2
-rw-r--r--lib/libvfio-user.c204
-rw-r--r--lib/private.h2
-rw-r--r--samples/client.c7
-rw-r--r--test/unit-tests.c21
5 files changed, 116 insertions, 120 deletions
diff --git a/lib/dma.h b/lib/dma.h
index 861b8d3..eb907e0 100644
--- a/lib/dma.h
+++ b/lib/dma.h
@@ -110,7 +110,7 @@ dma_controller_destroy(dma_controller_t *dma);
/* Registers a new memory region.
* Returns:
* - On success, a non-negative region number
- * - On failure, -errno.
+ * - On failure, -1 with errno set.
*/
MOCK_DECLARE(int, dma_controller_add_region, dma_controller_t *dma,
vfu_dma_addr_t dma_addr, size_t size, int fd, off_t offset,
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 4a3aadf..e6b79f2 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -144,7 +144,7 @@ dev_get_caps(vfu_ctx_t *vfu_ctx, vfu_reg_info_t *vfu_reg, bool is_migr_reg,
*fds = malloc(nr_mmap_areas * sizeof(int));
if (*fds == NULL) {
- return -ENOMEM;
+ return ERROR_INT(ENOMEM);
}
sparse->header.id = VFIO_REGION_INFO_CAP_SPARSE_MMAP;
sparse->header.version = 1;
@@ -211,24 +211,21 @@ region_access(vfu_ctx_t *vfu_ctx, size_t region_index, char *buf,
if (region_index == VFU_PCI_DEV_CFG_REGION_IDX) {
ret = pci_config_space_access(vfu_ctx, buf, count, offset, is_write);
if (ret == -1) {
- ret = -errno;
+ return ret;
}
} else if (region_index == VFU_PCI_DEV_MIGR_REGION_IDX) {
if (vfu_ctx->migration == NULL) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
ret = migration_region_access(vfu_ctx, buf, count, offset, is_write);
- if (ret == -1) {
- ret = -errno;
- }
} else {
vfu_region_access_cb_t *cb = vfu_ctx->reg_info[region_index].cb;
if (cb == NULL) {
vfu_log(vfu_ctx, LOG_ERR, "no callback for region %zu",
region_index);
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
ret = cb(vfu_ctx, buf, count, offset, is_write);
@@ -301,7 +298,7 @@ handle_region_access(vfu_ctx_t *vfu_ctx, uint32_t size, uint16_t cmd,
assert(ra != NULL);
if (!is_valid_region_access(vfu_ctx, size, cmd, ra)) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
if (ra->count == 0) {
@@ -314,7 +311,7 @@ handle_region_access(vfu_ctx_t *vfu_ctx, uint32_t size, uint16_t cmd,
}
*data = calloc(1, *len);
if (*data == NULL) {
- return -ENOMEM;
+ return -1;
}
if (cmd == VFIO_USER_REGION_READ) {
buf = (char *)(((struct vfio_user_region_access*)(*data)) + 1);
@@ -331,7 +328,7 @@ handle_region_access(vfu_ctx_t *vfu_ctx, uint32_t size, uint16_t cmd,
ra->count, ra->offset + ra->count - 1, strerror(-ret));
/* FIXME we should return whatever has been accessed, not an error */
if (ret >= 0) {
- ret = -EINVAL;
+ ret = ERROR_INT(EINVAL);
}
return ret;
}
@@ -350,7 +347,7 @@ region_to_offset(uint32_t region)
return (uint64_t)region << VFU_REGION_SHIFT;
}
-long
+int
dev_get_reginfo(vfu_ctx_t *vfu_ctx, uint32_t index, uint32_t argsz,
struct vfio_region_info **vfio_reg, int **fds, size_t *nr_fds)
{
@@ -365,12 +362,12 @@ dev_get_reginfo(vfu_ctx_t *vfu_ctx, uint32_t index, uint32_t argsz,
if (index >= vfu_ctx->nr_regions) {
vfu_log(vfu_ctx, LOG_DEBUG, "bad region index %d in get region info",
index);
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
if (argsz < sizeof(struct vfio_region_info)) {
vfu_log(vfu_ctx, LOG_DEBUG, "bad argsz %d", argsz);
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
/*
@@ -378,7 +375,7 @@ dev_get_reginfo(vfu_ctx_t *vfu_ctx, uint32_t index, uint32_t argsz,
*/
*vfio_reg = calloc(1, argsz);
if (!*vfio_reg) {
- return -ENOMEM;
+ return -1;
}
caps_size = get_vfio_caps_size(index == VFU_PCI_DEV_MIGR_REGION_IDX,
vfu_reg);
@@ -425,7 +422,7 @@ handle_device_get_region_info(vfu_ctx_t *vfu_ctx, uint32_t size,
int **fds, size_t *nr_fds)
{
if (size < sizeof(*reg_info_in)) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
return dev_get_reginfo(vfu_ctx, reg_info_in->index, reg_info_in->argsz,
@@ -443,7 +440,7 @@ handle_device_get_info(vfu_ctx_t *vfu_ctx, uint32_t in_size,
if (in_size < sizeof(*in_dev_info) ||
in_dev_info->argsz < sizeof(*in_dev_info)) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
out_dev_info->argsz = sizeof(*in_dev_info);
@@ -464,7 +461,7 @@ consume_fd(int *fds, size_t nr_fds, size_t index)
int fd;
if (index >= nr_fds) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
fd = fds[index];
@@ -482,7 +479,7 @@ consume_fd(int *fds, size_t nr_fds, size_t index)
* @nr_fds: size of above array.
* @dma_regions: memory that contains the DMA regions to be mapped/unmapped
*
- * @returns 0 on success, -errno on failure.
+ * @returns 0 on success, -1 and errno on failure.
*/
int
handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
@@ -502,7 +499,7 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
if (size % sizeof(struct vfio_user_dma_region) != 0) {
vfu_log(vfu_ctx, LOG_ERR, "bad size of DMA regions %d", size);
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
nr_dma_regions = (int)(size / sizeof(struct vfio_user_dma_region));
@@ -528,8 +525,7 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
if (fd < 0) {
vfu_log(vfu_ctx, LOG_ERR, "failed to add DMA region %s: "
"mappable but fd not provided", rstr);
- ret = fd;
- break;
+ return -1;
}
}
@@ -537,13 +533,13 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
region->size, fd, region->offset,
region->prot);
if (ret < 0) {
- ret = -errno;
+ ret = errno;
vfu_log(vfu_ctx, LOG_ERR, "failed to add DMA region %s: %m",
rstr);
if (fd != -1) {
close(fd);
}
- break;
+ return ERROR_INT(ret);
}
if (vfu_ctx->dma_register != NULL) {
@@ -559,10 +555,10 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
vfu_ctx->dma_unregister,
vfu_ctx);
if (ret < 0) {
- ret = -errno;
+ ret = errno;
vfu_log(vfu_ctx, LOG_ERR, "failed to remove DMA region %s: %m",
rstr);
- break;
+ return ERROR_INT(ret);
}
}
}
@@ -585,7 +581,7 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx,
struct vfio_iommu_type1_dirty_bitmap_get *ranges,
uint32_t size)
{
- int ret = -EINVAL;
+ int ret = EINVAL;
size_t i;
assert(vfu_ctx != NULL);
@@ -594,12 +590,12 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx,
assert(ranges != NULL);
if (size % sizeof(struct vfio_iommu_type1_dirty_bitmap_get) != 0) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
*nr_iovecs = 1 + size / sizeof(struct vfio_iommu_type1_dirty_bitmap_get);
*iovecs = malloc(*nr_iovecs * sizeof(struct iovec));
if (*iovecs == NULL) {
- return -ENOMEM;
+ return -1;
}
for (i = 1; i < *nr_iovecs; i++) {
@@ -610,19 +606,22 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx,
r->bitmap.size,
(char**)&((*iovecs)[i].iov_base));
if (ret != 0) {
- ret = -errno;
+ ret = errno;
goto out;
}
(*iovecs)[i].iov_len = r->bitmap.size;
}
+
out:
if (ret != 0) {
if (*iovecs != NULL) {
free(*iovecs);
*iovecs = NULL;
}
+ return ERROR_INT(ret);
}
- return ret;
+
+ return 0;
}
int
@@ -639,15 +638,12 @@ MOCK_DEFINE(handle_dirty_pages)(vfu_ctx_t *vfu_ctx, uint32_t size,
if (size < sizeof(*dirty_bitmap) || size != dirty_bitmap->argsz) {
vfu_log(vfu_ctx, LOG_ERR, "invalid header size %u", size);
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
if (dirty_bitmap->flags & VFIO_IOMMU_DIRTY_PAGES_FLAG_START) {
ret = dma_controller_dirty_page_logging_start(vfu_ctx->dma,
migration_get_pgsize(vfu_ctx->migration));
- if (ret == -1) {
- ret = -errno;
- }
} else if (dirty_bitmap->flags & VFIO_IOMMU_DIRTY_PAGES_FLAG_STOP) {
dma_controller_dirty_page_logging_stop(vfu_ctx->dma);
ret = 0;
@@ -657,50 +653,42 @@ MOCK_DEFINE(handle_dirty_pages)(vfu_ctx_t *vfu_ctx, uint32_t size,
size - sizeof(*dirty_bitmap));
} else {
vfu_log(vfu_ctx, LOG_ERR, "bad flags %#x", dirty_bitmap->flags);
- ret = -EINVAL;
+ ret = ERROR_INT(EINVAL);
}
return ret;
}
-/*
- * FIXME return value is messed up, sometimes we return -1 and set errno while
- * other times we return -errno. Fix.
- */
-
-/*
- * Returns 0 if the header is valid, -errno otherwise.
- */
-static int
-validate_header(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size)
+static bool
+is_header_valid(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr, size_t size)
{
assert(hdr != NULL);
if (size < sizeof(hdr)) {
vfu_log(vfu_ctx, LOG_ERR, "short header read %ld", size);
- return -EINVAL;
+ return false;
}
if (hdr->flags.type != VFIO_USER_F_TYPE_COMMAND) {
vfu_log(vfu_ctx, LOG_ERR, "msg%#hx: not a command req", hdr->msg_id);
- return -EINVAL;
+ return false;
}
if (hdr->msg_size < sizeof(hdr)) {
vfu_log(vfu_ctx, LOG_ERR, "msg%#hx: bad size %d in header",
hdr->msg_id, hdr->msg_size);
- return -EINVAL;
+ return false;
}
- return 0;
+ return true;
}
/*
* Populates @hdr to contain the header for the next command to be processed.
* Stores any passed FDs into @fds and the number in @nr_fds.
*
- * Returns 0 if there is no command to process, -errno on error, or the number
- * of bytes read.
+ * Returns 0 if there is no command to process, -1 and errno on error, or the
+ * number of bytes read.
*/
int
MOCK_DEFINE(get_next_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
@@ -716,15 +704,15 @@ MOCK_DEFINE(get_next_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
case ENOMSG:
vfu_reset_ctx(vfu_ctx, "closed");
- return -ENOTCONN;
+ return ERROR_INT(ENOTCONN);
case ECONNRESET:
vfu_reset_ctx(vfu_ctx, "reset");
- return -ENOTCONN;
+ return ERROR_INT(ENOTCONN);
default:
vfu_log(vfu_ctx, LOG_ERR, "failed to receive request: %m");
- return -errno;
+ return -1;
}
}
@@ -759,6 +747,18 @@ MOCK_DEFINE(should_exec_command)(vfu_ctx_t *vfu_ctx, uint16_t cmd)
return true;
}
+/*
+ * Theoretically, there are still situations in which free() might change errno.
+ * See https://sourceware.org/bugzilla/show_bug.cgi?id=17924
+ */
+static void
+sfree(void *data)
+{
+ int saved_errno = errno;
+ free(data);
+ errno = saved_errno;
+}
+
int
MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
size_t size, int *fds, size_t nr_fds, int **fds_out,
@@ -780,13 +780,12 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
assert(iovecs != NULL);
assert(free_iovec_data != NULL);
- ret = validate_header(vfu_ctx, hdr, size);
- if (ret < 0) {
- return ret;
+ if (!is_header_valid(vfu_ctx, hdr, size)) {
+ return ERROR_INT(EINVAL);
}
if (!should_exec_command(vfu_ctx, hdr->cmd)) {
- return -EINVAL;
+ return ERROR_INT(EINVAL);
}
cmd_data_size = hdr->msg_size - sizeof(*hdr);
@@ -797,12 +796,12 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
if (ret < 0) {
if (errno == ENOMSG) {
vfu_reset_ctx(vfu_ctx, "closed");
- return -ENOTCONN;
+ return ERROR_INT(ENOTCONN);
} else if (errno == ECONNRESET) {
vfu_reset_ctx(vfu_ctx, "reset");
- return -ENOTCONN;
+ return ERROR_INT(ENOTCONN);
} else {
- return -errno;
+ return -1;
}
}
}
@@ -818,7 +817,7 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
case VFIO_USER_DEVICE_GET_INFO:
dev_info = calloc(1, sizeof(*dev_info));
if (dev_info == NULL) {
- ret = -ENOMEM;
+ ret = ERROR_INT(errno);
break;
}
ret = handle_device_get_info(vfu_ctx, cmd_data_size, cmd_data,
@@ -829,7 +828,7 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
*iovecs = _iovecs;
*nr_iovecs = 2;
} else {
- free(dev_info);
+ sfree(dev_info);
}
break;
@@ -850,7 +849,7 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
case VFIO_USER_DEVICE_GET_IRQ_INFO:
irq_info = calloc(1, sizeof(*irq_info));
if (irq_info == NULL) {
- ret = -ENOMEM;
+ ret = ERROR_INT(errno);
break;
}
ret = handle_device_get_irq_info(vfu_ctx, cmd_data_size, cmd_data,
@@ -861,17 +860,13 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
*iovecs = _iovecs;
*nr_iovecs = 2;
} else {
- ret = -errno;
- free(irq_info);
+ sfree(irq_info);
}
break;
case VFIO_USER_DEVICE_SET_IRQS:
ret = handle_device_set_irqs(vfu_ctx, cmd_data_size, fds, nr_fds,
cmd_data);
- if (ret < 0) {
- ret = -errno;
- }
break;
case VFIO_USER_REGION_READ:
@@ -905,11 +900,11 @@ MOCK_DEFINE(exec_command)(vfu_ctx_t *vfu_ctx, struct vfio_user_header *hdr,
default:
vfu_log(vfu_ctx, LOG_ERR, "bad command %d", hdr->cmd);
- ret = -EINVAL;
+ ret = ERROR_INT(EINVAL);
break;
}
- free(cmd_data);
+ sfree(cmd_data);
return ret;
}
@@ -917,7 +912,6 @@ int
MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx)
{
struct vfio_user_header hdr = { 0, };
- int ret;
int *fds = NULL, *fds_out = NULL;
size_t nr_fds, i;
size_t nr_fds_out = 0;
@@ -925,6 +919,8 @@ MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx)
struct iovec *iovecs = NULL;
size_t nr_iovecs = 0;
bool free_iovec_data = true;
+ int saved_errno;
+ int ret;
assert(vfu_ctx != NULL);
@@ -948,6 +944,8 @@ MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx)
ret = exec_command(vfu_ctx, &hdr, ret, fds, nr_fds, &fds_out, &nr_fds_out,
_iovecs, &iovecs, &nr_iovecs, &free_iovec_data);
+ saved_errno = errno;
+
for (i = 0; i < nr_fds; i++) {
if (fds[i] != -1) {
vfu_log(vfu_ctx, LOG_DEBUG,
@@ -957,16 +955,13 @@ MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx)
}
}
- /*
- * TODO: In case of error during command handling set errno respectively
- * in the reply message.
- */
+ errno = saved_errno;
if (ret < 0) {
- vfu_log(vfu_ctx, LOG_ERR, "msg%#hx: cmd %d failed: %s", hdr.msg_id,
- hdr.cmd, strerror(-ret));
+ vfu_log(vfu_ctx, LOG_ERR, "msg%#hx: cmd %d failed: %m", hdr.msg_id,
+ hdr.cmd);
- if (ret == -ENOTCONN) {
+ if (errno == ENOTCONN) {
goto out;
}
} else {
@@ -980,24 +975,23 @@ MOCK_DEFINE(process_request)(vfu_ctx_t *vfu_ctx)
ret = 0;
} else {
ret = vfu_ctx->tran->reply(vfu_ctx, hdr.msg_id, iovecs, nr_iovecs,
- fds_out, nr_fds_out, -ret);
+ fds_out, nr_fds_out, ret == 0 ? 0 : errno);
if (ret < 0) {
vfu_log(vfu_ctx, LOG_ERR, "failed to reply: %m");
if (errno == ECONNRESET) {
vfu_reset_ctx(vfu_ctx, "reset");
- ret = -ENOTCONN;
+ errno = ENOTCONN;
} else if (errno == ENOMSG) {
vfu_reset_ctx(vfu_ctx, "closed");
- ret = -ENOTCONN;
- } else {
- ret = -errno;
+ errno = ENOTCONN;
}
}
}
out:
+ saved_errno = errno;
if (iovecs != NULL) {
if (free_iovec_data) {
size_t i;
@@ -1010,7 +1004,9 @@ out:
}
}
free(fds_out);
- return ret;
+ errno = saved_errno;
+
+ return ret == 0 ? 0 : ERROR_INT(errno);
}
int
@@ -1067,7 +1063,7 @@ vfu_realize_ctx(vfu_ctx_t *vfu_ctx)
vfu_ctx->irqs = calloc(1, sizeof(vfu_irqs_t) + size);
if (vfu_ctx->irqs == NULL) {
// vfu_ctx->pci.config_space should be free'ed by vfu_destroy_ctx().
- return ERROR_INT(ENOMEM);
+ return -1;
}
// Set context irq information.
@@ -1110,7 +1106,7 @@ vfu_run_ctx(vfu_ctx_t *vfu_ctx)
err = process_request(vfu_ctx);
} while (err == 0 && blocking);
- return err == 0 ? 0 : ERROR_INT(-err);
+ return err;
}
static void
@@ -1203,7 +1199,7 @@ vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt,
vfu_ctx = calloc(1, sizeof(vfu_ctx_t));
if (vfu_ctx == NULL) {
- return ERROR_PTR(ENOMEM);
+ return NULL;
}
vfu_ctx->dev_type = dev_type;
@@ -1215,7 +1211,6 @@ vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt,
vfu_ctx->uuid = strdup(path);
if (vfu_ctx->uuid == NULL) {
- err = -errno;
goto err_out;
}
@@ -1227,23 +1222,19 @@ vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt,
vfu_ctx->nr_regions = VFU_PCI_DEV_NUM_REGIONS;
vfu_ctx->reg_info = calloc(vfu_ctx->nr_regions, sizeof(*vfu_ctx->reg_info));
if (vfu_ctx->reg_info == NULL) {
- err = -ENOMEM;
goto err_out;
}
if (vfu_setup_device_nr_irqs(vfu_ctx, VFU_DEV_ERR_IRQ, 1) == -1) {
- err = -errno;
goto err_out;
}
if (vfu_setup_device_nr_irqs(vfu_ctx, VFU_DEV_REQ_IRQ, 1) == -1) {
- err = -errno;
goto err_out;
}
if (vfu_ctx->tran->init != NULL) {
err = vfu_ctx->tran->init(vfu_ctx);
if (err < 0) {
- err = -errno;
goto err_out;
}
}
@@ -1255,9 +1246,11 @@ vfu_create_ctx(vfu_trans_t trans, const char *path, int flags, void *pvt,
return vfu_ctx;
err_out:
+ err = errno;
+
vfu_destroy_ctx(vfu_ctx);
- return ERROR_PTR(-err);
+ return ERROR_PTR(err);
}
int
@@ -1305,7 +1298,7 @@ copyin_mmap_areas(vfu_reg_info_t *reg_info,
reg_info->mmap_areas = malloc(size);
if (reg_info->mmap_areas == NULL) {
- return -ENOMEM;
+ return -1;
}
memcpy(reg_info->mmap_areas, mmap_areas, size);
@@ -1406,7 +1399,7 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size,
if (nr_mmap_areas > 0) {
ret = copyin_mmap_areas(reg, mmap_areas, nr_mmap_areas);
if (ret < 0) {
- goto out;
+ goto err;
}
}
@@ -1414,17 +1407,18 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size,
if (!validate_sparse_mmaps_for_migr_reg(reg)) {
vfu_log(vfu_ctx, LOG_ERR,
"migration registers cannot be memory mapped");
- ret = -EINVAL;
- goto out;
+ errno = EINVAL;
+ goto err;
}
}
-out:
- if (ret < 0) {
- free(reg->mmap_areas);
- memset(reg, 0, sizeof(*reg));
- return ERROR_INT(-ret);
- }
+
return 0;
+
+err:
+ ret = errno;
+ free(reg->mmap_areas);
+ memset(reg, 0, sizeof(*reg));
+ return ERROR_INT(ret);
}
int
@@ -1445,7 +1439,7 @@ vfu_setup_device_dma(vfu_ctx_t *vfu_ctx, vfu_dma_register_cb_t *dma_register,
// Create the internal DMA controller.
vfu_ctx->dma = dma_controller_create(vfu_ctx, VFU_DMA_REGIONS);
if (vfu_ctx->dma == NULL) {
- return ERROR_INT(ENOMEM);
+ return ERROR_INT(errno);
}
vfu_ctx->dma_register = dma_register;
diff --git a/lib/private.h b/lib/private.h
index 322a988..64780ce 100644
--- a/lib/private.h
+++ b/lib/private.h
@@ -148,7 +148,7 @@ consume_fd(int *fds, size_t nr_fds, size_t index);
vfu_reg_info_t *
vfu_get_region_info(vfu_ctx_t *vfu_ctx);
-long
+int
dev_get_reginfo(vfu_ctx_t *vfu_ctx, uint32_t index, uint32_t argsz,
struct vfio_region_info **vfio_reg, int **fds, size_t *nr_fds);
diff --git a/samples/client.c b/samples/client.c
index 797cb00..0647328 100644
--- a/samples/client.c
+++ b/samples/client.c
@@ -1270,12 +1270,7 @@ int main(int argc, char *argv[])
* it's the client that creates and provides the FD. Do we need to save some
* state in the migration data?
*/
- ret = configure_irqs(sock);
- if (ret < 0) {
- errx(EXIT_FAILURE, "failed to configure IRQs on destination server: %s",
- strerror(-ret));
- }
- irq_fd = ret;
+ irq_fd = configure_irqs(sock);
wait_for_irq(irq_fd);
diff --git a/test/unit-tests.c b/test/unit-tests.c
index 80d61c7..5ee3358 100644
--- a/test/unit-tests.c
+++ b/test/unit-tests.c
@@ -74,7 +74,8 @@ test_dma_map_mappable_without_fd(void **state UNUSED)
};
int fd;
- assert_int_equal(-EINVAL, handle_dma_map_or_unmap(&vfu_ctx, size, true, &fd, 0, &dma_region));
+ assert_int_equal(-1, handle_dma_map_or_unmap(&vfu_ctx, size, true, &fd, 0, &dma_region));
+ assert_int_equal(errno, EINVAL);
}
static void
@@ -260,10 +261,11 @@ test_dma_add_regions_mixed_partial_failure(void **state UNUSED)
expect_value(close, fd, 0xb);
will_return(close, 0);
- assert_int_equal(-EREMOTEIO,
+ assert_int_equal(-1,
handle_dma_map_or_unmap(&vfu_ctx,
ARRAY_SIZE(r) * sizeof(struct vfio_user_dma_region),
true, fds, 2, r));
+ assert_int_equal(EREMOTEIO, errno);
}
/*
@@ -614,16 +616,18 @@ test_get_region_info(UNUSED void **state)
size_t nr_fds;
/* bad argsz */
- assert_int_equal(-EINVAL,
+ assert_int_equal(-1,
dev_get_reginfo(&vfu_ctx, index, argsz, &vfio_reg,
&fds, &nr_fds));
+ assert_int_equal(EINVAL, errno);
/* bad region */
index = vfu_ctx.nr_regions;
argsz = sizeof(struct vfio_region_info);
- assert_int_equal(-EINVAL,
+ assert_int_equal(-1,
dev_get_reginfo(&vfu_ctx, index, argsz, &vfio_reg,
&fds, &nr_fds));
+ assert_int_equal(EINVAL, errno);
/* no region caps */
index = 1;
@@ -1188,9 +1192,10 @@ test_device_get_info_compat(void **state UNUSED)
assert_int_equal(VFU_DEV_NUM_IRQS, d_out.num_irqs);
/* fewer fields */
- assert_int_equal(-EINVAL,
+ assert_int_equal(-1,
handle_device_get_info(&vfu_ctx, (sizeof(d_in)) - 1,
&d_in, &d_out));
+ assert_int_equal(EINVAL, errno);
}
@@ -1675,7 +1680,8 @@ test_exec_command(UNUSED void **state)
expect_value(should_exec_command, cmd, 0xbeef);
r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, &_iovecs,
&iovecs, &nr_iovecs, &free_iovec_data);
- assert_int_equal(-EINVAL, r);
+ assert_int_equal(-1, r);
+ assert_int_equal(EINVAL, errno);
/* XXX should execute command */
struct transport_ops tran = { .recv_body = recv_body };
@@ -1685,7 +1691,8 @@ test_exec_command(UNUSED void **state)
expect_value(should_exec_command, cmd, 0xbeef);
r = exec_command(&vfu_ctx, &hdr, size, &fds, 0, NULL, NULL, &_iovecs,
&iovecs, &nr_iovecs, &free_iovec_data);
- assert_int_equal(-ENOBUFS, r);
+ assert_int_equal(-1, r);
+ assert_int_equal(ENOBUFS, errno);
}
static void