From: "Philippe Mathieu-Daudé" <philmd@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 05/38] cpus: Register VMState per user / system emulation
Date: Sun, 9 Mar 2025 18:51:34 +0100 [thread overview]
Message-ID: <20250309175207.43828-6-philmd@linaro.org> (raw)
In-Reply-To: <20250309175207.43828-1-philmd@linaro.org>
Simplify cpu-target.c by extracting mixed vmstate code
into the cpu_vmstate_register() / cpu_vmstate_unregister()
helpers, implemented in cpu-user.c and cpu-system.c.
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20250123234415.59850-20-philmd@linaro.org>
---
include/hw/core/cpu.h | 2 +
cpu-target.c | 121 +-----------------------------------------
hw/core/cpu-system.c | 115 +++++++++++++++++++++++++++++++++++++++
hw/core/cpu-user.c | 12 +++++
4 files changed, 131 insertions(+), 119 deletions(-)
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 9dd6ac7c763..bc0c9468344 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -1165,6 +1165,8 @@ G_NORETURN void cpu_abort(CPUState *cpu, const char *fmt, ...)
/* $(top_srcdir)/cpu.c */
void cpu_class_init_props(DeviceClass *dc);
void cpu_exec_initfn(CPUState *cpu);
+void cpu_vmstate_register(CPUState *cpu);
+void cpu_vmstate_unregister(CPUState *cpu);
bool cpu_exec_realizefn(CPUState *cpu, Error **errp);
void cpu_exec_unrealizefn(CPUState *cpu);
void cpu_exec_reset_hold(CPUState *cpu);
diff --git a/cpu-target.c b/cpu-target.c
index b6e66d5ac02..bc9c537c575 100644
--- a/cpu-target.c
+++ b/cpu-target.c
@@ -21,115 +21,17 @@
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/qemu-print.h"
-#include "migration/vmstate.h"
-#ifndef CONFIG_USER_ONLY
-#include "hw/core/sysemu-cpu-ops.h"
-#endif
#include "system/accel-ops.h"
#include "system/cpus.h"
-#include "system/tcg.h"
#include "exec/tswap.h"
#include "exec/replay-core.h"
#include "exec/cpu-common.h"
-#include "exec/cputlb.h"
-#include "exec/exec-all.h"
-#include "exec/tb-flush.h"
#include "exec/log.h"
#include "accel/accel-cpu-target.h"
#include "trace/trace-root.h"
#include "qemu/accel.h"
#include "hw/core/cpu.h"
-#ifndef CONFIG_USER_ONLY
-static int cpu_common_post_load(void *opaque, int version_id)
-{
- if (tcg_enabled()) {
- CPUState *cpu = opaque;
-
- /*
- * 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
- * version_id is increased.
- */
- cpu->interrupt_request &= ~0x01;
-
- tlb_flush(cpu);
-
- /*
- * loadvm has just updated the content of RAM, bypassing the
- * usual mechanisms that ensure we flush TBs for writes to
- * memory we've translated code from. So we must flush all TBs,
- * which will now be stale.
- */
- tb_flush(cpu);
- }
-
- return 0;
-}
-
-static int cpu_common_pre_load(void *opaque)
-{
- CPUState *cpu = opaque;
-
- cpu->exception_index = -1;
-
- return 0;
-}
-
-static bool cpu_common_exception_index_needed(void *opaque)
-{
- CPUState *cpu = opaque;
-
- return tcg_enabled() && cpu->exception_index != -1;
-}
-
-static const VMStateDescription vmstate_cpu_common_exception_index = {
- .name = "cpu_common/exception_index",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = cpu_common_exception_index_needed,
- .fields = (const VMStateField[]) {
- VMSTATE_INT32(exception_index, CPUState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-static bool cpu_common_crash_occurred_needed(void *opaque)
-{
- CPUState *cpu = opaque;
-
- return cpu->crash_occurred;
-}
-
-static const VMStateDescription vmstate_cpu_common_crash_occurred = {
- .name = "cpu_common/crash_occurred",
- .version_id = 1,
- .minimum_version_id = 1,
- .needed = cpu_common_crash_occurred_needed,
- .fields = (const VMStateField[]) {
- VMSTATE_BOOL(crash_occurred, CPUState),
- VMSTATE_END_OF_LIST()
- }
-};
-
-const VMStateDescription vmstate_cpu_common = {
- .name = "cpu_common",
- .version_id = 1,
- .minimum_version_id = 1,
- .pre_load = cpu_common_pre_load,
- .post_load = cpu_common_post_load,
- .fields = (const VMStateField[]) {
- VMSTATE_UINT32(halted, CPUState),
- VMSTATE_UINT32(interrupt_request, CPUState),
- VMSTATE_END_OF_LIST()
- },
- .subsections = (const VMStateDescription * const []) {
- &vmstate_cpu_common_exception_index,
- &vmstate_cpu_common_crash_occurred,
- NULL
- }
-};
-#endif
-
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
{
if (!accel_cpu_common_realize(cpu, errp)) {
@@ -139,33 +41,14 @@ bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
/* Wait until cpu initialization complete before exposing cpu. */
cpu_list_add(cpu);
-#ifdef CONFIG_USER_ONLY
- assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
- qdev_get_vmsd(DEVICE(cpu))->unmigratable);
-#else
- if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
- vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
- }
- if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
- vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
- }
-#endif /* CONFIG_USER_ONLY */
+ cpu_vmstate_register(cpu);
return true;
}
void cpu_exec_unrealizefn(CPUState *cpu)
{
-#ifndef CONFIG_USER_ONLY
- CPUClass *cc = CPU_GET_CLASS(cpu);
-
- if (cc->sysemu_ops->legacy_vmsd != NULL) {
- vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
- }
- if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
- vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
- }
-#endif
+ cpu_vmstate_unregister(cpu);
cpu_list_remove(cpu);
/*
diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c
index e511507e13b..6c89d76e498 100644
--- a/hw/core/cpu-system.c
+++ b/hw/core/cpu-system.c
@@ -21,11 +21,15 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "exec/address-spaces.h"
+#include "exec/cputlb.h"
#include "exec/memory.h"
+#include "exec/tb-flush.h"
#include "exec/tswap.h"
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/core/sysemu-cpu-ops.h"
+#include "migration/vmstate.h"
+#include "system/tcg.h"
bool cpu_paging_enabled(const CPUState *cpu)
{
@@ -194,3 +198,114 @@ void cpu_exec_initfn(CPUState *cpu)
cpu->memory = get_system_memory();
object_ref(OBJECT(cpu->memory));
}
+
+static int cpu_common_post_load(void *opaque, int version_id)
+{
+ if (tcg_enabled()) {
+ CPUState *cpu = opaque;
+
+ /*
+ * 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
+ * version_id is increased.
+ */
+ cpu->interrupt_request &= ~0x01;
+
+ tlb_flush(cpu);
+
+ /*
+ * loadvm has just updated the content of RAM, bypassing the
+ * usual mechanisms that ensure we flush TBs for writes to
+ * memory we've translated code from. So we must flush all TBs,
+ * which will now be stale.
+ */
+ tb_flush(cpu);
+ }
+
+ return 0;
+}
+
+static int cpu_common_pre_load(void *opaque)
+{
+ CPUState *cpu = opaque;
+
+ cpu->exception_index = -1;
+
+ return 0;
+}
+
+static bool cpu_common_exception_index_needed(void *opaque)
+{
+ CPUState *cpu = opaque;
+
+ return tcg_enabled() && cpu->exception_index != -1;
+}
+
+static const VMStateDescription vmstate_cpu_common_exception_index = {
+ .name = "cpu_common/exception_index",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = cpu_common_exception_index_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_INT32(exception_index, CPUState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+static bool cpu_common_crash_occurred_needed(void *opaque)
+{
+ CPUState *cpu = opaque;
+
+ return cpu->crash_occurred;
+}
+
+static const VMStateDescription vmstate_cpu_common_crash_occurred = {
+ .name = "cpu_common/crash_occurred",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .needed = cpu_common_crash_occurred_needed,
+ .fields = (const VMStateField[]) {
+ VMSTATE_BOOL(crash_occurred, CPUState),
+ VMSTATE_END_OF_LIST()
+ }
+};
+
+const VMStateDescription vmstate_cpu_common = {
+ .name = "cpu_common",
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .pre_load = cpu_common_pre_load,
+ .post_load = cpu_common_post_load,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32(halted, CPUState),
+ VMSTATE_UINT32(interrupt_request, CPUState),
+ VMSTATE_END_OF_LIST()
+ },
+ .subsections = (const VMStateDescription * const []) {
+ &vmstate_cpu_common_exception_index,
+ &vmstate_cpu_common_crash_occurred,
+ NULL
+ }
+};
+
+void cpu_vmstate_register(CPUState *cpu)
+{
+ if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+ vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
+ }
+ if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
+ vmstate_register(NULL, cpu->cpu_index,
+ cpu->cc->sysemu_ops->legacy_vmsd, cpu);
+ }
+}
+
+void cpu_vmstate_unregister(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->sysemu_ops->legacy_vmsd != NULL) {
+ vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
+ }
+ if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+ vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
+ }
+}
diff --git a/hw/core/cpu-user.c b/hw/core/cpu-user.c
index cdd8de2fefa..1892acdee0f 100644
--- a/hw/core/cpu-user.c
+++ b/hw/core/cpu-user.c
@@ -10,6 +10,7 @@
#include "hw/qdev-core.h"
#include "hw/qdev-properties.h"
#include "hw/core/cpu.h"
+#include "migration/vmstate.h"
static const Property cpu_user_props[] = {
/*
@@ -30,3 +31,14 @@ void cpu_exec_initfn(CPUState *cpu)
{
/* nothing to do */
}
+
+void cpu_vmstate_register(CPUState *cpu)
+{
+ assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
+ qdev_get_vmsd(DEVICE(cpu))->unmigratable);
+}
+
+void cpu_vmstate_unregister(CPUState *cpu)
+{
+ /* nothing to do */
+}
--
2.47.1
next prev parent reply other threads:[~2025-03-09 18:01 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-09 17:51 [PULL 00/38] Accelerators & CPU patches for 2025-03-09 Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 01/38] linux-user: Only include 'exec/tb-flush.h' header when necessary Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 02/38] bsd-user: Always use mmap_find_vma_aligned() in target_mmap() Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 03/38] bsd-user: Propagate alignment argument to mmap_find_vma() Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 04/38] user: Extract common MMAP API to 'user/mmap.h' Philippe Mathieu-Daudé
2025-03-09 17:51 ` Philippe Mathieu-Daudé [this message]
2025-03-09 17:51 ` [PULL 06/38] cpus: Build cpu_exec_[un]realizefn() methods once Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 07/38] cpus: Prefer cached CpuClass over CPU_GET_CLASS() macro Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 08/38] accel: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 09/38] user: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 10/38] disas: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 11/38] gdbstub: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 12/38] hw/acpi: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 13/38] target/arm: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 14/38] cpus: Restrict cpu_has_work() to system emulation Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 15/38] cpus: Un-inline cpu_has_work() Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 16/38] cpus: Introduce SysemuCPUOps::has_work() handler Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 17/38] target/alpha: Move has_work() from CPUClass to SysemuCPUOps Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 18/38] target/arm: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 19/38] target/avr: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 20/38] target/hexagon: Remove CPUClass:has_work() handler Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 21/38] target/hppa: Move has_work() from CPUClass to SysemuCPUOps Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 22/38] target/i386: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 23/38] target/loongarch: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 24/38] target/m68k: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 25/38] target/microblaze: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 26/38] target/mips: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 27/38] target/openrisc: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 28/38] target/ppc: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 29/38] target/riscv: " Philippe Mathieu-Daudé
2025-03-09 17:51 ` [PULL 30/38] target/rx: " Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 31/38] target/s390x: Restrict I/O handler installers to system emulation Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 32/38] target/s390x: Move has_work() from CPUClass to SysemuCPUOps Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 33/38] target/sh4: " Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 34/38] target/sparc: " Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 35/38] target/tricore: " Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 36/38] target/xtensa: " Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 37/38] cpus: Remove CPUClass::has_work() handler Philippe Mathieu-Daudé
2025-03-09 17:52 ` [PULL 38/38] MAINTAINERS: Consolidate core exec/vCPU handling section Philippe Mathieu-Daudé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250309175207.43828-6-philmd@linaro.org \
--to=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).