Make sure we don't have any more ongoing memory transaction when releasing the
BQL. This will trigger an abort if we misuse the QEMU memory model, e.g., when
calling run_on_cpu() during a memory commit.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
cpus.c | 2 ++
include/exec/memory-internal.h | 1 +
memory.c | 6 ++++++
3 files changed, 9 insertions(+)
diff --git a/cpus.c b/cpus.c
index 48aa295fea..8c82556ff4 100644
--- a/cpus.c
+++ b/cpus.c
@@ -43,6 +43,7 @@
#include "sysemu/hvf.h"
#include "sysemu/whpx.h"
#include "exec/exec-all.h"
+#include "exec/memory-internal.h"
#include "qemu/thread.h"
#include "qemu/plugin.h"
@@ -1834,6 +1835,7 @@ void qemu_mutex_lock_iothread_impl(const char *file, int line)
static void qemu_mutex_unlock_iothread_prepare(void)
{
+ assert(!memory_region_has_pending_transaction());
}
void qemu_mutex_unlock_iothread(void)
diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h
index 9fcc2af25c..3124b91c4b 100644
--- a/include/exec/memory-internal.h
+++ b/include/exec/memory-internal.h
@@ -35,6 +35,7 @@ static inline AddressSpaceDispatch *address_space_to_dispatch(AddressSpace *as)
FlatView *address_space_get_flatview(AddressSpace *as);
void flatview_unref(FlatView *view);
+bool memory_region_has_pending_transaction(void);
extern const MemoryRegionOps unassigned_mem_ops;
diff --git a/memory.c b/memory.c
index fea427f43f..2f8dc9721f 100644
--- a/memory.c
+++ b/memory.c
@@ -177,6 +177,12 @@ static bool memory_region_has_pending_update(void)
return memory_region_update_pending || ioeventfd_update_pending;
}
+bool memory_region_has_pending_transaction(void)
+{
+ return memory_region_transaction_depth ||
+ memory_region_has_pending_update();
+}
+
static bool memory_region_ioeventfd_before(MemoryRegionIoeventfd *a,
MemoryRegionIoeventfd *b)
{
--
2.24.1