system/runstate: Fix regression, clarify BQL status of exit notifiers
authorPhil Dennis-Jordan <phil@philjordan.eu>
Sun, 12 Jan 2025 21:26:09 +0000 (22:26 +0100)
committerDavid Woodhouse <dwmw@amazon.co.uk>
Wed, 15 Jan 2025 18:05:19 +0000 (18:05 +0000)
By changing the way the main QEMU event loop is invoked, I inadvertently
changed the BQL status of exit notifiers: some of them implicitly
assumed they would be called with the BQL held; the BQL is however
not held during the exit(status) call in qemu_default_main().

Instead of attempting to ensuring we always call exit() from the BQL -
including any transitive calls - this change adds a BQL lock guard to
qemu_run_exit_notifiers, ensuring the BQL will always be held in the
exit notifiers.

Additionally, the BQL promise is now documented at the
qemu_{add,remove}_exit_notifier() declarations.

Fixes: f5ab12caba4f ("ui & main loop: Redesign of system-specific main
thread event handling")
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2771
Reported-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: Phil Dennis-Jordan <phil@philjordan.eu>
Tested-by: David Woodhouse <dwmw@amazon.co.uk>
Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
include/system/system.h
system/runstate.c

index 5364ad4f2765976f8e7ba7919e8c04c5731a8acb..0cbb43ec303bd6d0da9994977c18e581e91a57bd 100644 (file)
@@ -15,6 +15,7 @@ extern bool qemu_uuid_set;
 
 const char *qemu_get_vm_name(void);
 
+/* Exit notifiers will run with BQL held. */
 void qemu_add_exit_notifier(Notifier *notify);
 void qemu_remove_exit_notifier(Notifier *notify);
 
index 3a8fe866bc718018b3b530f464076b99c0ae2d5a..272801d3076956ae5d92f26e8f5d171be47b8ffa 100644 (file)
@@ -850,6 +850,7 @@ void qemu_remove_exit_notifier(Notifier *notify)
 
 static void qemu_run_exit_notifiers(void)
 {
+    BQL_LOCK_GUARD();
     notifier_list_notify(&exit_notifiers, NULL);
 }