1 | /* |
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 | |
27 | #ifndef QEMU_VMSTATE_H |
28 | #define QEMU_VMSTATE_H |
29 | |
30 | typedef struct VMStateInfo VMStateInfo; |
31 | typedef struct VMStateField VMStateField; |
32 | |
33 | /* VMStateInfo allows customized migration of objects that don't fit in |
34 | * any category in VMStateFlags. Additional information is always passed |
35 | * into get and put in terms of field and vmdesc parameters. However |
36 | * these two parameters should only be used in cases when customized |
37 | * handling is needed, such as QTAILQ. For primitive data types such as |
38 | * integer, field and vmdesc parameters should be ignored inside get/put. |
39 | */ |
40 | struct VMStateInfo { |
41 | const char *name; |
42 | int (*get)(QEMUFile *f, void *pv, size_t size, const VMStateField *field); |
43 | int (*put)(QEMUFile *f, void *pv, size_t size, const VMStateField *field, |
44 | QJSON *vmdesc); |
45 | }; |
46 | |
47 | enum VMStateFlags { |
48 | /* Ignored */ |
49 | VMS_SINGLE = 0x001, |
50 | |
51 | /* The struct member at opaque + VMStateField.offset is a pointer |
52 | * to the actual field (e.g. struct a { uint8_t *b; |
53 | * }). Dereference the pointer before using it as basis for |
54 | * further pointer arithmetic (see e.g. VMS_ARRAY). Does not |
55 | * affect the meaning of VMStateField.num_offset or |
56 | * VMStateField.size_offset; see VMS_VARRAY* and VMS_VBUFFER for |
57 | * those. */ |
58 | VMS_POINTER = 0x002, |
59 | |
60 | /* The field is an array of fixed size. VMStateField.num contains |
61 | * the number of entries in the array. The size of each entry is |
62 | * given by VMStateField.size and / or opaque + |
63 | * VMStateField.size_offset; see VMS_VBUFFER and |
64 | * VMS_MULTIPLY. Each array entry will be processed individually |
65 | * (VMStateField.info.get()/put() if VMS_STRUCT is not set, |
66 | * recursion into VMStateField.vmsd if VMS_STRUCT is set). May not |
67 | * be combined with VMS_VARRAY*. */ |
68 | VMS_ARRAY = 0x004, |
69 | |
70 | /* The field is itself a struct, containing one or more |
71 | * fields. Recurse into VMStateField.vmsd. Most useful in |
72 | * combination with VMS_ARRAY / VMS_VARRAY*, recursing into each |
73 | * array entry. */ |
74 | VMS_STRUCT = 0x008, |
75 | |
76 | /* The field is an array of variable size. The int32_t at opaque + |
77 | * VMStateField.num_offset contains the number of entries in the |
78 | * array. See the VMS_ARRAY description regarding array handling |
79 | * in general. May not be combined with VMS_ARRAY or any other |
80 | * VMS_VARRAY*. */ |
81 | VMS_VARRAY_INT32 = 0x010, |
82 | |
83 | /* Ignored */ |
84 | VMS_BUFFER = 0x020, |
85 | |
86 | /* The field is a (fixed-size or variable-size) array of pointers |
87 | * (e.g. struct a { uint8_t *b[]; }). Dereference each array entry |
88 | * before using it. Note: Does not imply any one of VMS_ARRAY / |
89 | * VMS_VARRAY*; these need to be set explicitly. */ |
90 | VMS_ARRAY_OF_POINTER = 0x040, |
91 | |
92 | /* The field is an array of variable size. The uint16_t at opaque |
93 | * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) |
94 | * contains the number of entries in the array. See the VMS_ARRAY |
95 | * description regarding array handling in general. May not be |
96 | * combined with VMS_ARRAY or any other VMS_VARRAY*. */ |
97 | VMS_VARRAY_UINT16 = 0x080, |
98 | |
99 | /* The size of the individual entries (a single array entry if |
100 | * VMS_ARRAY or any of VMS_VARRAY* are set, or the field itself if |
101 | * neither is set) is variable (i.e. not known at compile-time), |
102 | * but the same for all entries. Use the int32_t at opaque + |
103 | * VMStateField.size_offset (subject to VMS_MULTIPLY) to determine |
104 | * the size of each (and every) entry. */ |
105 | VMS_VBUFFER = 0x100, |
106 | |
107 | /* Multiply the entry size given by the int32_t at opaque + |
108 | * VMStateField.size_offset (see VMS_VBUFFER description) with |
109 | * VMStateField.size to determine the number of bytes to be |
110 | * allocated. Only valid in combination with VMS_VBUFFER. */ |
111 | VMS_MULTIPLY = 0x200, |
112 | |
113 | /* The field is an array of variable size. The uint8_t at opaque + |
114 | * VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) |
115 | * contains the number of entries in the array. See the VMS_ARRAY |
116 | * description regarding array handling in general. May not be |
117 | * combined with VMS_ARRAY or any other VMS_VARRAY*. */ |
118 | VMS_VARRAY_UINT8 = 0x400, |
119 | |
120 | /* The field is an array of variable size. The uint32_t at opaque |
121 | * + VMStateField.num_offset (subject to VMS_MULTIPLY_ELEMENTS) |
122 | * contains the number of entries in the array. See the VMS_ARRAY |
123 | * description regarding array handling in general. May not be |
124 | * combined with VMS_ARRAY or any other VMS_VARRAY*. */ |
125 | VMS_VARRAY_UINT32 = 0x800, |
126 | |
127 | /* Fail loading the serialised VM state if this field is missing |
128 | * from the input. */ |
129 | VMS_MUST_EXIST = 0x1000, |
130 | |
131 | /* When loading serialised VM state, allocate memory for the |
132 | * (entire) field. Only valid in combination with |
133 | * VMS_POINTER. Note: Not all combinations with other flags are |
134 | * currently supported, e.g. VMS_ALLOC|VMS_ARRAY_OF_POINTER won't |
135 | * cause the individual entries to be allocated. */ |
136 | VMS_ALLOC = 0x2000, |
137 | |
138 | /* Multiply the number of entries given by the integer at opaque + |
139 | * VMStateField.num_offset (see VMS_VARRAY*) with VMStateField.num |
140 | * to determine the number of entries in the array. Only valid in |
141 | * combination with one of VMS_VARRAY*. */ |
142 | VMS_MULTIPLY_ELEMENTS = 0x4000, |
143 | |
144 | /* A structure field that is like VMS_STRUCT, but uses |
145 | * VMStateField.struct_version_id to tell which version of the |
146 | * structure we are referencing to use. */ |
147 | VMS_VSTRUCT = 0x8000, |
148 | }; |
149 | |
150 | typedef enum { |
151 | MIG_PRI_DEFAULT = 0, |
152 | MIG_PRI_IOMMU, /* Must happen before PCI devices */ |
153 | MIG_PRI_PCI_BUS, /* Must happen before IOMMU */ |
154 | MIG_PRI_GICV3_ITS, /* Must happen before PCI devices */ |
155 | MIG_PRI_GICV3, /* Must happen before the ITS */ |
156 | MIG_PRI_MAX, |
157 | } MigrationPriority; |
158 | |
159 | struct VMStateField { |
160 | const char *name; |
161 | const char *err_hint; |
162 | size_t offset; |
163 | size_t size; |
164 | size_t start; |
165 | int num; |
166 | size_t num_offset; |
167 | size_t size_offset; |
168 | const VMStateInfo *info; |
169 | enum VMStateFlags flags; |
170 | const VMStateDescription *vmsd; |
171 | int version_id; |
172 | int struct_version_id; |
173 | bool (*field_exists)(void *opaque, int version_id); |
174 | }; |
175 | |
176 | struct VMStateDescription { |
177 | const char *name; |
178 | int unmigratable; |
179 | int version_id; |
180 | int minimum_version_id; |
181 | int minimum_version_id_old; |
182 | MigrationPriority priority; |
183 | LoadStateHandler *load_state_old; |
184 | int (*pre_load)(void *opaque); |
185 | int (*post_load)(void *opaque, int version_id); |
186 | int (*pre_save)(void *opaque); |
187 | int (*post_save)(void *opaque); |
188 | bool (*needed)(void *opaque); |
189 | const VMStateField *fields; |
190 | const VMStateDescription **subsections; |
191 | }; |
192 | |
193 | extern const VMStateDescription vmstate_dummy; |
194 | |
195 | extern const VMStateInfo vmstate_info_bool; |
196 | |
197 | extern const VMStateInfo vmstate_info_int8; |
198 | extern const VMStateInfo vmstate_info_int16; |
199 | extern const VMStateInfo vmstate_info_int32; |
200 | extern const VMStateInfo vmstate_info_int64; |
201 | |
202 | extern const VMStateInfo vmstate_info_uint8_equal; |
203 | extern const VMStateInfo vmstate_info_uint16_equal; |
204 | extern const VMStateInfo vmstate_info_int32_equal; |
205 | extern const VMStateInfo vmstate_info_uint32_equal; |
206 | extern const VMStateInfo vmstate_info_uint64_equal; |
207 | extern const VMStateInfo vmstate_info_int32_le; |
208 | |
209 | extern const VMStateInfo vmstate_info_uint8; |
210 | extern const VMStateInfo vmstate_info_uint16; |
211 | extern const VMStateInfo vmstate_info_uint32; |
212 | extern const VMStateInfo vmstate_info_uint64; |
213 | |
214 | /** Put this in the stream when migrating a null pointer.*/ |
215 | #define VMS_NULLPTR_MARKER (0x30U) /* '0' */ |
216 | extern const VMStateInfo vmstate_info_nullptr; |
217 | |
218 | extern const VMStateInfo vmstate_info_float64; |
219 | extern const VMStateInfo vmstate_info_cpudouble; |
220 | |
221 | extern const VMStateInfo vmstate_info_timer; |
222 | extern const VMStateInfo vmstate_info_buffer; |
223 | extern const VMStateInfo vmstate_info_unused_buffer; |
224 | extern const VMStateInfo vmstate_info_tmp; |
225 | extern const VMStateInfo vmstate_info_bitmap; |
226 | extern const VMStateInfo vmstate_info_qtailq; |
227 | |
228 | #define type_check_2darray(t1,t2,n,m) ((t1(*)[n][m])0 - (t2*)0) |
229 | /* |
230 | * Check that type t2 is an array of type t1 of size n, |
231 | * e.g. if t1 is 'foo' and n is 32 then t2 must be 'foo[32]' |
232 | */ |
233 | #define type_check_array(t1,t2,n) ((t1(*)[n])0 - (t2*)0) |
234 | #define type_check_pointer(t1,t2) ((t1**)0 - (t2*)0) |
235 | /* |
236 | * type of element 0 of the specified (array) field of the type. |
237 | * Note that if the field is a pointer then this will return the |
238 | * pointed-to type rather than complaining. |
239 | */ |
240 | #define typeof_elt_of_field(type, field) typeof(((type *)0)->field[0]) |
241 | /* Check that field f in struct type t2 is an array of t1, of any size */ |
242 | #define type_check_varray(t1, t2, f) \ |
243 | (type_check(t1, typeof_elt_of_field(t2, f)) \ |
244 | + QEMU_BUILD_BUG_ON_ZERO(!QEMU_IS_ARRAY(((t2 *)0)->f))) |
245 | |
246 | #define vmstate_offset_value(_state, _field, _type) \ |
247 | (offsetof(_state, _field) + \ |
248 | type_check(_type, typeof_field(_state, _field))) |
249 | |
250 | #define vmstate_offset_pointer(_state, _field, _type) \ |
251 | (offsetof(_state, _field) + \ |
252 | type_check_pointer(_type, typeof_field(_state, _field))) |
253 | |
254 | #define vmstate_offset_array(_state, _field, _type, _num) \ |
255 | (offsetof(_state, _field) + \ |
256 | type_check_array(_type, typeof_field(_state, _field), _num)) |
257 | |
258 | #define vmstate_offset_2darray(_state, _field, _type, _n1, _n2) \ |
259 | (offsetof(_state, _field) + \ |
260 | type_check_2darray(_type, typeof_field(_state, _field), _n1, _n2)) |
261 | |
262 | #define vmstate_offset_sub_array(_state, _field, _type, _start) \ |
263 | vmstate_offset_value(_state, _field[_start], _type) |
264 | |
265 | #define vmstate_offset_buffer(_state, _field) \ |
266 | vmstate_offset_array(_state, _field, uint8_t, \ |
267 | sizeof(typeof_field(_state, _field))) |
268 | |
269 | #define vmstate_offset_varray(_state, _field, _type) \ |
270 | (offsetof(_state, _field) + \ |
271 | type_check_varray(_type, _state, _field)) |
272 | |
273 | /* In the macros below, if there is a _version, that means the macro's |
274 | * field will be processed only if the version being received is >= |
275 | * the _version specified. In general, if you add a new field, you |
276 | * would increment the structure's version and put that version |
277 | * number into the new field so it would only be processed with the |
278 | * new version. |
279 | * |
280 | * In particular, for VMSTATE_STRUCT() and friends the _version does |
281 | * *NOT* pick the version of the sub-structure. It works just as |
282 | * specified above. The version of the top-level structure received |
283 | * is passed down to all sub-structures. This means that the |
284 | * sub-structures must have version that are compatible with all the |
285 | * structures that use them. |
286 | * |
287 | * If you want to specify the version of the sub-structure, use |
288 | * VMSTATE_VSTRUCT(), which allows the specific sub-structure version |
289 | * to be directly specified. |
290 | */ |
291 | |
292 | #define VMSTATE_SINGLE_TEST(_field, _state, _test, _version, _info, _type) { \ |
293 | .name = (stringify(_field)), \ |
294 | .version_id = (_version), \ |
295 | .field_exists = (_test), \ |
296 | .size = sizeof(_type), \ |
297 | .info = &(_info), \ |
298 | .flags = VMS_SINGLE, \ |
299 | .offset = vmstate_offset_value(_state, _field, _type), \ |
300 | } |
301 | |
302 | #define VMSTATE_SINGLE_FULL(_field, _state, _test, _version, _info, \ |
303 | _type, _err_hint) { \ |
304 | .name = (stringify(_field)), \ |
305 | .err_hint = (_err_hint), \ |
306 | .version_id = (_version), \ |
307 | .field_exists = (_test), \ |
308 | .size = sizeof(_type), \ |
309 | .info = &(_info), \ |
310 | .flags = VMS_SINGLE, \ |
311 | .offset = vmstate_offset_value(_state, _field, _type), \ |
312 | } |
313 | |
314 | /* Validate state using a boolean predicate. */ |
315 | #define VMSTATE_VALIDATE(_name, _test) { \ |
316 | .name = (_name), \ |
317 | .field_exists = (_test), \ |
318 | .flags = VMS_ARRAY | VMS_MUST_EXIST, \ |
319 | .num = 0, /* 0 elements: no data, only run _test */ \ |
320 | } |
321 | |
322 | #define VMSTATE_POINTER(_field, _state, _version, _info, _type) { \ |
323 | .name = (stringify(_field)), \ |
324 | .version_id = (_version), \ |
325 | .info = &(_info), \ |
326 | .size = sizeof(_type), \ |
327 | .flags = VMS_SINGLE|VMS_POINTER, \ |
328 | .offset = vmstate_offset_value(_state, _field, _type), \ |
329 | } |
330 | |
331 | #define VMSTATE_POINTER_TEST(_field, _state, _test, _info, _type) { \ |
332 | .name = (stringify(_field)), \ |
333 | .info = &(_info), \ |
334 | .field_exists = (_test), \ |
335 | .size = sizeof(_type), \ |
336 | .flags = VMS_SINGLE|VMS_POINTER, \ |
337 | .offset = vmstate_offset_value(_state, _field, _type), \ |
338 | } |
339 | |
340 | #define VMSTATE_ARRAY(_field, _state, _num, _version, _info, _type) {\ |
341 | .name = (stringify(_field)), \ |
342 | .version_id = (_version), \ |
343 | .num = (_num), \ |
344 | .info = &(_info), \ |
345 | .size = sizeof(_type), \ |
346 | .flags = VMS_ARRAY, \ |
347 | .offset = vmstate_offset_array(_state, _field, _type, _num), \ |
348 | } |
349 | |
350 | #define VMSTATE_2DARRAY(_field, _state, _n1, _n2, _version, _info, _type) { \ |
351 | .name = (stringify(_field)), \ |
352 | .version_id = (_version), \ |
353 | .num = (_n1) * (_n2), \ |
354 | .info = &(_info), \ |
355 | .size = sizeof(_type), \ |
356 | .flags = VMS_ARRAY, \ |
357 | .offset = vmstate_offset_2darray(_state, _field, _type, _n1, _n2), \ |
358 | } |
359 | |
360 | #define VMSTATE_VARRAY_MULTIPLY(_field, _state, _field_num, _multiply, _info, _type) { \ |
361 | .name = (stringify(_field)), \ |
362 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ |
363 | .num = (_multiply), \ |
364 | .info = &(_info), \ |
365 | .size = sizeof(_type), \ |
366 | .flags = VMS_VARRAY_UINT32|VMS_MULTIPLY_ELEMENTS, \ |
367 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
368 | } |
369 | |
370 | #define VMSTATE_ARRAY_TEST(_field, _state, _num, _test, _info, _type) {\ |
371 | .name = (stringify(_field)), \ |
372 | .field_exists = (_test), \ |
373 | .num = (_num), \ |
374 | .info = &(_info), \ |
375 | .size = sizeof(_type), \ |
376 | .flags = VMS_ARRAY, \ |
377 | .offset = vmstate_offset_array(_state, _field, _type, _num),\ |
378 | } |
379 | |
380 | #define VMSTATE_SUB_ARRAY(_field, _state, _start, _num, _version, _info, _type) { \ |
381 | .name = (stringify(_field)), \ |
382 | .version_id = (_version), \ |
383 | .num = (_num), \ |
384 | .info = &(_info), \ |
385 | .size = sizeof(_type), \ |
386 | .flags = VMS_ARRAY, \ |
387 | .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \ |
388 | } |
389 | |
390 | #define VMSTATE_ARRAY_INT32_UNSAFE(_field, _state, _field_num, _info, _type) {\ |
391 | .name = (stringify(_field)), \ |
392 | .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ |
393 | .info = &(_info), \ |
394 | .size = sizeof(_type), \ |
395 | .flags = VMS_VARRAY_INT32, \ |
396 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
397 | } |
398 | |
399 | #define VMSTATE_VARRAY_INT32(_field, _state, _field_num, _version, _info, _type) {\ |
400 | .name = (stringify(_field)), \ |
401 | .version_id = (_version), \ |
402 | .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ |
403 | .info = &(_info), \ |
404 | .size = sizeof(_type), \ |
405 | .flags = VMS_VARRAY_INT32|VMS_POINTER, \ |
406 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
407 | } |
408 | |
409 | #define VMSTATE_VARRAY_UINT32(_field, _state, _field_num, _version, _info, _type) {\ |
410 | .name = (stringify(_field)), \ |
411 | .version_id = (_version), \ |
412 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ |
413 | .info = &(_info), \ |
414 | .size = sizeof(_type), \ |
415 | .flags = VMS_VARRAY_UINT32|VMS_POINTER, \ |
416 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
417 | } |
418 | |
419 | #define VMSTATE_VARRAY_UINT32_ALLOC(_field, _state, _field_num, _version, _info, _type) {\ |
420 | .name = (stringify(_field)), \ |
421 | .version_id = (_version), \ |
422 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ |
423 | .info = &(_info), \ |
424 | .size = sizeof(_type), \ |
425 | .flags = VMS_VARRAY_UINT32|VMS_POINTER|VMS_ALLOC, \ |
426 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
427 | } |
428 | |
429 | #define VMSTATE_VARRAY_UINT16_UNSAFE(_field, _state, _field_num, _version, _info, _type) {\ |
430 | .name = (stringify(_field)), \ |
431 | .version_id = (_version), \ |
432 | .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ |
433 | .info = &(_info), \ |
434 | .size = sizeof(_type), \ |
435 | .flags = VMS_VARRAY_UINT16, \ |
436 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
437 | } |
438 | |
439 | #define VMSTATE_VSTRUCT_TEST(_field, _state, _test, _version, _vmsd, _type, _struct_version) { \ |
440 | .name = (stringify(_field)), \ |
441 | .version_id = (_version), \ |
442 | .struct_version_id = (_struct_version), \ |
443 | .field_exists = (_test), \ |
444 | .vmsd = &(_vmsd), \ |
445 | .size = sizeof(_type), \ |
446 | .flags = VMS_VSTRUCT, \ |
447 | .offset = vmstate_offset_value(_state, _field, _type), \ |
448 | } |
449 | |
450 | #define VMSTATE_STRUCT_TEST(_field, _state, _test, _version, _vmsd, _type) { \ |
451 | .name = (stringify(_field)), \ |
452 | .version_id = (_version), \ |
453 | .field_exists = (_test), \ |
454 | .vmsd = &(_vmsd), \ |
455 | .size = sizeof(_type), \ |
456 | .flags = VMS_STRUCT, \ |
457 | .offset = vmstate_offset_value(_state, _field, _type), \ |
458 | } |
459 | |
460 | #define VMSTATE_STRUCT_POINTER_V(_field, _state, _version, _vmsd, _type) { \ |
461 | .name = (stringify(_field)), \ |
462 | .version_id = (_version), \ |
463 | .vmsd = &(_vmsd), \ |
464 | .size = sizeof(_type *), \ |
465 | .flags = VMS_STRUCT|VMS_POINTER, \ |
466 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
467 | } |
468 | |
469 | #define VMSTATE_STRUCT_POINTER_TEST_V(_field, _state, _test, _version, _vmsd, _type) { \ |
470 | .name = (stringify(_field)), \ |
471 | .version_id = (_version), \ |
472 | .field_exists = (_test), \ |
473 | .vmsd = &(_vmsd), \ |
474 | .size = sizeof(_type *), \ |
475 | .flags = VMS_STRUCT|VMS_POINTER, \ |
476 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
477 | } |
478 | |
479 | #define VMSTATE_ARRAY_OF_POINTER(_field, _state, _num, _version, _info, _type) {\ |
480 | .name = (stringify(_field)), \ |
481 | .version_id = (_version), \ |
482 | .num = (_num), \ |
483 | .info = &(_info), \ |
484 | .size = sizeof(_type), \ |
485 | .flags = VMS_ARRAY|VMS_ARRAY_OF_POINTER, \ |
486 | .offset = vmstate_offset_array(_state, _field, _type, _num), \ |
487 | } |
488 | |
489 | #define VMSTATE_ARRAY_OF_POINTER_TO_STRUCT(_f, _s, _n, _v, _vmsd, _type) { \ |
490 | .name = (stringify(_f)), \ |
491 | .version_id = (_v), \ |
492 | .num = (_n), \ |
493 | .vmsd = &(_vmsd), \ |
494 | .size = sizeof(_type *), \ |
495 | .flags = VMS_ARRAY|VMS_STRUCT|VMS_ARRAY_OF_POINTER, \ |
496 | .offset = vmstate_offset_array(_s, _f, _type*, _n), \ |
497 | } |
498 | |
499 | #define VMSTATE_STRUCT_SUB_ARRAY(_field, _state, _start, _num, _version, _vmsd, _type) { \ |
500 | .name = (stringify(_field)), \ |
501 | .version_id = (_version), \ |
502 | .num = (_num), \ |
503 | .vmsd = &(_vmsd), \ |
504 | .size = sizeof(_type), \ |
505 | .flags = VMS_STRUCT|VMS_ARRAY, \ |
506 | .offset = vmstate_offset_sub_array(_state, _field, _type, _start), \ |
507 | } |
508 | |
509 | #define VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, _test, _version, _vmsd, _type) { \ |
510 | .name = (stringify(_field)), \ |
511 | .num = (_num), \ |
512 | .field_exists = (_test), \ |
513 | .version_id = (_version), \ |
514 | .vmsd = &(_vmsd), \ |
515 | .size = sizeof(_type), \ |
516 | .flags = VMS_STRUCT|VMS_ARRAY, \ |
517 | .offset = vmstate_offset_array(_state, _field, _type, _num),\ |
518 | } |
519 | |
520 | #define VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, _test, \ |
521 | _version, _vmsd, _type) { \ |
522 | .name = (stringify(_field)), \ |
523 | .num = (_n1) * (_n2), \ |
524 | .field_exists = (_test), \ |
525 | .version_id = (_version), \ |
526 | .vmsd = &(_vmsd), \ |
527 | .size = sizeof(_type), \ |
528 | .flags = VMS_STRUCT | VMS_ARRAY, \ |
529 | .offset = vmstate_offset_2darray(_state, _field, _type, \ |
530 | _n1, _n2), \ |
531 | } |
532 | |
533 | #define VMSTATE_STRUCT_VARRAY_UINT8(_field, _state, _field_num, _version, _vmsd, _type) { \ |
534 | .name = (stringify(_field)), \ |
535 | .num_offset = vmstate_offset_value(_state, _field_num, uint8_t), \ |
536 | .version_id = (_version), \ |
537 | .vmsd = &(_vmsd), \ |
538 | .size = sizeof(_type), \ |
539 | .flags = VMS_STRUCT|VMS_VARRAY_UINT8, \ |
540 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
541 | } |
542 | |
543 | /* a variable length array (i.e. _type *_field) but we know the |
544 | * length |
545 | */ |
546 | #define VMSTATE_STRUCT_VARRAY_POINTER_KNOWN(_field, _state, _num, _version, _vmsd, _type) { \ |
547 | .name = (stringify(_field)), \ |
548 | .num = (_num), \ |
549 | .version_id = (_version), \ |
550 | .vmsd = &(_vmsd), \ |
551 | .size = sizeof(_type), \ |
552 | .flags = VMS_STRUCT|VMS_ARRAY|VMS_POINTER, \ |
553 | .offset = offsetof(_state, _field), \ |
554 | } |
555 | |
556 | #define VMSTATE_STRUCT_VARRAY_POINTER_INT32(_field, _state, _field_num, _vmsd, _type) { \ |
557 | .name = (stringify(_field)), \ |
558 | .version_id = 0, \ |
559 | .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ |
560 | .size = sizeof(_type), \ |
561 | .vmsd = &(_vmsd), \ |
562 | .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \ |
563 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
564 | } |
565 | |
566 | #define VMSTATE_STRUCT_VARRAY_POINTER_UINT32(_field, _state, _field_num, _vmsd, _type) { \ |
567 | .name = (stringify(_field)), \ |
568 | .version_id = 0, \ |
569 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ |
570 | .size = sizeof(_type), \ |
571 | .vmsd = &(_vmsd), \ |
572 | .flags = VMS_POINTER | VMS_VARRAY_INT32 | VMS_STRUCT, \ |
573 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
574 | } |
575 | |
576 | #define VMSTATE_STRUCT_VARRAY_POINTER_UINT16(_field, _state, _field_num, _vmsd, _type) { \ |
577 | .name = (stringify(_field)), \ |
578 | .version_id = 0, \ |
579 | .num_offset = vmstate_offset_value(_state, _field_num, uint16_t),\ |
580 | .size = sizeof(_type), \ |
581 | .vmsd = &(_vmsd), \ |
582 | .flags = VMS_POINTER | VMS_VARRAY_UINT16 | VMS_STRUCT, \ |
583 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
584 | } |
585 | |
586 | #define VMSTATE_STRUCT_VARRAY_INT32(_field, _state, _field_num, _version, _vmsd, _type) { \ |
587 | .name = (stringify(_field)), \ |
588 | .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ |
589 | .version_id = (_version), \ |
590 | .vmsd = &(_vmsd), \ |
591 | .size = sizeof(_type), \ |
592 | .flags = VMS_STRUCT|VMS_VARRAY_INT32, \ |
593 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
594 | } |
595 | |
596 | #define VMSTATE_STRUCT_VARRAY_UINT32(_field, _state, _field_num, _version, _vmsd, _type) { \ |
597 | .name = (stringify(_field)), \ |
598 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t), \ |
599 | .version_id = (_version), \ |
600 | .vmsd = &(_vmsd), \ |
601 | .size = sizeof(_type), \ |
602 | .flags = VMS_STRUCT|VMS_VARRAY_UINT32, \ |
603 | .offset = vmstate_offset_varray(_state, _field, _type), \ |
604 | } |
605 | |
606 | #define VMSTATE_STRUCT_VARRAY_ALLOC(_field, _state, _field_num, _version, _vmsd, _type) {\ |
607 | .name = (stringify(_field)), \ |
608 | .version_id = (_version), \ |
609 | .vmsd = &(_vmsd), \ |
610 | .num_offset = vmstate_offset_value(_state, _field_num, int32_t), \ |
611 | .size = sizeof(_type), \ |
612 | .flags = VMS_STRUCT|VMS_VARRAY_INT32|VMS_ALLOC|VMS_POINTER, \ |
613 | .offset = vmstate_offset_pointer(_state, _field, _type), \ |
614 | } |
615 | |
616 | #define VMSTATE_STATIC_BUFFER(_field, _state, _version, _test, _start, _size) { \ |
617 | .name = (stringify(_field)), \ |
618 | .version_id = (_version), \ |
619 | .field_exists = (_test), \ |
620 | .size = (_size - _start), \ |
621 | .info = &vmstate_info_buffer, \ |
622 | .flags = VMS_BUFFER, \ |
623 | .offset = vmstate_offset_buffer(_state, _field) + _start, \ |
624 | } |
625 | |
626 | #define VMSTATE_VBUFFER_MULTIPLY(_field, _state, _version, _test, \ |
627 | _field_size, _multiply) { \ |
628 | .name = (stringify(_field)), \ |
629 | .version_id = (_version), \ |
630 | .field_exists = (_test), \ |
631 | .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ |
632 | .size = (_multiply), \ |
633 | .info = &vmstate_info_buffer, \ |
634 | .flags = VMS_VBUFFER|VMS_POINTER|VMS_MULTIPLY, \ |
635 | .offset = offsetof(_state, _field), \ |
636 | } |
637 | |
638 | #define VMSTATE_VBUFFER(_field, _state, _version, _test, _field_size) { \ |
639 | .name = (stringify(_field)), \ |
640 | .version_id = (_version), \ |
641 | .field_exists = (_test), \ |
642 | .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\ |
643 | .info = &vmstate_info_buffer, \ |
644 | .flags = VMS_VBUFFER|VMS_POINTER, \ |
645 | .offset = offsetof(_state, _field), \ |
646 | } |
647 | |
648 | #define VMSTATE_VBUFFER_UINT32(_field, _state, _version, _test, _field_size) { \ |
649 | .name = (stringify(_field)), \ |
650 | .version_id = (_version), \ |
651 | .field_exists = (_test), \ |
652 | .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ |
653 | .info = &vmstate_info_buffer, \ |
654 | .flags = VMS_VBUFFER|VMS_POINTER, \ |
655 | .offset = offsetof(_state, _field), \ |
656 | } |
657 | |
658 | #define VMSTATE_VBUFFER_ALLOC_UINT32(_field, _state, _version, \ |
659 | _test, _field_size) { \ |
660 | .name = (stringify(_field)), \ |
661 | .version_id = (_version), \ |
662 | .field_exists = (_test), \ |
663 | .size_offset = vmstate_offset_value(_state, _field_size, uint32_t),\ |
664 | .info = &vmstate_info_buffer, \ |
665 | .flags = VMS_VBUFFER|VMS_POINTER|VMS_ALLOC, \ |
666 | .offset = offsetof(_state, _field), \ |
667 | } |
668 | |
669 | #define VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, _test, _version, _info, _size) { \ |
670 | .name = (stringify(_field)), \ |
671 | .version_id = (_version), \ |
672 | .field_exists = (_test), \ |
673 | .size = (_size), \ |
674 | .info = &(_info), \ |
675 | .flags = VMS_BUFFER, \ |
676 | .offset = offsetof(_state, _field), \ |
677 | } |
678 | |
679 | #define VMSTATE_BUFFER_POINTER_UNSAFE(_field, _state, _version, _size) { \ |
680 | .name = (stringify(_field)), \ |
681 | .version_id = (_version), \ |
682 | .size = (_size), \ |
683 | .info = &vmstate_info_buffer, \ |
684 | .flags = VMS_BUFFER|VMS_POINTER, \ |
685 | .offset = offsetof(_state, _field), \ |
686 | } |
687 | |
688 | /* Allocate a temporary of type 'tmp_type', set tmp->parent to _state |
689 | * and execute the vmsd on the temporary. Note that we're working with |
690 | * the whole of _state here, not a field within it. |
691 | * We compile time check that: |
692 | * That _tmp_type contains a 'parent' member that's a pointer to the |
693 | * '_state' type |
694 | * That the pointer is right at the start of _tmp_type. |
695 | */ |
696 | #define VMSTATE_WITH_TMP(_state, _tmp_type, _vmsd) { \ |
697 | .name = "tmp", \ |
698 | .size = sizeof(_tmp_type) + \ |
699 | QEMU_BUILD_BUG_ON_ZERO(offsetof(_tmp_type, parent) != 0) + \ |
700 | type_check_pointer(_state, \ |
701 | typeof_field(_tmp_type, parent)), \ |
702 | .vmsd = &(_vmsd), \ |
703 | .info = &vmstate_info_tmp, \ |
704 | } |
705 | |
706 | #define VMSTATE_UNUSED_BUFFER(_test, _version, _size) { \ |
707 | .name = "unused", \ |
708 | .field_exists = (_test), \ |
709 | .version_id = (_version), \ |
710 | .size = (_size), \ |
711 | .info = &vmstate_info_unused_buffer, \ |
712 | .flags = VMS_BUFFER, \ |
713 | } |
714 | |
715 | /* Discard size * field_num bytes, where field_num is a uint32 member */ |
716 | #define VMSTATE_UNUSED_VARRAY_UINT32(_state, _test, _version, _field_num, _size) {\ |
717 | .name = "unused", \ |
718 | .field_exists = (_test), \ |
719 | .num_offset = vmstate_offset_value(_state, _field_num, uint32_t),\ |
720 | .version_id = (_version), \ |
721 | .size = (_size), \ |
722 | .info = &vmstate_info_unused_buffer, \ |
723 | .flags = VMS_VARRAY_UINT32 | VMS_BUFFER, \ |
724 | } |
725 | |
726 | /* _field_size should be a int32_t field in the _state struct giving the |
727 | * size of the bitmap _field in bits. |
728 | */ |
729 | #define VMSTATE_BITMAP(_field, _state, _version, _field_size) { \ |
730 | .name = (stringify(_field)), \ |
731 | .version_id = (_version), \ |
732 | .size_offset = vmstate_offset_value(_state, _field_size, int32_t),\ |
733 | .info = &vmstate_info_bitmap, \ |
734 | .flags = VMS_VBUFFER|VMS_POINTER, \ |
735 | .offset = offsetof(_state, _field), \ |
736 | } |
737 | |
738 | /* For migrating a QTAILQ. |
739 | * Target QTAILQ needs be properly initialized. |
740 | * _type: type of QTAILQ element |
741 | * _next: name of QTAILQ entry field in QTAILQ element |
742 | * _vmsd: VMSD for QTAILQ element |
743 | * size: size of QTAILQ element |
744 | * start: offset of QTAILQ entry in QTAILQ element |
745 | */ |
746 | #define VMSTATE_QTAILQ_V(_field, _state, _version, _vmsd, _type, _next) \ |
747 | { \ |
748 | .name = (stringify(_field)), \ |
749 | .version_id = (_version), \ |
750 | .vmsd = &(_vmsd), \ |
751 | .size = sizeof(_type), \ |
752 | .info = &vmstate_info_qtailq, \ |
753 | .offset = offsetof(_state, _field), \ |
754 | .start = offsetof(_type, _next), \ |
755 | } |
756 | |
757 | /* _f : field name |
758 | _f_n : num of elements field_name |
759 | _n : num of elements |
760 | _s : struct state name |
761 | _v : version |
762 | */ |
763 | |
764 | #define VMSTATE_SINGLE(_field, _state, _version, _info, _type) \ |
765 | VMSTATE_SINGLE_TEST(_field, _state, NULL, _version, _info, _type) |
766 | |
767 | #define VMSTATE_VSTRUCT(_field, _state, _vmsd, _type, _struct_version)\ |
768 | VMSTATE_VSTRUCT_TEST(_field, _state, NULL, 0, _vmsd, _type, _struct_version) |
769 | |
770 | #define VMSTATE_VSTRUCT_V(_field, _state, _version, _vmsd, _type, _struct_version) \ |
771 | VMSTATE_VSTRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type, \ |
772 | _struct_version) |
773 | |
774 | #define VMSTATE_STRUCT(_field, _state, _version, _vmsd, _type) \ |
775 | VMSTATE_STRUCT_TEST(_field, _state, NULL, _version, _vmsd, _type) |
776 | |
777 | #define VMSTATE_STRUCT_POINTER(_field, _state, _vmsd, _type) \ |
778 | VMSTATE_STRUCT_POINTER_V(_field, _state, 0, _vmsd, _type) |
779 | |
780 | #define VMSTATE_STRUCT_POINTER_TEST(_field, _state, _test, _vmsd, _type) \ |
781 | VMSTATE_STRUCT_POINTER_TEST_V(_field, _state, _test, 0, _vmsd, _type) |
782 | |
783 | #define VMSTATE_STRUCT_ARRAY(_field, _state, _num, _version, _vmsd, _type) \ |
784 | VMSTATE_STRUCT_ARRAY_TEST(_field, _state, _num, NULL, _version, \ |
785 | _vmsd, _type) |
786 | |
787 | #define VMSTATE_STRUCT_2DARRAY(_field, _state, _n1, _n2, _version, \ |
788 | _vmsd, _type) \ |
789 | VMSTATE_STRUCT_2DARRAY_TEST(_field, _state, _n1, _n2, NULL, \ |
790 | _version, _vmsd, _type) |
791 | |
792 | #define VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, _info, _size) \ |
793 | VMSTATE_BUFFER_UNSAFE_INFO_TEST(_field, _state, NULL, _version, _info, \ |
794 | _size) |
795 | |
796 | #define VMSTATE_BOOL_V(_f, _s, _v) \ |
797 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_bool, bool) |
798 | |
799 | #define VMSTATE_INT8_V(_f, _s, _v) \ |
800 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int8, int8_t) |
801 | #define VMSTATE_INT16_V(_f, _s, _v) \ |
802 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int16, int16_t) |
803 | #define VMSTATE_INT32_V(_f, _s, _v) \ |
804 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int32, int32_t) |
805 | #define VMSTATE_INT64_V(_f, _s, _v) \ |
806 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_int64, int64_t) |
807 | |
808 | #define VMSTATE_UINT8_V(_f, _s, _v) \ |
809 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, uint8_t) |
810 | #define VMSTATE_UINT16_V(_f, _s, _v) \ |
811 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, uint16_t) |
812 | #define VMSTATE_UINT32_V(_f, _s, _v) \ |
813 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, uint32_t) |
814 | #define VMSTATE_UINT64_V(_f, _s, _v) \ |
815 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, uint64_t) |
816 | |
817 | #ifdef CONFIG_LINUX |
818 | |
819 | #define VMSTATE_U8_V(_f, _s, _v) \ |
820 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint8, __u8) |
821 | #define VMSTATE_U16_V(_f, _s, _v) \ |
822 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint16, __u16) |
823 | #define VMSTATE_U32_V(_f, _s, _v) \ |
824 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint32, __u32) |
825 | #define VMSTATE_U64_V(_f, _s, _v) \ |
826 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_uint64, __u64) |
827 | |
828 | #endif |
829 | |
830 | #define VMSTATE_BOOL(_f, _s) \ |
831 | VMSTATE_BOOL_V(_f, _s, 0) |
832 | |
833 | #define VMSTATE_INT8(_f, _s) \ |
834 | VMSTATE_INT8_V(_f, _s, 0) |
835 | #define VMSTATE_INT16(_f, _s) \ |
836 | VMSTATE_INT16_V(_f, _s, 0) |
837 | #define VMSTATE_INT32(_f, _s) \ |
838 | VMSTATE_INT32_V(_f, _s, 0) |
839 | #define VMSTATE_INT64(_f, _s) \ |
840 | VMSTATE_INT64_V(_f, _s, 0) |
841 | |
842 | #define VMSTATE_UINT8(_f, _s) \ |
843 | VMSTATE_UINT8_V(_f, _s, 0) |
844 | #define VMSTATE_UINT16(_f, _s) \ |
845 | VMSTATE_UINT16_V(_f, _s, 0) |
846 | #define VMSTATE_UINT32(_f, _s) \ |
847 | VMSTATE_UINT32_V(_f, _s, 0) |
848 | #define VMSTATE_UINT64(_f, _s) \ |
849 | VMSTATE_UINT64_V(_f, _s, 0) |
850 | |
851 | #ifdef CONFIG_LINUX |
852 | |
853 | #define VMSTATE_U8(_f, _s) \ |
854 | VMSTATE_U8_V(_f, _s, 0) |
855 | #define VMSTATE_U16(_f, _s) \ |
856 | VMSTATE_U16_V(_f, _s, 0) |
857 | #define VMSTATE_U32(_f, _s) \ |
858 | VMSTATE_U32_V(_f, _s, 0) |
859 | #define VMSTATE_U64(_f, _s) \ |
860 | VMSTATE_U64_V(_f, _s, 0) |
861 | |
862 | #endif |
863 | |
864 | #define VMSTATE_UINT8_EQUAL(_f, _s, _err_hint) \ |
865 | VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \ |
866 | vmstate_info_uint8_equal, uint8_t, _err_hint) |
867 | |
868 | #define VMSTATE_UINT16_EQUAL(_f, _s, _err_hint) \ |
869 | VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \ |
870 | vmstate_info_uint16_equal, uint16_t, _err_hint) |
871 | |
872 | #define VMSTATE_UINT16_EQUAL_V(_f, _s, _v, _err_hint) \ |
873 | VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \ |
874 | vmstate_info_uint16_equal, uint16_t, _err_hint) |
875 | |
876 | #define VMSTATE_INT32_EQUAL(_f, _s, _err_hint) \ |
877 | VMSTATE_SINGLE_FULL(_f, _s, 0, 0, \ |
878 | vmstate_info_int32_equal, int32_t, _err_hint) |
879 | |
880 | #define VMSTATE_UINT32_EQUAL_V(_f, _s, _v, _err_hint) \ |
881 | VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \ |
882 | vmstate_info_uint32_equal, uint32_t, _err_hint) |
883 | |
884 | #define VMSTATE_UINT32_EQUAL(_f, _s, _err_hint) \ |
885 | VMSTATE_UINT32_EQUAL_V(_f, _s, 0, _err_hint) |
886 | |
887 | #define VMSTATE_UINT64_EQUAL_V(_f, _s, _v, _err_hint) \ |
888 | VMSTATE_SINGLE_FULL(_f, _s, 0, _v, \ |
889 | vmstate_info_uint64_equal, uint64_t, _err_hint) |
890 | |
891 | #define VMSTATE_UINT64_EQUAL(_f, _s, _err_hint) \ |
892 | VMSTATE_UINT64_EQUAL_V(_f, _s, 0, _err_hint) |
893 | |
894 | #define VMSTATE_INT32_POSITIVE_LE(_f, _s) \ |
895 | VMSTATE_SINGLE(_f, _s, 0, vmstate_info_int32_le, int32_t) |
896 | |
897 | #define VMSTATE_BOOL_TEST(_f, _s, _t) \ |
898 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_bool, bool) |
899 | |
900 | #define VMSTATE_INT8_TEST(_f, _s, _t) \ |
901 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_int8, int8_t) |
902 | |
903 | #define VMSTATE_INT16_TEST(_f, _s, _t) \ |
904 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_int16, int16_t) |
905 | |
906 | #define VMSTATE_INT32_TEST(_f, _s, _t) \ |
907 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_int32, int32_t) |
908 | |
909 | #define VMSTATE_INT64_TEST(_f, _s, _t) \ |
910 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_int64, int64_t) |
911 | |
912 | #define VMSTATE_UINT8_TEST(_f, _s, _t) \ |
913 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint8, uint8_t) |
914 | |
915 | #define VMSTATE_UINT16_TEST(_f, _s, _t) \ |
916 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint16, uint16_t) |
917 | |
918 | #define VMSTATE_UINT32_TEST(_f, _s, _t) \ |
919 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint32, uint32_t) |
920 | |
921 | #define VMSTATE_UINT64_TEST(_f, _s, _t) \ |
922 | VMSTATE_SINGLE_TEST(_f, _s, _t, 0, vmstate_info_uint64, uint64_t) |
923 | |
924 | |
925 | #define VMSTATE_FLOAT64_V(_f, _s, _v) \ |
926 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_float64, float64) |
927 | |
928 | #define VMSTATE_FLOAT64(_f, _s) \ |
929 | VMSTATE_FLOAT64_V(_f, _s, 0) |
930 | |
931 | #define VMSTATE_TIMER_PTR_TEST(_f, _s, _test) \ |
932 | VMSTATE_POINTER_TEST(_f, _s, _test, vmstate_info_timer, QEMUTimer *) |
933 | |
934 | #define VMSTATE_TIMER_PTR_V(_f, _s, _v) \ |
935 | VMSTATE_POINTER(_f, _s, _v, vmstate_info_timer, QEMUTimer *) |
936 | |
937 | #define VMSTATE_TIMER_PTR(_f, _s) \ |
938 | VMSTATE_TIMER_PTR_V(_f, _s, 0) |
939 | |
940 | #define VMSTATE_TIMER_PTR_ARRAY(_f, _s, _n) \ |
941 | VMSTATE_ARRAY_OF_POINTER(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer *) |
942 | |
943 | #define VMSTATE_TIMER_TEST(_f, _s, _test) \ |
944 | VMSTATE_SINGLE_TEST(_f, _s, _test, 0, vmstate_info_timer, QEMUTimer) |
945 | |
946 | #define VMSTATE_TIMER_V(_f, _s, _v) \ |
947 | VMSTATE_SINGLE(_f, _s, _v, vmstate_info_timer, QEMUTimer) |
948 | |
949 | #define VMSTATE_TIMER(_f, _s) \ |
950 | VMSTATE_TIMER_V(_f, _s, 0) |
951 | |
952 | #define VMSTATE_TIMER_ARRAY(_f, _s, _n) \ |
953 | VMSTATE_ARRAY(_f, _s, _n, 0, vmstate_info_timer, QEMUTimer) |
954 | |
955 | #define VMSTATE_BOOL_ARRAY_V(_f, _s, _n, _v) \ |
956 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_bool, bool) |
957 | |
958 | #define VMSTATE_BOOL_ARRAY(_f, _s, _n) \ |
959 | VMSTATE_BOOL_ARRAY_V(_f, _s, _n, 0) |
960 | |
961 | #define VMSTATE_BOOL_SUB_ARRAY(_f, _s, _start, _num) \ |
962 | VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_bool, bool) |
963 | |
964 | #define VMSTATE_UINT16_ARRAY_V(_f, _s, _n, _v) \ |
965 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint16, uint16_t) |
966 | |
967 | #define VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, _v) \ |
968 | VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint16, uint16_t) |
969 | |
970 | #define VMSTATE_UINT16_ARRAY(_f, _s, _n) \ |
971 | VMSTATE_UINT16_ARRAY_V(_f, _s, _n, 0) |
972 | |
973 | #define VMSTATE_UINT16_SUB_ARRAY(_f, _s, _start, _num) \ |
974 | VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint16, uint16_t) |
975 | |
976 | #define VMSTATE_UINT16_2DARRAY(_f, _s, _n1, _n2) \ |
977 | VMSTATE_UINT16_2DARRAY_V(_f, _s, _n1, _n2, 0) |
978 | |
979 | #define VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, _v) \ |
980 | VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint8, uint8_t) |
981 | |
982 | #define VMSTATE_UINT8_ARRAY_V(_f, _s, _n, _v) \ |
983 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint8, uint8_t) |
984 | |
985 | #define VMSTATE_UINT8_ARRAY(_f, _s, _n) \ |
986 | VMSTATE_UINT8_ARRAY_V(_f, _s, _n, 0) |
987 | |
988 | #define VMSTATE_UINT8_SUB_ARRAY(_f, _s, _start, _num) \ |
989 | VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint8, uint8_t) |
990 | |
991 | #define VMSTATE_UINT8_2DARRAY(_f, _s, _n1, _n2) \ |
992 | VMSTATE_UINT8_2DARRAY_V(_f, _s, _n1, _n2, 0) |
993 | |
994 | #define VMSTATE_UINT32_ARRAY_V(_f, _s, _n, _v) \ |
995 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint32, uint32_t) |
996 | |
997 | #define VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, _v) \ |
998 | VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint32, uint32_t) |
999 | |
1000 | #define VMSTATE_UINT32_ARRAY(_f, _s, _n) \ |
1001 | VMSTATE_UINT32_ARRAY_V(_f, _s, _n, 0) |
1002 | |
1003 | #define VMSTATE_UINT32_SUB_ARRAY(_f, _s, _start, _num) \ |
1004 | VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint32, uint32_t) |
1005 | |
1006 | #define VMSTATE_UINT32_2DARRAY(_f, _s, _n1, _n2) \ |
1007 | VMSTATE_UINT32_2DARRAY_V(_f, _s, _n1, _n2, 0) |
1008 | |
1009 | #define VMSTATE_UINT64_ARRAY_V(_f, _s, _n, _v) \ |
1010 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_uint64, uint64_t) |
1011 | |
1012 | #define VMSTATE_UINT64_ARRAY(_f, _s, _n) \ |
1013 | VMSTATE_UINT64_ARRAY_V(_f, _s, _n, 0) |
1014 | |
1015 | #define VMSTATE_UINT64_SUB_ARRAY(_f, _s, _start, _num) \ |
1016 | VMSTATE_SUB_ARRAY(_f, _s, _start, _num, 0, vmstate_info_uint64, uint64_t) |
1017 | |
1018 | #define VMSTATE_UINT64_2DARRAY(_f, _s, _n1, _n2) \ |
1019 | VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, 0) |
1020 | |
1021 | #define VMSTATE_UINT64_2DARRAY_V(_f, _s, _n1, _n2, _v) \ |
1022 | VMSTATE_2DARRAY(_f, _s, _n1, _n2, _v, vmstate_info_uint64, uint64_t) |
1023 | |
1024 | #define VMSTATE_INT16_ARRAY_V(_f, _s, _n, _v) \ |
1025 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int16, int16_t) |
1026 | |
1027 | #define VMSTATE_INT16_ARRAY(_f, _s, _n) \ |
1028 | VMSTATE_INT16_ARRAY_V(_f, _s, _n, 0) |
1029 | |
1030 | #define VMSTATE_INT32_ARRAY_V(_f, _s, _n, _v) \ |
1031 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int32, int32_t) |
1032 | |
1033 | #define VMSTATE_INT32_ARRAY(_f, _s, _n) \ |
1034 | VMSTATE_INT32_ARRAY_V(_f, _s, _n, 0) |
1035 | |
1036 | #define VMSTATE_INT64_ARRAY_V(_f, _s, _n, _v) \ |
1037 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_int64, int64_t) |
1038 | |
1039 | #define VMSTATE_INT64_ARRAY(_f, _s, _n) \ |
1040 | VMSTATE_INT64_ARRAY_V(_f, _s, _n, 0) |
1041 | |
1042 | #define VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, _v) \ |
1043 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_float64, float64) |
1044 | |
1045 | #define VMSTATE_FLOAT64_ARRAY(_f, _s, _n) \ |
1046 | VMSTATE_FLOAT64_ARRAY_V(_f, _s, _n, 0) |
1047 | |
1048 | #define VMSTATE_CPUDOUBLE_ARRAY_V(_f, _s, _n, _v) \ |
1049 | VMSTATE_ARRAY(_f, _s, _n, _v, vmstate_info_cpudouble, CPU_DoubleU) |
1050 | |
1051 | #define VMSTATE_CPUDOUBLE_ARRAY(_f, _s, _n) \ |
1052 | VMSTATE_CPUDOUBLE_ARRAY_V(_f, _s, _n, 0) |
1053 | |
1054 | #define VMSTATE_BUFFER_V(_f, _s, _v) \ |
1055 | VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, 0, sizeof(typeof_field(_s, _f))) |
1056 | |
1057 | #define VMSTATE_BUFFER(_f, _s) \ |
1058 | VMSTATE_BUFFER_V(_f, _s, 0) |
1059 | |
1060 | #define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \ |
1061 | VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size) |
1062 | |
1063 | #define VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, _v) \ |
1064 | VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, _start, sizeof(typeof_field(_s, _f))) |
1065 | |
1066 | #define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \ |
1067 | VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0) |
1068 | |
1069 | #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \ |
1070 | VMSTATE_VBUFFER(_f, _s, 0, NULL, _size) |
1071 | |
1072 | #define VMSTATE_PARTIAL_VBUFFER_UINT32(_f, _s, _size) \ |
1073 | VMSTATE_VBUFFER_UINT32(_f, _s, 0, NULL, _size) |
1074 | |
1075 | #define VMSTATE_BUFFER_TEST(_f, _s, _test) \ |
1076 | VMSTATE_STATIC_BUFFER(_f, _s, 0, _test, 0, sizeof(typeof_field(_s, _f))) |
1077 | |
1078 | #define VMSTATE_BUFFER_UNSAFE(_field, _state, _version, _size) \ |
1079 | VMSTATE_BUFFER_UNSAFE_INFO(_field, _state, _version, vmstate_info_buffer, _size) |
1080 | |
1081 | /* |
1082 | * These VMSTATE_UNUSED*() macros can be used to fill in the holes |
1083 | * when some of the vmstate fields are obsolete to be compatible with |
1084 | * migrations between new/old binaries. |
1085 | * |
1086 | * CAUTION: when using any of the VMSTATE_UNUSED*() macros please be |
1087 | * sure that the size passed in is the size that was actually *sent* |
1088 | * rather than the size of the *structure*. One example is the |
1089 | * boolean type - the size of the structure can vary depending on the |
1090 | * definition of boolean, however the size we actually sent is always |
1091 | * 1 byte (please refer to implementation of VMSTATE_BOOL_V and |
1092 | * vmstate_info_bool). So here we should always pass in size==1 |
1093 | * rather than size==sizeof(bool). |
1094 | */ |
1095 | #define VMSTATE_UNUSED_V(_v, _size) \ |
1096 | VMSTATE_UNUSED_BUFFER(NULL, _v, _size) |
1097 | |
1098 | #define VMSTATE_UNUSED(_size) \ |
1099 | VMSTATE_UNUSED_V(0, _size) |
1100 | |
1101 | #define VMSTATE_UNUSED_TEST(_test, _size) \ |
1102 | VMSTATE_UNUSED_BUFFER(_test, 0, _size) |
1103 | |
1104 | #define VMSTATE_END_OF_LIST() \ |
1105 | {} |
1106 | |
1107 | int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd, |
1108 | void *opaque, int version_id); |
1109 | int vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd, |
1110 | void *opaque, QJSON *vmdesc); |
1111 | int vmstate_save_state_v(QEMUFile *f, const VMStateDescription *vmsd, |
1112 | void *opaque, QJSON *vmdesc, int version_id); |
1113 | |
1114 | bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque); |
1115 | |
1116 | /* Returns: 0 on success, -1 on failure */ |
1117 | int vmstate_register_with_alias_id(DeviceState *dev, int instance_id, |
1118 | const VMStateDescription *vmsd, |
1119 | void *base, int alias_id, |
1120 | int required_for_version, |
1121 | Error **errp); |
1122 | |
1123 | /* Returns: 0 on success, -1 on failure */ |
1124 | static inline int vmstate_register(DeviceState *dev, int instance_id, |
1125 | const VMStateDescription *vmsd, |
1126 | void *opaque) |
1127 | { |
1128 | return vmstate_register_with_alias_id(dev, instance_id, vmsd, |
1129 | opaque, -1, 0, NULL); |
1130 | } |
1131 | |
1132 | void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, |
1133 | void *opaque); |
1134 | |
1135 | struct MemoryRegion; |
1136 | void vmstate_register_ram(struct MemoryRegion *memory, DeviceState *dev); |
1137 | void vmstate_unregister_ram(struct MemoryRegion *memory, DeviceState *dev); |
1138 | void vmstate_register_ram_global(struct MemoryRegion *memory); |
1139 | |
1140 | bool vmstate_check_only_migratable(const VMStateDescription *vmsd); |
1141 | |
1142 | #endif |
1143 | |