Skip to content

Commit ca05578

Browse files
committed
cpus: Register VMState per user / system emulation
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é <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Message-Id: <[email protected]>
1 parent 1405d7e commit ca05578

File tree

4 files changed

+131
-119
lines changed

4 files changed

+131
-119
lines changed

cpu-target.c

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -21,115 +21,17 @@
2121
#include "qapi/error.h"
2222
#include "qemu/error-report.h"
2323
#include "qemu/qemu-print.h"
24-
#include "migration/vmstate.h"
25-
#ifndef CONFIG_USER_ONLY
26-
#include "hw/core/sysemu-cpu-ops.h"
27-
#endif
2824
#include "system/accel-ops.h"
2925
#include "system/cpus.h"
30-
#include "system/tcg.h"
3126
#include "exec/tswap.h"
3227
#include "exec/replay-core.h"
3328
#include "exec/cpu-common.h"
34-
#include "exec/cputlb.h"
35-
#include "exec/exec-all.h"
36-
#include "exec/tb-flush.h"
3729
#include "exec/log.h"
3830
#include "accel/accel-cpu-target.h"
3931
#include "trace/trace-root.h"
4032
#include "qemu/accel.h"
4133
#include "hw/core/cpu.h"
4234

43-
#ifndef CONFIG_USER_ONLY
44-
static int cpu_common_post_load(void *opaque, int version_id)
45-
{
46-
if (tcg_enabled()) {
47-
CPUState *cpu = opaque;
48-
49-
/*
50-
* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
51-
* version_id is increased.
52-
*/
53-
cpu->interrupt_request &= ~0x01;
54-
55-
tlb_flush(cpu);
56-
57-
/*
58-
* loadvm has just updated the content of RAM, bypassing the
59-
* usual mechanisms that ensure we flush TBs for writes to
60-
* memory we've translated code from. So we must flush all TBs,
61-
* which will now be stale.
62-
*/
63-
tb_flush(cpu);
64-
}
65-
66-
return 0;
67-
}
68-
69-
static int cpu_common_pre_load(void *opaque)
70-
{
71-
CPUState *cpu = opaque;
72-
73-
cpu->exception_index = -1;
74-
75-
return 0;
76-
}
77-
78-
static bool cpu_common_exception_index_needed(void *opaque)
79-
{
80-
CPUState *cpu = opaque;
81-
82-
return tcg_enabled() && cpu->exception_index != -1;
83-
}
84-
85-
static const VMStateDescription vmstate_cpu_common_exception_index = {
86-
.name = "cpu_common/exception_index",
87-
.version_id = 1,
88-
.minimum_version_id = 1,
89-
.needed = cpu_common_exception_index_needed,
90-
.fields = (const VMStateField[]) {
91-
VMSTATE_INT32(exception_index, CPUState),
92-
VMSTATE_END_OF_LIST()
93-
}
94-
};
95-
96-
static bool cpu_common_crash_occurred_needed(void *opaque)
97-
{
98-
CPUState *cpu = opaque;
99-
100-
return cpu->crash_occurred;
101-
}
102-
103-
static const VMStateDescription vmstate_cpu_common_crash_occurred = {
104-
.name = "cpu_common/crash_occurred",
105-
.version_id = 1,
106-
.minimum_version_id = 1,
107-
.needed = cpu_common_crash_occurred_needed,
108-
.fields = (const VMStateField[]) {
109-
VMSTATE_BOOL(crash_occurred, CPUState),
110-
VMSTATE_END_OF_LIST()
111-
}
112-
};
113-
114-
const VMStateDescription vmstate_cpu_common = {
115-
.name = "cpu_common",
116-
.version_id = 1,
117-
.minimum_version_id = 1,
118-
.pre_load = cpu_common_pre_load,
119-
.post_load = cpu_common_post_load,
120-
.fields = (const VMStateField[]) {
121-
VMSTATE_UINT32(halted, CPUState),
122-
VMSTATE_UINT32(interrupt_request, CPUState),
123-
VMSTATE_END_OF_LIST()
124-
},
125-
.subsections = (const VMStateDescription * const []) {
126-
&vmstate_cpu_common_exception_index,
127-
&vmstate_cpu_common_crash_occurred,
128-
NULL
129-
}
130-
};
131-
#endif
132-
13335
bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
13436
{
13537
if (!accel_cpu_common_realize(cpu, errp)) {
@@ -139,33 +41,14 @@ bool cpu_exec_realizefn(CPUState *cpu, Error **errp)
13941
/* Wait until cpu initialization complete before exposing cpu. */
14042
cpu_list_add(cpu);
14143

142-
#ifdef CONFIG_USER_ONLY
143-
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
144-
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
145-
#else
146-
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
147-
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
148-
}
149-
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
150-
vmstate_register(NULL, cpu->cpu_index, cpu->cc->sysemu_ops->legacy_vmsd, cpu);
151-
}
152-
#endif /* CONFIG_USER_ONLY */
44+
cpu_vmstate_register(cpu);
15345

15446
return true;
15547
}
15648

15749
void cpu_exec_unrealizefn(CPUState *cpu)
15850
{
159-
#ifndef CONFIG_USER_ONLY
160-
CPUClass *cc = CPU_GET_CLASS(cpu);
161-
162-
if (cc->sysemu_ops->legacy_vmsd != NULL) {
163-
vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
164-
}
165-
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
166-
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
167-
}
168-
#endif
51+
cpu_vmstate_unregister(cpu);
16952

17053
cpu_list_remove(cpu);
17154
/*

hw/core/cpu-system.c

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,15 @@
2121
#include "qemu/osdep.h"
2222
#include "qapi/error.h"
2323
#include "exec/address-spaces.h"
24+
#include "exec/cputlb.h"
2425
#include "exec/memory.h"
26+
#include "exec/tb-flush.h"
2527
#include "exec/tswap.h"
2628
#include "hw/qdev-core.h"
2729
#include "hw/qdev-properties.h"
2830
#include "hw/core/sysemu-cpu-ops.h"
31+
#include "migration/vmstate.h"
32+
#include "system/tcg.h"
2933

3034
bool cpu_paging_enabled(const CPUState *cpu)
3135
{
@@ -194,3 +198,114 @@ void cpu_exec_initfn(CPUState *cpu)
194198
cpu->memory = get_system_memory();
195199
object_ref(OBJECT(cpu->memory));
196200
}
201+
202+
static int cpu_common_post_load(void *opaque, int version_id)
203+
{
204+
if (tcg_enabled()) {
205+
CPUState *cpu = opaque;
206+
207+
/*
208+
* 0x01 was CPU_INTERRUPT_EXIT. This line can be removed when the
209+
* version_id is increased.
210+
*/
211+
cpu->interrupt_request &= ~0x01;
212+
213+
tlb_flush(cpu);
214+
215+
/*
216+
* loadvm has just updated the content of RAM, bypassing the
217+
* usual mechanisms that ensure we flush TBs for writes to
218+
* memory we've translated code from. So we must flush all TBs,
219+
* which will now be stale.
220+
*/
221+
tb_flush(cpu);
222+
}
223+
224+
return 0;
225+
}
226+
227+
static int cpu_common_pre_load(void *opaque)
228+
{
229+
CPUState *cpu = opaque;
230+
231+
cpu->exception_index = -1;
232+
233+
return 0;
234+
}
235+
236+
static bool cpu_common_exception_index_needed(void *opaque)
237+
{
238+
CPUState *cpu = opaque;
239+
240+
return tcg_enabled() && cpu->exception_index != -1;
241+
}
242+
243+
static const VMStateDescription vmstate_cpu_common_exception_index = {
244+
.name = "cpu_common/exception_index",
245+
.version_id = 1,
246+
.minimum_version_id = 1,
247+
.needed = cpu_common_exception_index_needed,
248+
.fields = (const VMStateField[]) {
249+
VMSTATE_INT32(exception_index, CPUState),
250+
VMSTATE_END_OF_LIST()
251+
}
252+
};
253+
254+
static bool cpu_common_crash_occurred_needed(void *opaque)
255+
{
256+
CPUState *cpu = opaque;
257+
258+
return cpu->crash_occurred;
259+
}
260+
261+
static const VMStateDescription vmstate_cpu_common_crash_occurred = {
262+
.name = "cpu_common/crash_occurred",
263+
.version_id = 1,
264+
.minimum_version_id = 1,
265+
.needed = cpu_common_crash_occurred_needed,
266+
.fields = (const VMStateField[]) {
267+
VMSTATE_BOOL(crash_occurred, CPUState),
268+
VMSTATE_END_OF_LIST()
269+
}
270+
};
271+
272+
const VMStateDescription vmstate_cpu_common = {
273+
.name = "cpu_common",
274+
.version_id = 1,
275+
.minimum_version_id = 1,
276+
.pre_load = cpu_common_pre_load,
277+
.post_load = cpu_common_post_load,
278+
.fields = (const VMStateField[]) {
279+
VMSTATE_UINT32(halted, CPUState),
280+
VMSTATE_UINT32(interrupt_request, CPUState),
281+
VMSTATE_END_OF_LIST()
282+
},
283+
.subsections = (const VMStateDescription * const []) {
284+
&vmstate_cpu_common_exception_index,
285+
&vmstate_cpu_common_crash_occurred,
286+
NULL
287+
}
288+
};
289+
290+
void cpu_vmstate_register(CPUState *cpu)
291+
{
292+
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
293+
vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
294+
}
295+
if (cpu->cc->sysemu_ops->legacy_vmsd != NULL) {
296+
vmstate_register(NULL, cpu->cpu_index,
297+
cpu->cc->sysemu_ops->legacy_vmsd, cpu);
298+
}
299+
}
300+
301+
void cpu_vmstate_unregister(CPUState *cpu)
302+
{
303+
CPUClass *cc = CPU_GET_CLASS(cpu);
304+
305+
if (cc->sysemu_ops->legacy_vmsd != NULL) {
306+
vmstate_unregister(NULL, cc->sysemu_ops->legacy_vmsd, cpu);
307+
}
308+
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
309+
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
310+
}
311+
}

hw/core/cpu-user.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "hw/qdev-core.h"
1111
#include "hw/qdev-properties.h"
1212
#include "hw/core/cpu.h"
13+
#include "migration/vmstate.h"
1314

1415
static const Property cpu_user_props[] = {
1516
/*
@@ -30,3 +31,14 @@ void cpu_exec_initfn(CPUState *cpu)
3031
{
3132
/* nothing to do */
3233
}
34+
35+
void cpu_vmstate_register(CPUState *cpu)
36+
{
37+
assert(qdev_get_vmsd(DEVICE(cpu)) == NULL ||
38+
qdev_get_vmsd(DEVICE(cpu))->unmigratable);
39+
}
40+
41+
void cpu_vmstate_unregister(CPUState *cpu)
42+
{
43+
/* nothing to do */
44+
}

include/hw/core/cpu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,8 @@ G_NORETURN void cpu_abort(CPUState *cpu, const char *fmt, ...)
11651165
/* $(top_srcdir)/cpu.c */
11661166
void cpu_class_init_props(DeviceClass *dc);
11671167
void cpu_exec_initfn(CPUState *cpu);
1168+
void cpu_vmstate_register(CPUState *cpu);
1169+
void cpu_vmstate_unregister(CPUState *cpu);
11681170
bool cpu_exec_realizefn(CPUState *cpu, Error **errp);
11691171
void cpu_exec_unrealizefn(CPUState *cpu);
11701172
void cpu_exec_reset_hold(CPUState *cpu);

0 commit comments

Comments
 (0)