blob: 0b26bc68dde9e95012ee212203ebb6719e0d591b [file] [log] [blame]
Paolo Bonzini701a8f72012-01-13 17:07:20 +01001/*
2 * QEMU migration/snapshot declarations
3 *
4 * Copyright (c) 2009-2011 Red Hat, Inc.
5 *
6 * Original author: Juan Quintela <quintela@redhat.com>
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26#ifndef QEMU_VMSTATE_H
27#define QEMU_VMSTATE_H 1
28
Peter Maydellec3f8c92013-06-27 20:53:38 +010029#ifndef CONFIG_USER_ONLY
Paolo Bonzinifd7f0d62013-02-04 10:57:50 +010030#include <migration/qemu-file.h>
Peter Maydellec3f8c92013-06-27 20:53:38 +010031#endif
Alexander Graf8118f092015-01-22 15:01:39 +010032#include <qjson.h>
Paolo Bonzinifd7f0d62013-02-04 10:57:50 +010033
Paolo Bonzini701a8f72012-01-13 17:07:20 +010034typedef void SaveStateHandler(QEMUFile *f, void *opaque);
Paolo Bonzini701a8f72012-01-13 17:07:20 +010035typedef int LoadStateHandler(QEMUFile *f, void *opaque, int version_id);
36
Juan Quintela22ea40f2012-06-26 17:19:10 +020037typedef struct SaveVMHandlers {
Paolo Bonzini32c835b2013-02-22 17:36:27 +010038 /* This runs inside the iothread lock. */
Juan Quintela86253682012-06-26 18:51:00 +020039 void (*set_params)(const MigrationParams *params, void * opaque);
Juan Quintela22ea40f2012-06-26 17:19:10 +020040 SaveStateHandler *save_state;
Paolo Bonzini8c8de192013-02-22 17:36:26 +010041
Juan Quintela9b5bfab2012-06-26 19:26:41 +020042 void (*cancel)(void *opaque);
Paolo Bonzini8c8de192013-02-22 17:36:26 +010043 int (*save_live_complete)(QEMUFile *f, void *opaque);
Paolo Bonzini32c835b2013-02-22 17:36:27 +010044
45 /* This runs both outside and inside the iothread lock. */
Juan Quintela6bd68782012-06-27 10:59:15 +020046 bool (*is_active)(void *opaque);
Paolo Bonzini32c835b2013-02-22 17:36:27 +010047
48 /* This runs outside the iothread lock in the migration case, and
49 * within the lock in the savevm case. The callback had better only
50 * use data that is local to the migration thread or protected
51 * by other locks.
52 */
Paolo Bonzini8c8de192013-02-22 17:36:26 +010053 int (*save_live_iterate)(QEMUFile *f, void *opaque);
Paolo Bonzini32c835b2013-02-22 17:36:27 +010054
55 /* This runs outside the iothread lock! */
Paolo Bonzini9b095032013-02-22 17:36:28 +010056 int (*save_live_setup)(QEMUFile *f, void *opaque);
Paolo Bonzini8c8de192013-02-22 17:36:26 +010057 uint64_t (*save_live_pending)(QEMUFile *f, void *opaque, uint64_t max_size);
58
59 LoadStateHandler *load_state;
Juan Quintela22ea40f2012-06-26 17:19:10 +020060} SaveVMHandlers;
61
Paolo Bonzini701a8f72012-01-13 17:07:20 +010062int register_savevm(DeviceState *dev,
63 const char *idstr,
64 int instance_id,
65 int version_id,
66 SaveStateHandler *save_state,
67 LoadStateHandler *load_state,
68 void *opaque);
69
70int register_savevm_live(DeviceState *dev,
71 const char *idstr,
72 int instance_id,
73 int version_id,
Juan Quintela7908c782012-06-26 18:46:10 +020074 SaveVMHandlers *ops,
Paolo Bonzini701a8f72012-01-13 17:07:20 +010075 void *opaque);
76
77void unregister_savevm(DeviceState *dev, const char *idstr, void *opaque);
78void register_device_unmigratable(DeviceState *dev, const char *idstr,
79 void *opaque);
80
81
82typedef struct VMStateInfo VMStateInfo;
83typedef struct VMStateDescription VMStateDescription;
84
85struct VMStateInfo {
86 const char *name;
87 int (*get)(QEMUFile *f, void *pv, size_t size);
88 void (*put)(QEMUFile *f, void *pv, size_t size);
89};
90
91enum VMStateFlags {
92 VMS_SINGLE = 0x001,
93 VMS_POINTER = 0x002,
94 VMS_ARRAY = 0x004,
95 VMS_STRUCT = 0x008,
96 VMS_VARRAY_INT32 = 0x010, /* Array with size in int32_t field*/
97 VMS_BUFFER = 0x020, /* static sized buffer */
98 VMS_ARRAY_OF_POINTER = 0x040,
99 VMS_VARRAY_UINT16 = 0x080, /* Array with size in uint16_t field */
100 VMS_VBUFFER = 0x100, /* Buffer with size in int32_t field */
101 VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */
102 VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/
103 VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/
Michael S. Tsirkin5bf81c82014-04-03 19:50:31 +0300104 VMS_MUST_EXIST = 0x1000, /* Field must exist in input */
Alexey Kardashevskiyf32935e2014-05-30 19:34:19 +1000105 VMS_ALLOC = 0x2000, /* Alloc a buffer on the destination */
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100106};
107
108typedef struct {
109 const char *name;
110 size_t offset;
111 size_t size;
112 size_t start;
113 int num;
114 size_t num_offset;
115 size_t size_offset;
116 const VMStateInfo *info;
117 enum VMStateFlags flags;
118 const VMStateDescription *vmsd;
119 int version_id;
120 bool (*field_exists)(void *opaque, int version_id);
121} VMStateField;
122
123typedef struct VMStateSubsection {
124 const VMStateDescription *vmsd;
125 bool (*needed)(void *opaque);
126} VMStateSubsection;
127
128struct VMStateDescription {
129 const char *name;
130 int unmigratable;
131 int version_id;
132 int minimum_version_id;
133 int minimum_version_id_old;
134 LoadStateHandler *load_state_old;
135 int (*pre_load)(void *opaque);
136 int (*post_load)(void *opaque, int version_id);
137 void (*pre_save)(void *opaque);
138 VMStateField *fields;
139 const VMStateSubsection *subsections;
140};
141
Andreas Färberc71c3e92013-02-18 17:56:20 +0100142#ifdef CONFIG_USER_ONLY
143extern const VMStateDescription vmstate_dummy;
144#endif
145
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100146extern const VMStateInfo vmstate_info_bool;
147
148extern const VMStateInfo vmstate_info_int8;
149extern const VMStateInfo vmstate_info_int16;
150extern const VMStateInfo vmstate_info_int32;
151extern const VMStateInfo vmstate_info_int64;
152
153extern const VMStateInfo vmstate_info_uint8_equal;
154extern const VMStateInfo vmstate_info_uint16_equal;
155extern const VMStateInfo vmstate_info_int32_equal;
156extern const VMStateInfo vmstate_info_uint32_equal;
David Gibsone344b8a2013-03-12 14:06:00 +1100157extern const VMStateInfo vmstate_info_uint64_equal;
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100158extern const VMStateInfo vmstate_info_int32_le;
159
160extern const VMStateInfo vmstate_info_uint8;
161extern const VMStateInfo vmstate_info_uint16;
162extern const VMStateInfo vmstate_info_uint32;
163extern const VMStateInfo vmstate_info_uint64;
164
David Gibson213945e2013-03-12 14:06:02 +1100165extern const VMStateInfo vmstate_info_float64;
166
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100167extern const VMStateInfo vmstate_info_timer;
168extern const VMStateInfo vmstate_info_buffer;
169extern const VMStateInfo vmstate_info_unused_buffer;
Peter Maydell08e99e22012-10-30 07:45:12 +0000170extern const VMStateInfo vmstate_info_bitmap;
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100171
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100172#define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100173#define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0)
174#define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0)
175
176#define vmstate_offset_value(_state, _field, _type) \
177 (offsetof(_state, _field) + \
178 type_check(_type, typeof_field(_state, _field)))
179
180#define vmstate_offset_pointer(_state, _field, _type) \
181 (offsetof(_state, _field) + \
182 type_check_pointer(_type, typeof_field(_state, _field)))
183
184#define vmstate_offset_array(_state, _field, _type, _num) \
185 (offsetof(_state, _field) + \
186 type_check_array(_type, typeof_field(_state, _field), _num))
187
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100188#define vmstate_offset_2darray(_state, _field, _type, _n1, _n2) \
189 (offsetof(_state, _field) + \
190 type_check_2darray(_type, typeof_field(_state, _field), _n1, _n2))
191
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100192#define vmstate_offset_sub_array(_state, _field, _type, _start) \
Paolo Bonziniea987c22015-01-07 15:12:13 +0100193 vmstate_offset_value(_state, _field[_start], _type)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100194
195#define vmstate_offset_buffer(_state, _field) \
196 vmstate_offset_array(_state, _field, uint8_t, \
197 sizeof(typeof_field(_state, _field)))
198
199#define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \
200 .name = (stringify(_field)), \
201 .version_id = (_version), \
202 .field_exists = (_test), \
203 .size = sizeof(_type), \
204 .info = &(_info), \
205 .flags = VMS_SINGLE, \
206 .offset = vmstate_offset_value(_state, _field, _type), \
207}
208
Michael S. Tsirkin4082f082014-04-03 19:50:35 +0300209/* Validate state using a boolean predicate. */
210#define VMSTATE_VALIDATE(_name, _test) { \
211 .name = (_name), \
212 .field_exists = (_test), \
213 .flags = VMS_ARRAY | VMS_MUST_EXIST, \
214 .num = 0, /* 0 elements: no data, only run _test */ \
215}
216
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100217#define VMSTATE_POINTER(_field, _state, _version, _info, _type) { \
218 .name = (stringify(_field)), \
219 .version_id = (_version), \
220 .info = &(_info), \
221 .size = sizeof(_type), \
222 .flags = VMS_SINGLE|VMS_POINTER, \
223 .offset = vmstate_offset_value(_state, _field, _type), \
224}
225
226#define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) { \
227 .name = (stringify(_field)), \
228 .info = &(_info), \
229 .field_exists = (_test), \
230 .size = sizeof(_type), \
231 .flags = VMS_SINGLE|VMS_POINTER, \
232 .offset = vmstate_offset_value(_state, _field, _type), \
233}
234
235#define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\
236 .name = (stringify(_field)), \
237 .version_id = (_version), \
238 .num = (_num), \
239 .info = &(_info), \
240 .size = sizeof(_type), \
241 .flags = VMS_ARRAY, \
242 .offset = vmstate_offset_array(_state, _field, _type, _num), \
243}
244
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100245#define VMSTATE_2DARRAY(_field, _state, _n1, _n2, _version, _info, _type) { \
246 .name = (stringify(_field)), \
247 .version_id = (_version), \
248 .num = (_n1) * (_n2), \
249 .info = &(_info), \
250 .size = sizeof(_type), \
251 .flags = VMS_ARRAY, \
252 .offset = vmstate_offset_2darray(_state, _field, _type, _n1, _n2), \
253}
254
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100255#define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\
256 .name = (stringify(_field)), \
257 .field_exists = (_test), \
258 .num = (_num), \
259 .info = &(_info), \
260 .size = sizeof(_type), \
261 .flags = VMS_ARRAY, \
262 .offset = vmstate_offset_array(_state, _field, _type, _num),\
263}
264
265#define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \
266 .name = (stringify(_field)), \
267 .version_id = (_version), \
268 .num = (_num), \
269 .info = &(_info), \
270 .size = sizeof(_type), \
271 .flags = VMS_ARRAY, \
272 .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \
273}
274
275#define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\
276 .name = (stringify(_field)), \
277 .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
278 .info = &(_info), \
279 .size = sizeof(_type), \
280 .flags = VMS_VARRAY_INT32, \
281 .offset = offsetof(_state, _field), \
282}
283
284#define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\
285 .name = (stringify(_field)), \
286 .version_id = (_version), \
287 .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
288 .info = &(_info), \
289 .size = sizeof(_type), \
290 .flags = VMS_VARRAY_INT32|VMS_POINTER, \
291 .offset = vmstate_offset_pointer(_state, _field, _type), \
292}
293
294#define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\
295 .name = (stringify(_field)), \
296 .version_id = (_version), \
297 .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
298 .info = &(_info), \
299 .size = sizeof(_type), \
300 .flags = VMS_VARRAY_UINT32|VMS_POINTER, \
301 .offset = vmstate_offset_pointer(_state, _field, _type), \
302}
303
304#define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\
305 .name = (stringify(_field)), \
306 .version_id = (_version), \
307 .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\
308 .info = &(_info), \
309 .size = sizeof(_type), \
310 .flags = VMS_VARRAY_UINT16, \
311 .offset = offsetof(_state, _field), \
312}
313
314#define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \
315 .name = (stringify(_field)), \
316 .version_id = (_version), \
317 .field_exists = (_test), \
318 .vmsd = &(_vmsd), \
319 .size = sizeof(_type), \
320 .flags = VMS_STRUCT, \
321 .offset = vmstate_offset_value(_state, _field, _type), \
322}
323
Alexey Kardashevskiy71024002013-09-04 14:35:26 +1000324#define VMSTATE_STRUCT_POINTER_V(_field, _state, _version, _vmsd, _type) { \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100325 .name = (stringify(_field)), \
Alexey Kardashevskiy71024002013-09-04 14:35:26 +1000326 .version_id = (_version), \
327 .vmsd = &(_vmsd), \
Peter Maydell20bcf732014-01-01 21:56:57 +0000328 .size = sizeof(_type *), \
Alexey Kardashevskiy71024002013-09-04 14:35:26 +1000329 .flags = VMS_STRUCT|VMS_POINTER, \
Peter Maydell20bcf732014-01-01 21:56:57 +0000330 .offset = vmstate_offset_pointer(_state, _field, _type), \
Alexey Kardashevskiy71024002013-09-04 14:35:26 +1000331}
332
333#define VMSTATE_STRUCT_POINTER_TEST_V(_field, _state, _test, _version, _vmsd, _type) { \
334 .name = (stringify(_field)), \
335 .version_id = (_version), \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100336 .field_exists = (_test), \
337 .vmsd = &(_vmsd), \
Peter Maydell20bcf732014-01-01 21:56:57 +0000338 .size = sizeof(_type *), \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100339 .flags = VMS_STRUCT|VMS_POINTER, \
Peter Maydell20bcf732014-01-01 21:56:57 +0000340 .offset = vmstate_offset_pointer(_state, _field, _type), \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100341}
342
343#define VMSTATE_ARRAY_OF_POINTER(_field, _state, _num, _version, _info, _type) {\
344 .name = (stringify(_field)), \
345 .version_id = (_version), \
346 .num = (_num), \
347 .info = &(_info), \
348 .size = sizeof(_type), \
349 .flags = VMS_ARRAY|VMS_ARRAY_OF_POINTER, \
350 .offset = vmstate_offset_array(_state, _field, _type, _num), \
351}
352
Peter Maydella1f05e72013-12-17 19:42:37 +0000353#define VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(_f, _s, _n, _v, _vmsd, _type) { \
354 .name = (stringify(_f)), \
355 .version_id = (_v), \
356 .num = (_n), \
357 .vmsd = &(_vmsd), \
358 .size = sizeof(_type *), \
359 .flags = VMS_ARRAY|VMS_STRUCT|VMS_ARRAY_OF_POINTER, \
360 .offset = vmstate_offset_array(_s, _f, _type*, _n), \
361}
362
Paolo Bonzinia03c3e92014-10-24 10:18:38 +0200363#define VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, _num, _version, _vmsd, _type) { \
364 .name = (stringify(_field)), \
365 .version_id = (_version), \
366 .num = (_num), \
367 .vmsd = &(_vmsd), \
368 .size = sizeof(_type), \
369 .flags = VMS_STRUCT|VMS_ARRAY, \
370 .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \
371}
372
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100373#define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \
374 .name = (stringify(_field)), \
375 .num = (_num), \
376 .field_exists = (_test), \
377 .version_id = (_version), \
378 .vmsd = &(_vmsd), \
379 .size = sizeof(_type), \
380 .flags = VMS_STRUCT|VMS_ARRAY, \
381 .offset = vmstate_offset_array(_state, _field, _type, _num),\
382}
383
384#define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \
385 .name = (stringify(_field)), \
386 .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \
387 .version_id = (_version), \
388 .vmsd = &(_vmsd), \
389 .size = sizeof(_type), \
390 .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \
391 .offset = offsetof(_state, _field), \
392}
393
394#define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \
395 .name = (stringify(_field)), \
396 .version_id = 0, \
397 .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
398 .size = sizeof(_type), \
399 .vmsd = &(_vmsd), \
400 .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \
401 .offset = vmstate_offset_pointer(_state, _field, _type), \
402}
403
David Gibson8474a9d2013-03-12 14:06:03 +1100404#define VMSTATE_STRUCT_VARRAY_POINTER_UINT32(_field, _state, _field_num, _vmsd, _type) { \
405 .name = (stringify(_field)), \
406 .version_id = 0, \
407 .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\
408 .size = sizeof(_type), \
409 .vmsd = &(_vmsd), \
410 .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \
411 .offset = vmstate_offset_pointer(_state, _field, _type), \
412}
413
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100414#define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \
415 .name = (stringify(_field)), \
416 .version_id = 0, \
417 .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\
418 .size = sizeof(_type), \
419 .vmsd = &(_vmsd), \
420 .flags = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT, \
421 .offset = vmstate_offset_pointer(_state, _field, _type), \
422}
423
424#define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \
425 .name = (stringify(_field)), \
426 .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
427 .version_id = (_version), \
428 .vmsd = &(_vmsd), \
429 .size = sizeof(_type), \
430 .flags = VMS_STRUCT|VMS_VARRAY_INT32, \
431 .offset = offsetof(_state, _field), \
432}
433
434#define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \
435 .name = (stringify(_field)), \
436 .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \
437 .version_id = (_version), \
438 .vmsd = &(_vmsd), \
439 .size = sizeof(_type), \
440 .flags = VMS_STRUCT|VMS_VARRAY_UINT32, \
441 .offset = offsetof(_state, _field), \
442}
443
Alexey Kardashevskiyf32935e2014-05-30 19:34:19 +1000444#define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\
445 .name = (stringify(_field)), \
446 .version_id = (_version), \
447 .vmsd = &(_vmsd), \
448 .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \
449 .size = sizeof(_type), \
450 .flags = VMS_STRUCT|VMS_VARRAY_INT32|VMS_ALLOC|VMS_POINTER, \
451 .offset = vmstate_offset_pointer(_state, _field, _type), \
452}
453
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100454#define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \
455 .name = (stringify(_field)), \
456 .version_id = (_version), \
457 .field_exists = (_test), \
458 .size = (_size - _start), \
459 .info = &vmstate_info_buffer, \
460 .flags = VMS_BUFFER, \
461 .offset = vmstate_offset_buffer(_state, _field) + _start, \
462}
463
David Gibson377e2cb2013-03-12 14:06:04 +1100464#define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, _start, _field_size, _multiply) { \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100465 .name = (stringify(_field)), \
466 .version_id = (_version), \
467 .field_exists = (_test), \
468 .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\
469 .size = (_multiply), \
470 .info = &vmstate_info_buffer, \
David Gibson377e2cb2013-03-12 14:06:04 +1100471 .flags = VMS_VBUFFER|VMS_POINTER|VMS_MULTIPLY, \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100472 .offset = offsetof(_state, _field), \
473 .start = (_start), \
474}
475
476#define VMSTATE_VBUFFER(_field, _state, _version, _test, _start, _field_size) { \
477 .name = (stringify(_field)), \
478 .version_id = (_version), \
479 .field_exists = (_test), \
480 .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\
481 .info = &vmstate_info_buffer, \
482 .flags = VMS_VBUFFER|VMS_POINTER, \
483 .offset = offsetof(_state, _field), \
484 .start = (_start), \
485}
486
487#define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _start, _field_size) { \
488 .name = (stringify(_field)), \
489 .version_id = (_version), \
490 .field_exists = (_test), \
491 .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\
492 .info = &vmstate_info_buffer, \
493 .flags = VMS_VBUFFER|VMS_POINTER, \
494 .offset = offsetof(_state, _field), \
495 .start = (_start), \
496}
497
Alexey Kardashevskiy94ed7062014-10-02 19:56:02 +1000498#define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, _test, _start, _field_size) { \
499 .name = (stringify(_field)), \
500 .version_id = (_version), \
501 .field_exists = (_test), \
502 .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\
503 .info = &vmstate_info_buffer, \
504 .flags = VMS_VBUFFER|VMS_POINTER|VMS_ALLOC, \
505 .offset = offsetof(_state, _field), \
506 .start = (_start), \
507}
508
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100509#define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) { \
510 .name = (stringify(_field)), \
511 .version_id = (_version), \
512 .size = (_size), \
513 .info = &(_info), \
514 .flags = VMS_BUFFER, \
515 .offset = offsetof(_state, _field), \
516}
517
Igor Mitsyanko80705682013-04-05 16:17:58 +0100518#define VMSTATE_BUFFER_POINTER_UNSAFE(_field, _state, _version, _size) { \
519 .name = (stringify(_field)), \
520 .version_id = (_version), \
521 .size = (_size), \
522 .info = &vmstate_info_buffer, \
523 .flags = VMS_BUFFER|VMS_POINTER, \
524 .offset = offsetof(_state, _field), \
525}
526
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100527#define VMSTATE_UNUSED_BUFFER(_test, _version, _size) { \
528 .name = "unused", \
529 .field_exists = (_test), \
530 .version_id = (_version), \
531 .size = (_size), \
532 .info = &vmstate_info_unused_buffer, \
533 .flags = VMS_BUFFER, \
534}
535
Peter Maydell08e99e22012-10-30 07:45:12 +0000536/* _field_size should be a int32_t field in the _state struct giving the
537 * size of the bitmap _field in bits.
538 */
539#define VMSTATE_BITMAP(_field, _state, _version, _field_size) { \
540 .name = (stringify(_field)), \
541 .version_id = (_version), \
542 .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\
543 .info = &vmstate_info_bitmap, \
544 .flags = VMS_VBUFFER|VMS_POINTER, \
545 .offset = offsetof(_state, _field), \
546}
547
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100548/* _f : field name
549 _f_n : num of elements field_name
550 _n : num of elements
551 _s : struct state name
552 _v : version
553*/
554
555#define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \
556 VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type)
557
558#define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) \
559 VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type)
560
561#define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \
Alexey Kardashevskiy71024002013-09-04 14:35:26 +1000562 VMSTATE_STRUCT_POINTER_V(_field, _state, 0, _vmsd, _type)
563
564#define VMSTATE_STRUCT_POINTER_TEST(_field, _state, _test, _vmsd, _type) \
565 VMSTATE_STRUCT_POINTER_TEST_V(_field, _state, _test, 0, _vmsd, _type)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100566
567#define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \
568 VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, \
569 _vmsd, _type)
570
571#define VMSTATE_BOOL_V(_f, _s, _v) \
572 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool)
573
574#define VMSTATE_INT8_V(_f, _s, _v) \
575 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t)
576#define VMSTATE_INT16_V(_f, _s, _v) \
577 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int16, int16_t)
578#define VMSTATE_INT32_V(_f, _s, _v) \
579 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int32, int32_t)
580#define VMSTATE_INT64_V(_f, _s, _v) \
581 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int64, int64_t)
582
583#define VMSTATE_UINT8_V(_f, _s, _v) \
584 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, uint8_t)
585#define VMSTATE_UINT16_V(_f, _s, _v) \
586 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, uint16_t)
587#define VMSTATE_UINT32_V(_f, _s, _v) \
588 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, uint32_t)
589#define VMSTATE_UINT64_V(_f, _s, _v) \
590 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t)
591
592#define VMSTATE_BOOL(_f, _s) \
593 VMSTATE_BOOL_V(_f, _s, 0)
594
595#define VMSTATE_INT8(_f, _s) \
596 VMSTATE_INT8_V(_f, _s, 0)
597#define VMSTATE_INT16(_f, _s) \
598 VMSTATE_INT16_V(_f, _s, 0)
599#define VMSTATE_INT32(_f, _s) \
600 VMSTATE_INT32_V(_f, _s, 0)
601#define VMSTATE_INT64(_f, _s) \
602 VMSTATE_INT64_V(_f, _s, 0)
603
604#define VMSTATE_UINT8(_f, _s) \
605 VMSTATE_UINT8_V(_f, _s, 0)
606#define VMSTATE_UINT16(_f, _s) \
607 VMSTATE_UINT16_V(_f, _s, 0)
608#define VMSTATE_UINT32(_f, _s) \
609 VMSTATE_UINT32_V(_f, _s, 0)
610#define VMSTATE_UINT64(_f, _s) \
611 VMSTATE_UINT64_V(_f, _s, 0)
612
613#define VMSTATE_UINT8_EQUAL(_f, _s) \
614 VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint8_equal, uint8_t)
615
616#define VMSTATE_UINT16_EQUAL(_f, _s) \
617 VMSTATE_SINGLE(_f, _s, 0, vmstate_info_uint16_equal, uint16_t)
618
619#define VMSTATE_UINT16_EQUAL_V(_f, _s, _v) \
620 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16_equal, uint16_t)
621
622#define VMSTATE_INT32_EQUAL(_f, _s) \
623 VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_equal, int32_t)
624
David Gibsond58f5592013-03-12 14:06:01 +1100625#define VMSTATE_UINT32_EQUAL_V(_f, _s, _v) \
626 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32_equal, uint32_t)
627
628#define VMSTATE_UINT32_EQUAL(_f, _s) \
629 VMSTATE_UINT32_EQUAL_V(_f, _s, 0)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100630
David Gibsone344b8a2013-03-12 14:06:00 +1100631#define VMSTATE_UINT64_EQUAL_V(_f, _s, _v) \
632 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64_equal, uint64_t)
633
634#define VMSTATE_UINT64_EQUAL(_f, _s) \
635 VMSTATE_UINT64_EQUAL_V(_f, _s, 0)
636
Michael S. Tsirkin34764362014-04-03 19:52:21 +0300637#define VMSTATE_INT32_POSITIVE_LE(_f, _s) \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100638 VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t)
639
640#define VMSTATE_UINT8_TEST(_f, _s, _t) \
641 VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t)
642
643#define VMSTATE_UINT16_TEST(_f, _s, _t) \
644 VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t)
645
646#define VMSTATE_UINT32_TEST(_f, _s, _t) \
647 VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t)
648
David Gibson213945e2013-03-12 14:06:02 +1100649
650#define VMSTATE_FLOAT64_V(_f, _s, _v) \
651 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_float64, float64)
652
653#define VMSTATE_FLOAT64(_f, _s) \
654 VMSTATE_FLOAT64_V(_f, _s, 0)
655
Paolo Bonzinie7206772015-01-08 10:18:59 +0100656#define VMSTATE_TIMER_PTR_TEST(_f, _s, _test) \
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100657 VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *)
658
Paolo Bonzinie7206772015-01-08 10:18:59 +0100659#define VMSTATE_TIMER_PTR_V(_f, _s, _v) \
Paolo Bonzini02815182012-08-02 18:04:08 +0200660 VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *)
661
Paolo Bonzinie7206772015-01-08 10:18:59 +0100662#define VMSTATE_TIMER_PTR(_f, _s) \
663 VMSTATE_TIMER_PTR_V(_f, _s, 0)
664
665#define VMSTATE_TIMER_PTR_ARRAY(_f, _s, _n) \
666 VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *)
667
668#define VMSTATE_TIMER_TEST(_f, _s, _test) \
669 VMSTATE_SINGLE_TEST(_f, _s, _test, 0, vmstate_info_timer, QEMUTimer)
670
671#define VMSTATE_TIMER_V(_f, _s, _v) \
672 VMSTATE_SINGLE(_f, _s, _v, vmstate_info_timer, QEMUTimer)
673
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100674#define VMSTATE_TIMER(_f, _s) \
Paolo Bonzini02815182012-08-02 18:04:08 +0200675 VMSTATE_TIMER_V(_f, _s, 0)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100676
677#define VMSTATE_TIMER_ARRAY(_f, _s, _n) \
Paolo Bonzinie7206772015-01-08 10:18:59 +0100678 VMSTATE_ARRAY(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer)
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100679
680#define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \
681 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool)
682
683#define VMSTATE_BOOL_ARRAY(_f, _s, _n) \
684 VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0)
685
686#define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \
687 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t)
688
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100689#define VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, _v) \
690 VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint16, uint16_t)
691
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100692#define VMSTATE_UINT16_ARRAY(_f, _s, _n) \
693 VMSTATE_UINT16_ARRAY_V(_f, _s, _n, 0)
694
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100695#define VMSTATE_UINT16_2DARRAY(_f, _s, _n1, _n2) \
696 VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, 0)
697
698#define VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, _v) \
699 VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint8, uint8_t)
700
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100701#define VMSTATE_UINT8_ARRAY_V(_f, _s, _n, _v) \
702 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint8, uint8_t)
703
704#define VMSTATE_UINT8_ARRAY(_f, _s, _n) \
705 VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0)
706
Fam Zheng2e323f02014-03-06 16:26:02 +0800707#define VMSTATE_UINT8_SUB_ARRAY(_f, _s, _start, _num) \
708 VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint8, uint8_t)
709
Peter Maydellbd7f92e2013-04-05 16:17:59 +0100710#define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2) \
711 VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0)
712
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100713#define VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) \
714 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint32, uint32_t)
715
Christoffer Dalla1b1d272013-09-20 20:35:06 +0100716#define VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, _v) \
717 VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint32, uint32_t)
718
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100719#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
720 VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
721
Christoffer Dalla1b1d272013-09-20 20:35:06 +0100722#define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \
723 VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0)
724
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100725#define VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) \
726 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint64, uint64_t)
727
728#define VMSTATE_UINT64_ARRAY(_f, _s, _n) \
729 VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0)
730
731#define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \
732 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t)
733
734#define VMSTATE_INT16_ARRAY(_f, _s, _n) \
735 VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0)
736
737#define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v) \
738 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t)
739
740#define VMSTATE_INT32_ARRAY(_f, _s, _n) \
741 VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0)
742
743#define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \
744 VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t)
745
746#define VMSTATE_UINT32_ARRAY(_f, _s, _n) \
747 VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0)
748
749#define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \
750 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t)
751
752#define VMSTATE_INT64_ARRAY(_f, _s, _n) \
753 VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0)
754
David Gibson213945e2013-03-12 14:06:02 +1100755#define VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, _v) \
756 VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_float64, float64)
757
758#define VMSTATE_FLOAT64_ARRAY(_f, _s, _n) \
759 VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, 0)
760
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100761#define VMSTATE_BUFFER_V(_f, _s, _v) \
762 VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f)))
763
764#define VMSTATE_BUFFER(_f, _s) \
765 VMSTATE_BUFFER_V(_f, _s, 0)
766
767#define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \
768 VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size)
769
770#define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \
771 VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f)))
772
773#define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \
774 VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size)
775
776#define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size) \
777 VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, 0, _size)
778
779#define VMSTATE_SUB_VBUFFER(_f, _s, _start, _size) \
780 VMSTATE_VBUFFER(_f, _s, 0, NULL, _start, _size)
781
782#define VMSTATE_BUFFER_TEST(_f, _s, _test) \
783 VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f)))
784
785#define VMSTATE_BUFFER_UNSAFE(_field, _state, _version, _size) \
786 VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, vmstate_info_buffer, _size)
787
788#define VMSTATE_UNUSED_V(_v, _size) \
789 VMSTATE_UNUSED_BUFFER(NULL, _v, _size)
790
791#define VMSTATE_UNUSED(_size) \
792 VMSTATE_UNUSED_V(0, _size)
793
794#define VMSTATE_UNUSED_TEST(_test, _size) \
795 VMSTATE_UNUSED_BUFFER(_test, 0, _size)
796
797#define VMSTATE_END_OF_LIST() \
798 {}
799
Jason Wang110f4632014-05-20 14:01:42 +0800800#define SELF_ANNOUNCE_ROUNDS 5
801
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100802int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
803 void *opaque, int version_id);
804void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
Alexander Graf8118f092015-01-22 15:01:39 +0100805 void *opaque, QJSON *vmdesc);
Andreas Färberd7650ea2013-02-18 21:41:59 +0100806
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100807int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,
808 const VMStateDescription *vmsd,
809 void *base, int alias_id,
810 int required_for_version);
Andreas Färberd7650ea2013-02-18 21:41:59 +0100811
812static inline int vmstate_register(DeviceState *dev, int instance_id,
813 const VMStateDescription *vmsd,
814 void *opaque)
815{
816 return vmstate_register_with_alias_id(dev, instance_id, vmsd,
817 opaque, -1, 0);
818}
819
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100820void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,
821 void *opaque);
822
823struct MemoryRegion;
824void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev);
825void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev);
826void vmstate_register_ram_global(struct MemoryRegion *memory);
827
Jason Wang508e1182014-05-20 14:01:43 +0800828static inline
829int64_t self_announce_delay(int round)
830{
831 assert(round < SELF_ANNOUNCE_ROUNDS && round > 0);
832 /* delay 50ms, 150ms, 250ms, ... */
833 return 50 + (SELF_ANNOUNCE_ROUNDS - round - 1) * 100;
834}
835
Amit Shahabfd9ce2014-06-20 18:56:08 +0530836void dump_vmstate_json_to_file(FILE *out_fp);
837
Paolo Bonzini701a8f72012-01-13 17:07:20 +0100838#endif