From a395d6a2fa17888f4a76cd71ed80bd29c2b739ca Mon Sep 17 00:00:00 2001 From: Aastha Rawat Date: Thu, 9 Apr 2026 11:53:06 +0000 Subject: [PATCH] accel/mshv: fix ioeventfd deassignment to forward correct datamatch value unregister_ioevent() is not forwarding the datamatch (queue index) to the mshv driver, causing only the first VirtIO-MMIO queue to be deassigned correctly. Subsequent queues fail with `-ENOENT`, triggering a fatal abort(). This failure was discovered while booting arm64 EDK2 firmware with mshv accel. Signed-off-by: Aastha Rawat Reviewed-by: Magnus Kulke Link: https://lore.kernel.org/r/20260409-fix_ioevent-v1-1-053b810ae6fb@linux.microsoft.com Signed-off-by: Paolo Bonzini --- accel/mshv/mshv-all.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/accel/mshv/mshv-all.c b/accel/mshv/mshv-all.c index d4cc7f5371..e1a8d62f8d 100644 --- a/accel/mshv/mshv-all.c +++ b/accel/mshv/mshv-all.c @@ -278,13 +278,22 @@ static int ioeventfd(int vm_fd, int event_fd, uint64_t addr, Datamatch dm, return ioctl(vm_fd, MSHV_IOEVENTFD, &args); } -static int unregister_ioevent(int vm_fd, int event_fd, uint64_t mmio_addr) +static int unregister_ioevent(int vm_fd, int event_fd, uint64_t mmio_addr, + uint64_t data, uint32_t len, bool data_match) { uint32_t flags = 0; Datamatch dm = {0}; flags |= BIT(MSHV_IOEVENTFD_BIT_DEASSIGN); - dm.tag = DATAMATCH_NONE; + if (!data_match) { + dm.tag = DATAMATCH_NONE; + } else if (len == sizeof(uint64_t)) { + dm.tag = DATAMATCH_U64; + dm.value.u64 = data; + } else { + dm.tag = DATAMATCH_U32; + dm.value.u32 = data; + } return ioeventfd(vm_fd, event_fd, mmio_addr, dm, flags); } @@ -337,11 +346,12 @@ static void mem_ioeventfd_del(MemoryListener *listener, int fd = event_notifier_get_fd(e); int ret; uint64_t addr = section->offset_within_address_space; + uint64_t len = int128_get64(section->size); trace_mshv_mem_ioeventfd_del(section->offset_within_address_space, int128_get64(section->size), data); - ret = unregister_ioevent(mshv_state->vm, fd, addr); + ret = unregister_ioevent(mshv_state->vm, fd, addr, data, len, match_data); if (ret < 0) { error_report("Failed to unregister ioeventfd: %s (%d)", strerror(-ret), -ret);