aboutsummaryrefslogtreecommitdiff
path: root/lib/libvfio-user.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libvfio-user.c')
-rw-r--r--lib/libvfio-user.c107
1 files changed, 53 insertions, 54 deletions
diff --git a/lib/libvfio-user.c b/lib/libvfio-user.c
index 40a23b8..ebd70af 100644
--- a/lib/libvfio-user.c
+++ b/lib/libvfio-user.c
@@ -56,6 +56,7 @@
#include "private.h"
#include "tran_sock.h"
+
void
vfu_log(vfu_ctx_t *vfu_ctx, int level, const char *fmt, ...)
{
@@ -152,8 +153,8 @@ dev_get_caps(vfu_ctx_t *vfu_ctx, vfu_reg_info_t *vfu_reg, bool is_migr_reg,
for (i = 0; i < nr_mmap_areas; i++) {
struct iovec *iov = &vfu_reg->mmap_areas[i];
- vfu_log(vfu_ctx, LOG_DEBUG, "%s: area %d [%#llx-%#llx)", __func__,
- i, iov->iov_base, iov->iov_base + iov->iov_len);
+ vfu_log(vfu_ctx, LOG_DEBUG, "%s: area %d [%#llx, %#llx)", __func__,
+ i, iov->iov_base, iov_end(iov));
(*fds)[i] = vfu_reg->fd;
sparse->areas[i].offset = (uintptr_t)iov->iov_base;
@@ -487,7 +488,7 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
size_t fdi;
assert(vfu_ctx != NULL);
- assert(fds != NULL); /* TODO assert valid only for map */
+ assert(nr_fds == 0 || fds != NULL);
if (vfu_ctx->dma == NULL) {
return 0;
@@ -504,61 +505,57 @@ handle_dma_map_or_unmap(vfu_ctx_t *vfu_ctx, uint32_t size, bool map,
}
for (i = 0, fdi = 0; i < nr_dma_regions; i++) {
+ struct vfio_user_dma_region *region = &dma_regions[i];
+ char rstr[1024];
+
+ snprintf(rstr, sizeof(rstr), "[%#lx, %#lx) offset=%#lx "
+ "prot=%#x flags=%#x", region->addr, region->addr + region->size,
+ region->offset, region->prot, region->flags);
+
+ vfu_log(vfu_ctx, LOG_DEBUG, "%s DMA region %s",
+ map ? "adding" : "removing", rstr);
+
if (map) {
int fd = -1;
- if (dma_regions[i].flags == VFIO_USER_F_DMA_REGION_MAPPABLE) {
+ if (region->flags == VFIO_USER_F_DMA_REGION_MAPPABLE) {
fd = consume_fd(fds, nr_fds, fdi++);
if (fd < 0) {
+ vfu_log(vfu_ctx, LOG_ERR, "failed to add DMA region %s: "
+ "mappable but fd not provided", rstr);
ret = fd;
break;
}
}
- ret = dma_controller_add_region(vfu_ctx->dma,
- dma_regions[i].addr,
- dma_regions[i].size,
- fd,
- dma_regions[i].offset,
- dma_regions[i].prot);
+ ret = dma_controller_add_region(vfu_ctx->dma, (void *)region->addr,
+ region->size, fd, region->offset,
+ region->prot);
if (ret < 0) {
if (fd != -1) {
close(fd);
}
- vfu_log(vfu_ctx, LOG_INFO,
- "failed to add DMA region %#lx-%#lx offset=%#lx fd=%d: %s",
- dma_regions[i].addr,
- dma_regions[i].addr + dma_regions[i].size - 1,
- dma_regions[i].offset, fd,
- strerror(-ret));
+ vfu_log(vfu_ctx, LOG_ERR, "failed to add DMA region %s: %s",
+ rstr, strerror(-ret));
break;
}
- if (vfu_ctx->map_dma != NULL) {
- vfu_ctx->map_dma(vfu_ctx, dma_regions[i].addr,
- dma_regions[i].size, dma_regions[i].prot);
+
+ if (vfu_ctx->dma_register != NULL) {
+ vfu_ctx->dma_register(vfu_ctx,
+ &vfu_ctx->dma->regions[ret].info);
}
+
ret = 0;
- vfu_log(vfu_ctx, LOG_DEBUG,
- "added DMA region %#lx-%#lx offset=%#lx fd=%d prot=%#x",
- dma_regions[i].addr,
- dma_regions[i].addr + dma_regions[i].size - 1,
- dma_regions[i].offset, fd, dma_regions[i].prot);
} else {
ret = dma_controller_remove_region(vfu_ctx->dma,
- dma_regions[i].addr,
- dma_regions[i].size,
- vfu_ctx->unmap_dma, vfu_ctx);
+ (void *)region->addr,
+ region->size,
+ vfu_ctx->dma_unregister,
+ vfu_ctx);
if (ret < 0) {
- vfu_log(vfu_ctx, LOG_INFO,
- "failed to remove DMA region %#lx-%#lx: %s",
- dma_regions[i].addr,
- dma_regions[i].addr + dma_regions[i].size - 1,
- strerror(-ret));
+ vfu_log(vfu_ctx, LOG_ERR, "failed to remove DMA region %s: %s",
+ rstr, strerror(-ret));
break;
}
- vfu_log(vfu_ctx, LOG_DEBUG,
- "removed DMA region %#lx-%#lx",
- dma_regions[i].addr,
- dma_regions[i].addr + dma_regions[i].size - 1);
}
}
return ret;
@@ -599,8 +596,10 @@ handle_dirty_pages_get(vfu_ctx_t *vfu_ctx,
for (i = 1; i < *nr_iovecs; i++) {
struct vfio_iommu_type1_dirty_bitmap_get *r = &ranges[(i - 1)]; /* FIXME ugly indexing */
- ret = dma_controller_dirty_page_get(vfu_ctx->dma, r->iova, r->size,
- r->bitmap.pgsize, r->bitmap.size,
+ ret = dma_controller_dirty_page_get(vfu_ctx->dma,
+ (vfu_dma_addr_t)r->iova,
+ r->size, r->bitmap.pgsize,
+ r->bitmap.size,
(char**)&((*iovecs)[i].iov_base));
if (ret != 0) {
goto out;
@@ -1327,7 +1326,7 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size,
for (i = 0; i < nr_mmap_areas; i++) {
struct iovec *iov = &mmap_areas[i];
- if ((size_t)iov->iov_base + iov->iov_len > size) {
+ if ((size_t)iov_end(iov) > size) {
return ERROR_INT(EINVAL);
}
}
@@ -1385,8 +1384,8 @@ vfu_setup_device_reset_cb(vfu_ctx_t *vfu_ctx, vfu_reset_cb_t *reset)
}
int
-vfu_setup_device_dma_cb(vfu_ctx_t *vfu_ctx, vfu_map_dma_cb_t *map_dma,
- vfu_unmap_dma_cb_t *unmap_dma)
+vfu_setup_device_dma(vfu_ctx_t *vfu_ctx, vfu_dma_register_cb_t *dma_register,
+ vfu_dma_unregister_cb_t *dma_unregister)
{
assert(vfu_ctx != NULL);
@@ -1397,8 +1396,8 @@ vfu_setup_device_dma_cb(vfu_ctx_t *vfu_ctx, vfu_map_dma_cb_t *map_dma,
return ERROR_INT(ENOMEM);
}
- vfu_ctx->map_dma = map_dma;
- vfu_ctx->unmap_dma = unmap_dma;
+ vfu_ctx->dma_register = dma_register;
+ vfu_ctx->dma_unregister = dma_unregister;
return 0;
}
@@ -1450,33 +1449,33 @@ vfu_setup_device_migration_callbacks(vfu_ctx_t *vfu_ctx,
return 0;
}
-inline vfu_reg_info_t *
+vfu_reg_info_t *
vfu_get_region_info(vfu_ctx_t *vfu_ctx)
{
assert(vfu_ctx != NULL);
return vfu_ctx->reg_info;
}
-inline int
-vfu_addr_to_sg(vfu_ctx_t *vfu_ctx, dma_addr_t dma_addr,
- uint32_t len, dma_sg_t *sg, int max_sg, int prot)
+int
+vfu_addr_to_sg(vfu_ctx_t *vfu_ctx, vfu_dma_addr_t dma_addr,
+ size_t len, dma_sg_t *sg, int max_sg, int prot)
{
assert(vfu_ctx != NULL);
- if (unlikely(vfu_ctx->unmap_dma == NULL)) {
+ if (unlikely(vfu_ctx->dma == NULL)) {
return ERROR_INT(EINVAL);
}
return dma_addr_to_sg(vfu_ctx->dma, dma_addr, len, sg, max_sg, prot);
}
-inline int
+int
vfu_map_sg(vfu_ctx_t *vfu_ctx, const dma_sg_t *sg,
struct iovec *iov, int cnt)
{
int ret;
- if (unlikely(vfu_ctx->unmap_dma == NULL)) {
+ if (unlikely(vfu_ctx->dma_unregister == NULL)) {
return ERROR_INT(EINVAL);
}
@@ -1488,10 +1487,10 @@ vfu_map_sg(vfu_ctx_t *vfu_ctx, const dma_sg_t *sg,
return 0;
}
-inline void
+void
vfu_unmap_sg(vfu_ctx_t *vfu_ctx, const dma_sg_t *sg, struct iovec *iov, int cnt)
{
- if (unlikely(vfu_ctx->unmap_dma == NULL)) {
+ if (unlikely(vfu_ctx->dma_unregister == NULL)) {
return;
}
return dma_unmap_sg(vfu_ctx->dma, sg, iov, cnt);
@@ -1515,7 +1514,7 @@ vfu_dma_read(vfu_ctx_t *vfu_ctx, dma_sg_t *sg, void *data)
return ERROR_INT(ENOMEM);
}
- dma_send.addr = sg->dma_addr;
+ dma_send.addr = (uint64_t)sg->dma_addr;
dma_send.count = sg->length;
ret = vfu_ctx->tran->send_msg(vfu_ctx, msg_id, VFIO_USER_DMA_READ,
&dma_send, sizeof(dma_send), NULL,
@@ -1540,7 +1539,7 @@ vfu_dma_write(vfu_ctx_t *vfu_ctx, dma_sg_t *sg, void *data)
if (dma_send == NULL) {
return ERROR_INT(ENOMEM);
}
- dma_send->addr = sg->dma_addr;
+ dma_send->addr = (uint64_t)sg->dma_addr;
dma_send->count = sg->length;
memcpy(dma_send->data, data, sg->length); /* FIXME no need to copy! */
ret = vfu_ctx->tran->send_msg(vfu_ctx, msg_id, VFIO_USER_DMA_WRITE,