On 03.06.2025 14:13, David Hildenbrand wrote:
When we unplug a vhost device, we end up calling vhost_dev_cleanup()
where we do a memory_listener_unregister().

This memory_listener_unregister() call will end up disconnecting the
listener from the address space through listener_del_address_space().

In that process, we effectively communicate the removal of all memory
regions from that listener, resulting in region_del() + commit()
callbacks getting triggered.

So in case of vhost, we end up calling vhost_commit() with no remaining
memory slots (0).

In vhost_commit() we end up overwriting the global variables
used_memslots / used_shared_memslots, used for detecting the number
of free memslots. With used_memslots / used_shared_memslots set to 0
by vhost_commit() during device removal, we'll later assume that the
other vhost devices still have plenty of memslots left when calling
vhost_get_free_memslots().

Let's fix it by simply removing the global variables and depending
only on the actual per-device count.

Easy to reproduce by adding two vhost-user devices to a VM and then
hot-unplugging one of them.

While at it, detect unexpected underflows in vhost_get_free_memslots()
and issue a warning.

Reported-by: yuanminghao <yuanm...@chinatelecom.cn>
Link: 
https://lore.kernel.org/qemu-devel/20241121060755.164310-1-yuanm...@chinatelecom.cn/
Fixes: 2ce68e4cf5be ("vhost: add vhost_has_free_slot() interface")
Cc: Igor Mammedov <imamm...@redhat.com>
Cc: Michael S. Tsirkin <m...@redhat.com>
Cc: Stefano Garzarella <sgarz...@redhat.com>
Signed-off-by: David Hildenbrand <da...@redhat.com>

Is it a stable material (10.0.x) too?

Thanks,

/mjt

Reply via email to