mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
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 <aastharawat@linux.microsoft.com> Reviewed-by: Magnus Kulke <magnuskulke@linux.microsoft.com> Link: https://lore.kernel.org/r/20260409-fix_ioevent-v1-1-053b810ae6fb@linux.microsoft.com Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
committed by
Paolo Bonzini
parent
7d6231dfb5
commit
a395d6a2fa
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user