Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support for shadow ioeventfd #698

Merged
merged 11 commits into from
Jul 4, 2022
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);
tmakatos marked this conversation as resolved.
Show resolved Hide resolved

#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->out.nr_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);

/*
tmakatos marked this conversation as resolved.
Show resolved Hide resolved
* 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