Skip to content

Commit

Permalink
FIXME support for shadow ioeventfd
Browse files Browse the repository at this point in the history
Signed-off-by: Thanos Makatos <[email protected]>
Change-Id: Iad849c94076ffa5988e034c8bf7ec312d01f095f
  • Loading branch information
tmakatos committed Jun 17, 2022
1 parent 1c27402 commit 3f9562b
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 3 deletions.
2 changes: 1 addition & 1 deletion include/libvfio-user.h
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ vfu_sg_is_mappable(vfu_ctx_t *vfu_ctx, dma_sg_t *sg);
int
vfu_create_ioeventfd(vfu_ctx_t *vfu_ctx, uint32_t region_idx, int fd,
size_t offset, uint32_t size, uint32_t flags,
uint64_t datamatch);
uint64_t datamatch, int data_fd);

#ifdef __cplusplus
}
Expand Down
1 change: 1 addition & 0 deletions include/vfio-user.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ typedef struct vfio_user_region_io_fds_request {

#define VFIO_USER_IO_FD_TYPE_IOEVENTFD 0
#define VFIO_USER_IO_FD_TYPE_IOREGIONFD 1
#define VFIO_USER_IO_FD_TYPE_IOEVENTFD_SHADOW 2

typedef struct vfio_user_sub_region_ioeventfd {
uint64_t offset;
Expand Down
16 changes: 14 additions & 2 deletions lib/libvfio-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ handle_device_get_region_info(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
EXPORT int
vfu_create_ioeventfd(vfu_ctx_t *vfu_ctx, uint32_t region_idx, int fd,
size_t offset, uint32_t size, uint32_t flags,
uint64_t datamatch)
uint64_t datamatch, int data_fd)
{
vfu_reg_info_t *vfu_reg;

Expand All @@ -494,6 +494,7 @@ vfu_create_ioeventfd(vfu_ctx_t *vfu_ctx, uint32_t region_idx, int fd,
elem->size = size;
elem->flags = flags;
elem->datamatch = datamatch;
elem->data_fd = data_fd;
LIST_INSERT_HEAD(&vfu_reg->subregions, elem, entry);

return 0;
Expand Down Expand Up @@ -580,6 +581,7 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)

// At least one flag must be set for a valid region.
if (!(vfu_reg->flags & VFU_REGION_FLAG_MASK)) {
vfu_log(vfu_ctx, LOG_DEBUG, "no flag for region index %d", req->index);
return ERROR_INT(EINVAL);
}

Expand Down Expand Up @@ -627,7 +629,13 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
ioefd->size = sub_reg->size;
ioefd->fd_index = add_fd_index(msg->out.fds, &msg->out.nr_fds,
sub_reg->fd);
ioefd->type = VFIO_USER_IO_FD_TYPE_IOEVENTFD;
if (sub_reg->data_fd == -1) {
ioefd->type = VFIO_USER_IO_FD_TYPE_IOEVENTFD;
} else {
ioefd->type = VFIO_USER_IO_FD_TYPE_IOEVENTFD_SHADOW;
int ret = add_fd_index(msg->out_fds, &msg->nr_out_fds, sub_reg->data_fd);
assert(ret == 1);
}
ioefd->flags = sub_reg->flags;
ioefd->datamatch = sub_reg->datamatch;

Expand Down Expand Up @@ -1832,6 +1840,10 @@ vfu_setup_region(vfu_ctx_t *vfu_ctx, int region_idx, size_t size,

assert(vfu_ctx != NULL);

/*
* FIXME should we set a flag in the region to indicate that it has I/O
* region FDs? This way the client won't have to blindly look for them.
*/
if ((flags & ~(VFU_REGION_FLAG_MASK)) ||
(!(flags & VFU_REGION_FLAG_RW))) {
vfu_log(vfu_ctx, LOG_ERR, "invalid region flags");
Expand Down
1 change: 1 addition & 0 deletions lib/private.h
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ typedef struct ioeventfd {
int32_t fd;
uint32_t flags;
uint64_t datamatch;
int32_t data_fd;
LIST_ENTRY(ioeventfd) entry;
} ioeventfd_t;

Expand Down

0 comments on commit 3f9562b

Please sign in to comment.