From: Dusan Stojkovic <[email protected]> When QEMU runs as a Xen device model, the guest's RAM is not allocated by QEMU and is not backed by a file descriptor that could be shared with a vhost-user backend: accesses from QEMU go through the Xen mapcache and memory_region_get_fd() returns -1. vhost_section() therefore filters out every RAM section, the vhost memory listener registers no regions, and starting any vhost-user device fails with "Failed initializing vhost-user memory map".
With VHOST_USER_PROTOCOL_F_XEN_MMAP the backend does not need an fd or a process-local mapping it maps guest memory itself through the Xen foreign mapping interface, using the guest physical address and domain id. Accept the Xen RAM region in vhost_section() so that it reaches the backend's memory table. The Xen grant region (xen.grants) must never be accepted: grant references can only be mapped individually on demand via address_space_map(), and deriving a host pointer for the whole region, as vhost_region_add_section() does, aborts in the Xen mapcache. Note that xen_mr_is_memory() returns true for both the RAM and the grants region, so the grants region is excluded explicitly. Because of the necessity to exlude xen.grants, the missing stub for xen_mr_is_grants is added so that it can be called from common code. Signed-off-by: Dusan Stojkovic <[email protected]> Signed-off-by: Nikola Jelic <[email protected]> --- hw/virtio/vhost.c | 18 ++++++++++++++++++ hw/xen/xen_stubs.c | 5 +++++ 2 files changed, 23 insertions(+) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index af41841b52..26770d06d5 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -29,6 +29,7 @@ #include "system/dma.h" #include "system/memory.h" #include "system/ramblock.h" +#include "system/xen.h" #include "trace.h" /* enabled until disconnected backend stabilizes */ @@ -657,6 +658,23 @@ static bool vhost_section(struct vhost_dev *dev, MemoryRegionSection *section) return false; } + /* + * Under Xen, the guest's RAM is not backed by an fd that + * be passed to a vhost-user backend. The backend instead + * guest memory through the Xen foreign mapping interface, + * by guest physical address and domain id (see + * VHOST_USER_PROTOCOL_F_XEN_MMAP), so accept the Xen RAM + * region even though it has no fd. + */ + if (xen_enabled()) { + if (xen_mr_is_memory(mr) && !xen_mr_is_grants(mr)) { + trace_vhost_section(mr->name); + return true; + } + trace_vhost_reject_section(mr->name, 4); + return false; + } + /* * Some backends (like vhost-user) can only handle memory regions * that have an fd (can be mapped into a different process). Filter diff --git a/hw/xen/xen_stubs.c b/hw/xen/xen_stubs.c index f830768d99..7af39bceb0 100644 --- a/hw/xen/xen_stubs.c +++ b/hw/xen/xen_stubs.c @@ -29,6 +29,11 @@ bool xen_mr_is_memory(const MemoryRegion *mr) g_assert_not_reached(); } +bool xen_mr_is_grants(const MemoryRegion *mr) +{ + g_assert_not_reached(); +} + bool xen_map_cache_enabled(void) { return false; -- 2.43.0
