# ioregionfd ioregionfd is a mechanism that speeds up ioeventfds: https://lore.kernel.org/kvm/cover.1613828726.git.eafanasova@gmail.com/. 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 eventfd as normal. To use shadow ioeventfd, the kernel and QEMU need to be patched. The QEMU patch is designed specifically for SPDK's doorbells (one ioregionfd of 4K in BAR0); it should be trivial to extend. The list of patches: * kernel: https://gist.github.com/tmakatos/532afd092a8df2175120d3dbfcd719ef * QEMU: https://gist.github.com/tmakatos/57755d2a37a6d53c9ff392e7c34470f6 * SPDK: https://gist.github.com/tmakatos/f6c10fdaff59c9d629f94bd8e44a53bc shadow ioeventfd sample ----------------------- samples/shadow_ioeventfd_server.c implements a vfio-user server that allows a part of its BAR0 to be accessed via a shadow ioeventfd. shadow_ioeventfd_speed_test.c is run in the guest. It compares peformance of shadow ioeventfd vs. vfio-user messages by repeatedly writing to the part of the BAR0 that is handled by shadow ioeventfd and to the part not handled by shadow ioeventfd. To run the sample: * Patch and build the kernel and QEMU using above patches. * Enable support for shadow ioeventfd in libvfio-user (set `shadow-ieoventfd` to `true` in meson_options.txt and then build libvfio-user. * Run samples/shadow_ioeventfd_server, e.g. ``` build/samples/shadow_ioeventfd_server /var/run/cntrl ``` * Start the guest with `intel_iommu=off` in the kernel command line. * Bind the device to VFIO: ``` modprobe vfio-iommu-type1 allow_unsafe_interrupts=1 modprobe vfio-pci ids=4e58:0 ``` Build and run the test app in the guest (it needs to be copied there first), the BDF needs to be substituted accordingly: ``` gcc shadow_ioeventfd_speed_test.c ./a.out 3 0000:00:03.0 ```