On 29/10/25 19:52, Stefan Hajnoczi wrote:
When the Bus Master bit is disabled in a PCI device's Command Register,
the device's DMA address space becomes unassigned memory (i.e. the
io_mem_unassigned MemoryRegion).
This can lead to deadlocks with IOThreads since io_mem_unassigned
accesses attempt to acquire the Big QEMU Lock (BQL). For example,
virtio-pci devices deadlock in virtio_write_config() ->
virtio_pci_stop_ioeventfd() when waiting for the IOThread while holding
the BQL. The IOThread is unable to acquire the BQL but the vcpu thread
won't release the BQL while waiting for the IOThread.
io_mem_unassigned is trivially thread-safe since it has no state, it
simply rejects all load/store accesses. Therefore it is safe to enable
lockless I/O on io_mem_unassigned to eliminate this deadlock.
[...]
Buglink: https://issues.redhat.com/browse/RHEL-71933
Reported-by: Peixiu Hou <[email protected]>
Cc: Kevin Wolf <[email protected]>
Cc: Paolo Bonzini <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
---
system/physmem.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/system/physmem.c b/system/physmem.c
index a340ca3e61..1dc2b46e12 100644
--- a/system/physmem.c
+++ b/system/physmem.c
@@ -3011,6 +3011,9 @@ static void io_mem_init(void)
{
memory_region_init_io(&io_mem_unassigned, NULL, &unassigned_mem_ops, NULL,
NULL, UINT64_MAX);
+
+ /* Trivially thread-safe since memory accesses are rejected */
Maybe duplicate the comment in unassigned_mem_ops[]. Regardless,
Reviewed-by: Philippe Mathieu-Daudé <[email protected]>
+ memory_region_enable_lockless_io(&io_mem_unassigned);
}