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;