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
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions docs/ioregionfd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# ioregionfd

ioregionfd is a mechanism that speeds up ioeventfds:
https://lore.kernel.org/kvm/[email protected]/. In the
author's original words: "ioregionfd is a KVM dispatch mechanism which can be
used for handling MMIO/PIO accesses over file descriptors without returning
from ioctl(KVM_RUN).".

libvfio-user currently supports an experimental variant of this mechanism
called shadow ioeventfd. A shadow ioeventfd is a normal ioeventfd where the
vfio-user server passes another piece of memory (called the _shadow_ memory)
via an additional file descriptor when configuring the ioregionfd, which then
QEMU memory maps and passes this address to KVM. This shadow memory is never
exposed to the guest. When the guest writes to the trapped memory, KVM writes
the value to the shadow memory instread of discarding it, and then proceeds
kicking the evetnfd as normal.
tmakatos marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions include/libvfio-user.h
Original file line number Diff line number Diff line change
Expand Up @@ -1069,9 +1069,9 @@ vfu_sg_is_mappable(vfu_ctx_t *vfu_ctx, dma_sg_t *sg);
* @size: size of the ioeventfd
* @flags: Any flags to set up the ioeventfd
* @datamatch: sets the datamatch value
* @shadow_fd: File descriptor than can be mmap'ed, KVM will write there the
* @shadow_fd: File descriptor that can be mmap'ed, KVM will write there the
* otherwise discarded value when the ioeventfd is written to. If set to -1
* then a normal ioeventfd is set up instead of a shadow one. Then vfio-user
* then a normal ioeventfd is set up instead of a shadow one. The vfio-user
* client is free to ignore this, even if it supports shadow ioeventfds.
* Requires a kernel with shadow ioeventfd support.
* Experimental, must be compiled with SHADOW_IOEVENTFD defined, otherwise
Expand Down
7 changes: 4 additions & 3 deletions lib/libvfio-user.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
ioeventfd_t *sub_reg = NULL;
size_t nr_sub_reg = 0;
size_t i = 0;
size_t nr_shdw_reg = 0;
size_t nr_shadow_reg = 0;

assert(vfu_ctx != NULL);
assert(msg != NULL);
Expand Down Expand Up @@ -594,7 +594,7 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)
LIST_FOREACH(sub_reg, &vfu_reg->subregions, entry) {
nr_sub_reg++;
if (sub_reg->shadow_fd != -1) {
nr_shdw_reg++;
nr_shadow_reg++;
}
}

Expand Down Expand Up @@ -625,7 +625,8 @@ handle_device_get_region_io_fds(vfu_ctx_t *vfu_ctx, vfu_msg_t *msg)

msg->out.nr_fds = 0;
if (req->argsz >= reply->argsz) {
msg->out.fds = calloc(sizeof(int), max_sent_sub_regions + nr_shdw_reg);
msg->out.fds = calloc(sizeof(int),
max_sent_sub_regions + nr_shadow_reg);
if (msg->out.fds == NULL) {
return -1;
}
Expand Down
2 changes: 1 addition & 1 deletion meson_options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ option('tran-pipe', type: 'boolean', value: false,
description: 'enable pipe transport for testing')
option('debug-logs', type: 'feature', value: 'auto',
description: 'enable extra debugging code (default for debug builds)')
option('shadow-ioeventfd', type: 'boolean', value : true,
option('shadow-ioeventfd', type: 'boolean', value : false,
description: 'enable shadow ioeventfd (experimental)')
3 changes: 1 addition & 2 deletions test/py/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ python_tests = [
'test_vfu_realize_ctx.py',
]

opt_shadow_ioeventfd = get_option('shadow-ioeventfd')
if opt_shadow_ioeventfd
if get_option('shadow-ioeventfd')
python_tests += 'test_shadow_ioeventfd.py'
endif

Expand Down
2 changes: 1 addition & 1 deletion test/py/test_shadow_ioeventfd.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def test_shadow_ioeventfd():
else:
assert False

# Client writes to the I/O region. Tthe write to the eventfd would by done
# Client writes to the I/O region. The write to the eventfd would be done
# by KVM and the value would be the same in both cases.
cmem.seek(0x8)
cmem.write(c.c_ulonglong(0xdeadbeef))
Expand Down