@samitouri / QOSamiQemu / commits / f036b28896

system: Move runstate-related code from cpus.c to runstate.c

Keep cpus.c focused on vCPUs handling, move code related to VM state to runstate.c where similar code lives. Fix few checkpatch.pl warnings: WARNING: Block comments use a leading /* on a separate line WARNING: Block comments use * on subsequent lines #327: FILE: system/runstate.c:541: +/* does a state transition even if the VM is already stopped, + current state is forgotten forever */ Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com> Message-Id: <20260812211708.92824-17-philmd@oss.qualcomm.com>

Philippe Mathieu-Daudé committed Aug 12, 2026 at 10:41 UTC f036b28896f615eacbe70e89bc9966249c74b99d
2 files changed +154 -147
system/cpus.c
-147
@@ -25,7 +25,6 @@
25 #include "qemu/osdep.h"
26 #include "qemu/coroutine-tls.h"
27 #include "qapi/error.h"
28 -#include "qapi/qapi-events-run-state.h"
28 #include "exec/gdbstub.h"
29 #include "accel/accel-cpu-ops.h"
30 #include "system/hw_accel.h"
@@ -272,58 +271,6 @@ void cpu_interrupt(CPUState *cpu, int mask)
271 cpus_accel->handle_interrupt(cpu, mask);
272 }
273
275 -/*
276 - * True if the vm was previously suspended, and has not been woken or reset.
277 - */
278 -static int vm_was_suspended;
279 -
280 -void vm_set_suspended(bool suspended)
281 -{
282 - vm_was_suspended = suspended;
283 -}
284 -
285 -bool vm_get_suspended(void)
286 -{
287 - return vm_was_suspended;
288 -}
289 -
290 -static int do_vm_stop(RunState state, bool send_stop)
291 -{
292 - int ret = 0;
293 - RunState oldstate = runstate_get();
294 -
295 - if (runstate_is_live(oldstate)) {
296 - vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED);
297 - runstate_set(state);
298 - cpu_disable_ticks();
299 - if (oldstate == RUN_STATE_RUNNING) {
300 - pause_all_vcpus();
301 - }
302 - ret = vm_state_notify(0, state);
303 - if (send_stop) {
304 - qapi_event_send_stop();
305 - }
306 - }
307 -
308 - bdrv_drain_all();
309 - /*
310 - * Even if vm_state_notify() return failure,
311 - * it would be better to flush as before.
312 - */
313 - ret |= bdrv_flush_all();
314 - trace_vm_stop_flush_all(ret);
315 -
316 - return ret;
317 -}
318 -
319 -/* Special vm_stop() variant for terminating the process. Historically clients
320 - * did not expect a QMP STOP event and so we need to retain compatibility.
321 - */
322 -int vm_shutdown(void)
323 -{
324 - return do_vm_stop(RUN_STATE_SHUTDOWN, false);
325 -}
326 -
274 bool cpu_can_run(CPUState *cpu)
275 {
276 if (cpu->stop) {
@@ -734,97 +681,3 @@ void cpu_stop_current(void)
681 cpu_exit(current_cpu);
682 }
683 }
737 -
738 -int vm_stop(RunState state)
739 -{
740 - if (qemu_in_vcpu_thread()) {
741 - qemu_system_vmstop_request_prepare();
742 - qemu_system_vmstop_request(state);
743 - /*
744 - * FIXME: should not return to device code in case
745 - * vm_stop() has been requested.
746 - */
747 - cpu_stop_current();
748 - return 0;
749 - }
750 -
751 - return do_vm_stop(state, true);
752 -}
753 -
754 -/**
755 - * Prepare for (re)starting the VM.
756 - * Returns 0 if the vCPUs should be restarted, -1 on an error condition,
757 - * and 1 otherwise.
758 - */
759 -int vm_prepare_start(bool step_pending)
760 -{
761 - int ret = vm_was_suspended ? 1 : 0;
762 - RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING;
763 - RunState requested;
764 -
765 - qemu_vmstop_requested(&requested);
766 - if (runstate_is_running() && requested == RUN_STATE__MAX) {
767 - return -1;
768 - }
769 -
770 - /* Ensure that a STOP/RESUME pair of events is emitted if a
771 - * vmstop request was pending. The BLOCK_IO_ERROR event, for
772 - * example, according to documentation is always followed by
773 - * the STOP event.
774 - */
775 - if (runstate_is_running()) {
776 - qapi_event_send_stop();
777 - qapi_event_send_resume();
778 - return -1;
779 - }
780 -
781 - /*
782 - * WHPX accelerator needs to know whether we are going to step
783 - * any CPUs, before starting the first one.
784 - */
785 - accel_pre_resume(MACHINE(qdev_get_machine()), step_pending);
786 -
787 - /* We are sending this now, but the CPUs will be resumed shortly later */
788 - qapi_event_send_resume();
789 -
790 - cpu_enable_ticks();
791 - runstate_set(state);
792 - vm_state_notify(1, state);
793 - vm_was_suspended = false;
794 - return ret;
795 -}
796 -
797 -void vm_start(void)
798 -{
799 - if (!vm_prepare_start(false)) {
800 - resume_all_vcpus();
801 - }
802 -}
803 -
804 -void vm_resume(RunState state)
805 -{
806 - if (runstate_is_live(state)) {
807 - vm_start();
808 - } else {
809 - runstate_set(state);
810 - }
811 -}
812 -
813 -/* does a state transition even if the VM is already stopped,
814 - current state is forgotten forever */
815 -int vm_stop_force_state(RunState state)
816 -{
817 - if (runstate_is_live(runstate_get())) {
818 - return vm_stop(state);
819 - } else {
820 - int ret;
821 - runstate_set(state);
822 -
823 - bdrv_drain_all();
824 - /* Make sure to return an error if the flush in a previous vm_stop()
825 - * failed. */
826 - ret = bdrv_flush_all();
827 - trace_vm_stop_flush_all(ret);
828 - return ret;
829 - }
830 -}
system/runstate.c
+154
@@ -52,6 +52,7 @@
52 #include "qemu/thread.h"
53 #include "qom/object.h"
54 #include "qom/object_interfaces.h"
55 +#include "system/cpu-timers.h"
56 #include "system/cpus.h"
57 #include "system/qtest.h"
58 #include "system/replay.h"
@@ -408,6 +409,159 @@ int vm_state_notify(bool running, RunState state)
409 return ret;
410 }
411
412 +/*
413 + * True if the vm was previously suspended, and has not been woken or reset.
414 + */
415 +static int vm_was_suspended;
416 +
417 +void vm_set_suspended(bool suspended)
418 +{
419 + vm_was_suspended = suspended;
420 +}
421 +
422 +bool vm_get_suspended(void)
423 +{
424 + return vm_was_suspended;
425 +}
426 +
427 +static int do_vm_stop(RunState state, bool send_stop)
428 +{
429 + int ret = 0;
430 + RunState oldstate = runstate_get();
431 +
432 + if (runstate_is_live(oldstate)) {
433 + vm_was_suspended = (oldstate == RUN_STATE_SUSPENDED);
434 + runstate_set(state);
435 + cpu_disable_ticks();
436 + if (oldstate == RUN_STATE_RUNNING) {
437 + pause_all_vcpus();
438 + }
439 + ret = vm_state_notify(0, state);
440 + if (send_stop) {
441 + qapi_event_send_stop();
442 + }
443 + }
444 +
445 + bdrv_drain_all();
446 + /*
447 + * Even if vm_state_notify() return failure,
448 + * it would be better to flush as before.
449 + */
450 + ret |= bdrv_flush_all();
451 + trace_vm_stop_flush_all(ret);
452 +
453 + return ret;
454 +}
455 +
456 +/*
457 + * Special vm_stop() variant for terminating the process. Historically clients
458 + * did not expect a QMP STOP event and so we need to retain compatibility.
459 + */
460 +int vm_shutdown(void)
461 +{
462 + return do_vm_stop(RUN_STATE_SHUTDOWN, false);
463 +}
464 +
465 +
466 +int vm_stop(RunState state)
467 +{
468 + if (qemu_in_vcpu_thread()) {
469 + qemu_system_vmstop_request_prepare();
470 + qemu_system_vmstop_request(state);
471 + /*
472 + * FIXME: should not return to device code in case
473 + * vm_stop() has been requested.
474 + */
475 + cpu_stop_current();
476 + return 0;
477 + }
478 +
479 + return do_vm_stop(state, true);
480 +}
481 +
482 +/**
483 + * Prepare for (re)starting the VM.
484 + * Returns 0 if the vCPUs should be restarted, -1 on an error condition,
485 + * and 1 otherwise.
486 + */
487 +int vm_prepare_start(bool step_pending)
488 +{
489 + int ret = vm_was_suspended ? 1 : 0;
490 + RunState state = vm_was_suspended ? RUN_STATE_SUSPENDED : RUN_STATE_RUNNING;
491 + RunState requested;
492 +
493 + qemu_vmstop_requested(&requested);
494 + if (runstate_is_running() && requested == RUN_STATE__MAX) {
495 + return -1;
496 + }
497 +
498 + /*
499 + * Ensure that a STOP/RESUME pair of events is emitted if a
500 + * vmstop request was pending. The BLOCK_IO_ERROR event, for
501 + * example, according to documentation is always followed by
502 + * the STOP event.
503 + */
504 + if (runstate_is_running()) {
505 + qapi_event_send_stop();
506 + qapi_event_send_resume();
507 + return -1;
508 + }
509 +
510 + /*
511 + * WHPX accelerator needs to know whether we are going to step
512 + * any CPUs, before starting the first one.
513 + */
514 + accel_pre_resume(MACHINE(qdev_get_machine()), step_pending);
515 +
516 + /* We are sending this now, but the CPUs will be resumed shortly later */
517 + qapi_event_send_resume();
518 +
519 + cpu_enable_ticks();
520 + runstate_set(state);
521 + vm_state_notify(1, state);
522 + vm_was_suspended = false;
523 + return ret;
524 +}
525 +
526 +void vm_start(void)
527 +{
528 + if (!vm_prepare_start(false)) {
529 + resume_all_vcpus();
530 + }
531 +}
532 +
533 +void vm_resume(RunState state)
534 +{
535 + if (runstate_is_live(state)) {
536 + vm_start();
537 + } else {
538 + runstate_set(state);
539 + }
540 +}
541 +
542 +/*
543 + * does a state transition even if the VM is already stopped,
544 + * current state is forgotten forever
545 + */
546 +int vm_stop_force_state(RunState state)
547 +{
548 + if (runstate_is_live(runstate_get())) {
549 + return vm_stop(state);
550 + } else {
551 + int ret;
552 + runstate_set(state);
553 +
554 + bdrv_drain_all();
555 + /*
556 + * Make sure to return an error if the flush in a previous vm_stop()
557 + * failed.
558 + */
559 + ret = bdrv_flush_all();
560 + trace_vm_stop_flush_all(ret);
561 + return ret;
562 + }
563 +}
564 +
565 static ShutdownCause reset_requested;
566 static ShutdownCause shutdown_requested;
567 static int shutdown_exit_code = EXIT_SUCCESS;