From 36beb63be45ad1412562a98d9373a4c0bd91ab3d Mon Sep 17 00:00:00 2001 From: Thanos Makatos Date: Mon, 4 Jul 2022 12:16:08 +0100 Subject: support for shadow ioeventfd (#698) When an ioeventfd is written to, KVM discards the value since it has no memory to write it to, and simply kicks the eventfd. This a problem for devices such a NVMe controllers that need the value (e.g. doorbells on BAR0). This patch allows the vfio-user server to pass a file descriptor that can be mmap'ed and KVM can write the ioeventfd value to this _shadow_ memory instead of discarding it. This shadow memory is not exposed to the guest. Signed-off-by: Thanos Makatos Reviewed-by: John Levon Change-Id: Iad849c94076ffa5988e034c8bf7ec312d01f095f --- include/libvfio-user.h | 10 ++++++++-- include/vfio-user.h | 1 + 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/libvfio-user.h b/include/libvfio-user.h index 84eb2d8..d12d89f 100644 --- a/include/libvfio-user.h +++ b/include/libvfio-user.h @@ -1069,12 +1069,18 @@ 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 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. 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 + * must be -1. */ 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 shadow_fd); #ifdef __cplusplus } #endif diff --git a/include/vfio-user.h b/include/vfio-user.h index 7439484..dc6fafa 100644 --- a/include/vfio-user.h +++ b/include/vfio-user.h @@ -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; -- cgit v1.1