xref: /openbmc/qemu/migration/vmstate.c (revision 56e2cd24)
1 #include "qemu/osdep.h"
2 #include "qemu-common.h"
3 #include "migration/migration.h"
4 #include "migration/qemu-file.h"
5 #include "migration/vmstate.h"
6 #include "qemu/bitops.h"
7 #include "qemu/error-report.h"
8 #include "qemu/queue.h"
9 #include "trace.h"
10 #include "migration/qjson.h"
11 
12 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
13                                     void *opaque, QJSON *vmdesc);
14 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
15                                    void *opaque);
16 
17 static int vmstate_n_elems(void *opaque, VMStateField *field)
18 {
19     int n_elems = 1;
20 
21     if (field->flags & VMS_ARRAY) {
22         n_elems = field->num;
23     } else if (field->flags & VMS_VARRAY_INT32) {
24         n_elems = *(int32_t *)(opaque+field->num_offset);
25     } else if (field->flags & VMS_VARRAY_UINT32) {
26         n_elems = *(uint32_t *)(opaque+field->num_offset);
27     } else if (field->flags & VMS_VARRAY_UINT16) {
28         n_elems = *(uint16_t *)(opaque+field->num_offset);
29     } else if (field->flags & VMS_VARRAY_UINT8) {
30         n_elems = *(uint8_t *)(opaque+field->num_offset);
31     }
32 
33     if (field->flags & VMS_MULTIPLY_ELEMENTS) {
34         n_elems *= field->num;
35     }
36 
37     trace_vmstate_n_elems(field->name, n_elems);
38     return n_elems;
39 }
40 
41 static int vmstate_size(void *opaque, VMStateField *field)
42 {
43     int size = field->size;
44 
45     if (field->flags & VMS_VBUFFER) {
46         size = *(int32_t *)(opaque+field->size_offset);
47         if (field->flags & VMS_MULTIPLY) {
48             size *= field->size;
49         }
50     }
51 
52     return size;
53 }
54 
55 static void vmstate_handle_alloc(void *ptr, VMStateField *field, void *opaque)
56 {
57     if (field->flags & VMS_POINTER && field->flags & VMS_ALLOC) {
58         gsize size = vmstate_size(opaque, field);
59         size *= vmstate_n_elems(opaque, field);
60         if (size) {
61             *(void **)ptr = g_malloc(size);
62         }
63     }
64 }
65 
66 int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
67                        void *opaque, int version_id)
68 {
69     VMStateField *field = vmsd->fields;
70     int ret = 0;
71 
72     trace_vmstate_load_state(vmsd->name, version_id);
73     if (version_id > vmsd->version_id) {
74         error_report("%s: incoming version_id %d is too new "
75                      "for local version_id %d",
76                      vmsd->name, version_id, vmsd->version_id);
77         trace_vmstate_load_state_end(vmsd->name, "too new", -EINVAL);
78         return -EINVAL;
79     }
80     if  (version_id < vmsd->minimum_version_id) {
81         if (vmsd->load_state_old &&
82             version_id >= vmsd->minimum_version_id_old) {
83             ret = vmsd->load_state_old(f, opaque, version_id);
84             trace_vmstate_load_state_end(vmsd->name, "old path", ret);
85             return ret;
86         }
87         error_report("%s: incoming version_id %d is too old "
88                      "for local minimum version_id  %d",
89                      vmsd->name, version_id, vmsd->minimum_version_id);
90         trace_vmstate_load_state_end(vmsd->name, "too old", -EINVAL);
91         return -EINVAL;
92     }
93     if (vmsd->pre_load) {
94         int ret = vmsd->pre_load(opaque);
95         if (ret) {
96             return ret;
97         }
98     }
99     while (field->name) {
100         trace_vmstate_load_state_field(vmsd->name, field->name);
101         if ((field->field_exists &&
102              field->field_exists(opaque, version_id)) ||
103             (!field->field_exists &&
104              field->version_id <= version_id)) {
105             void *first_elem = opaque + field->offset;
106             int i, n_elems = vmstate_n_elems(opaque, field);
107             int size = vmstate_size(opaque, field);
108 
109             vmstate_handle_alloc(first_elem, field, opaque);
110             if (field->flags & VMS_POINTER) {
111                 first_elem = *(void **)first_elem;
112                 assert(first_elem || !n_elems || !size);
113             }
114             for (i = 0; i < n_elems; i++) {
115                 void *curr_elem = first_elem + size * i;
116 
117                 if (field->flags & VMS_ARRAY_OF_POINTER) {
118                     curr_elem = *(void **)curr_elem;
119                 }
120                 if (!curr_elem && size) {
121                     /* if null pointer check placeholder and do not follow */
122                     assert(field->flags & VMS_ARRAY_OF_POINTER);
123                     ret = vmstate_info_nullptr.get(f, curr_elem, size, NULL);
124                 } else if (field->flags & VMS_STRUCT) {
125                     ret = vmstate_load_state(f, field->vmsd, curr_elem,
126                                              field->vmsd->version_id);
127                 } else {
128                     ret = field->info->get(f, curr_elem, size, field);
129                 }
130                 if (ret >= 0) {
131                     ret = qemu_file_get_error(f);
132                 }
133                 if (ret < 0) {
134                     qemu_file_set_error(f, ret);
135                     error_report("Failed to load %s:%s", vmsd->name,
136                                  field->name);
137                     trace_vmstate_load_field_error(field->name, ret);
138                     return ret;
139                 }
140             }
141         } else if (field->flags & VMS_MUST_EXIST) {
142             error_report("Input validation failed: %s/%s",
143                          vmsd->name, field->name);
144             return -1;
145         }
146         field++;
147     }
148     ret = vmstate_subsection_load(f, vmsd, opaque);
149     if (ret != 0) {
150         return ret;
151     }
152     if (vmsd->post_load) {
153         ret = vmsd->post_load(opaque, version_id);
154     }
155     trace_vmstate_load_state_end(vmsd->name, "end", ret);
156     return ret;
157 }
158 
159 static int vmfield_name_num(VMStateField *start, VMStateField *search)
160 {
161     VMStateField *field;
162     int found = 0;
163 
164     for (field = start; field->name; field++) {
165         if (!strcmp(field->name, search->name)) {
166             if (field == search) {
167                 return found;
168             }
169             found++;
170         }
171     }
172 
173     return -1;
174 }
175 
176 static bool vmfield_name_is_unique(VMStateField *start, VMStateField *search)
177 {
178     VMStateField *field;
179     int found = 0;
180 
181     for (field = start; field->name; field++) {
182         if (!strcmp(field->name, search->name)) {
183             found++;
184             /* name found more than once, so it's not unique */
185             if (found > 1) {
186                 return false;
187             }
188         }
189     }
190 
191     return true;
192 }
193 
194 static const char *vmfield_get_type_name(VMStateField *field)
195 {
196     const char *type = "unknown";
197 
198     if (field->flags & VMS_STRUCT) {
199         type = "struct";
200     } else if (field->info->name) {
201         type = field->info->name;
202     }
203 
204     return type;
205 }
206 
207 static bool vmsd_can_compress(VMStateField *field)
208 {
209     if (field->field_exists) {
210         /* Dynamically existing fields mess up compression */
211         return false;
212     }
213 
214     if (field->flags & VMS_STRUCT) {
215         VMStateField *sfield = field->vmsd->fields;
216         while (sfield->name) {
217             if (!vmsd_can_compress(sfield)) {
218                 /* Child elements can't compress, so can't we */
219                 return false;
220             }
221             sfield++;
222         }
223 
224         if (field->vmsd->subsections) {
225             /* Subsections may come and go, better don't compress */
226             return false;
227         }
228     }
229 
230     return true;
231 }
232 
233 static void vmsd_desc_field_start(const VMStateDescription *vmsd, QJSON *vmdesc,
234                                   VMStateField *field, int i, int max)
235 {
236     char *name, *old_name;
237     bool is_array = max > 1;
238     bool can_compress = vmsd_can_compress(field);
239 
240     if (!vmdesc) {
241         return;
242     }
243 
244     name = g_strdup(field->name);
245 
246     /* Field name is not unique, need to make it unique */
247     if (!vmfield_name_is_unique(vmsd->fields, field)) {
248         int num = vmfield_name_num(vmsd->fields, field);
249         old_name = name;
250         name = g_strdup_printf("%s[%d]", name, num);
251         g_free(old_name);
252     }
253 
254     json_start_object(vmdesc, NULL);
255     json_prop_str(vmdesc, "name", name);
256     if (is_array) {
257         if (can_compress) {
258             json_prop_int(vmdesc, "array_len", max);
259         } else {
260             json_prop_int(vmdesc, "index", i);
261         }
262     }
263     json_prop_str(vmdesc, "type", vmfield_get_type_name(field));
264 
265     if (field->flags & VMS_STRUCT) {
266         json_start_object(vmdesc, "struct");
267     }
268 
269     g_free(name);
270 }
271 
272 static void vmsd_desc_field_end(const VMStateDescription *vmsd, QJSON *vmdesc,
273                                 VMStateField *field, size_t size, int i)
274 {
275     if (!vmdesc) {
276         return;
277     }
278 
279     if (field->flags & VMS_STRUCT) {
280         /* We printed a struct in between, close its child object */
281         json_end_object(vmdesc);
282     }
283 
284     json_prop_int(vmdesc, "size", size);
285     json_end_object(vmdesc);
286 }
287 
288 
289 bool vmstate_save_needed(const VMStateDescription *vmsd, void *opaque)
290 {
291     if (vmsd->needed && !vmsd->needed(opaque)) {
292         /* optional section not needed */
293         return false;
294     }
295     return true;
296 }
297 
298 
299 void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
300                         void *opaque, QJSON *vmdesc)
301 {
302     VMStateField *field = vmsd->fields;
303 
304     trace_vmstate_save_state_top(vmsd->name);
305 
306     if (vmsd->pre_save) {
307         vmsd->pre_save(opaque);
308     }
309 
310     if (vmdesc) {
311         json_prop_str(vmdesc, "vmsd_name", vmsd->name);
312         json_prop_int(vmdesc, "version", vmsd->version_id);
313         json_start_array(vmdesc, "fields");
314     }
315 
316     while (field->name) {
317         if (!field->field_exists ||
318             field->field_exists(opaque, vmsd->version_id)) {
319             void *first_elem = opaque + field->offset;
320             int i, n_elems = vmstate_n_elems(opaque, field);
321             int size = vmstate_size(opaque, field);
322             int64_t old_offset, written_bytes;
323             QJSON *vmdesc_loop = vmdesc;
324 
325             trace_vmstate_save_state_loop(vmsd->name, field->name, n_elems);
326             if (field->flags & VMS_POINTER) {
327                 first_elem = *(void **)first_elem;
328                 assert(first_elem || !n_elems || !size);
329             }
330             for (i = 0; i < n_elems; i++) {
331                 void *curr_elem = first_elem + size * i;
332 
333                 vmsd_desc_field_start(vmsd, vmdesc_loop, field, i, n_elems);
334                 old_offset = qemu_ftell_fast(f);
335                 if (field->flags & VMS_ARRAY_OF_POINTER) {
336                     assert(curr_elem);
337                     curr_elem = *(void **)curr_elem;
338                 }
339                 if (!curr_elem && size) {
340                     /* if null pointer write placeholder and do not follow */
341                     assert(field->flags & VMS_ARRAY_OF_POINTER);
342                     vmstate_info_nullptr.put(f, curr_elem, size, NULL, NULL);
343                 } else if (field->flags & VMS_STRUCT) {
344                     vmstate_save_state(f, field->vmsd, curr_elem, vmdesc_loop);
345                 } else {
346                     field->info->put(f, curr_elem, size, field, vmdesc_loop);
347                 }
348 
349                 written_bytes = qemu_ftell_fast(f) - old_offset;
350                 vmsd_desc_field_end(vmsd, vmdesc_loop, field, written_bytes, i);
351 
352                 /* Compressed arrays only care about the first element */
353                 if (vmdesc_loop && vmsd_can_compress(field)) {
354                     vmdesc_loop = NULL;
355                 }
356             }
357         } else {
358             if (field->flags & VMS_MUST_EXIST) {
359                 error_report("Output state validation failed: %s/%s",
360                         vmsd->name, field->name);
361                 assert(!(field->flags & VMS_MUST_EXIST));
362             }
363         }
364         field++;
365     }
366 
367     if (vmdesc) {
368         json_end_array(vmdesc);
369     }
370 
371     vmstate_subsection_save(f, vmsd, opaque, vmdesc);
372 }
373 
374 static const VMStateDescription *
375 vmstate_get_subsection(const VMStateDescription **sub, char *idstr)
376 {
377     while (sub && *sub && (*sub)->needed) {
378         if (strcmp(idstr, (*sub)->name) == 0) {
379             return *sub;
380         }
381         sub++;
382     }
383     return NULL;
384 }
385 
386 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
387                                    void *opaque)
388 {
389     trace_vmstate_subsection_load(vmsd->name);
390 
391     while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
392         char idstr[256], *idstr_ret;
393         int ret;
394         uint8_t version_id, len, size;
395         const VMStateDescription *sub_vmsd;
396 
397         len = qemu_peek_byte(f, 1);
398         if (len < strlen(vmsd->name) + 1) {
399             /* subsection name has be be "section_name/a" */
400             trace_vmstate_subsection_load_bad(vmsd->name, "(short)", "");
401             return 0;
402         }
403         size = qemu_peek_buffer(f, (uint8_t **)&idstr_ret, len, 2);
404         if (size != len) {
405             trace_vmstate_subsection_load_bad(vmsd->name, "(peek fail)", "");
406             return 0;
407         }
408         memcpy(idstr, idstr_ret, size);
409         idstr[size] = 0;
410 
411         if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
412             trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(prefix)");
413             /* it doesn't have a valid subsection name */
414             return 0;
415         }
416         sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
417         if (sub_vmsd == NULL) {
418             trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(lookup)");
419             return -ENOENT;
420         }
421         qemu_file_skip(f, 1); /* subsection */
422         qemu_file_skip(f, 1); /* len */
423         qemu_file_skip(f, len); /* idstr */
424         version_id = qemu_get_be32(f);
425 
426         ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
427         if (ret) {
428             trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(child)");
429             return ret;
430         }
431     }
432 
433     trace_vmstate_subsection_load_good(vmsd->name);
434     return 0;
435 }
436 
437 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
438                                     void *opaque, QJSON *vmdesc)
439 {
440     const VMStateDescription **sub = vmsd->subsections;
441     bool subsection_found = false;
442 
443     trace_vmstate_subsection_save_top(vmsd->name);
444     while (sub && *sub && (*sub)->needed) {
445         if ((*sub)->needed(opaque)) {
446             const VMStateDescription *vmsdsub = *sub;
447             uint8_t len;
448 
449             trace_vmstate_subsection_save_loop(vmsd->name, vmsdsub->name);
450             if (vmdesc) {
451                 /* Only create subsection array when we have any */
452                 if (!subsection_found) {
453                     json_start_array(vmdesc, "subsections");
454                     subsection_found = true;
455                 }
456 
457                 json_start_object(vmdesc, NULL);
458             }
459 
460             qemu_put_byte(f, QEMU_VM_SUBSECTION);
461             len = strlen(vmsdsub->name);
462             qemu_put_byte(f, len);
463             qemu_put_buffer(f, (uint8_t *)vmsdsub->name, len);
464             qemu_put_be32(f, vmsdsub->version_id);
465             vmstate_save_state(f, vmsdsub, opaque, vmdesc);
466 
467             if (vmdesc) {
468                 json_end_object(vmdesc);
469             }
470         }
471         sub++;
472     }
473 
474     if (vmdesc && subsection_found) {
475         json_end_array(vmdesc);
476     }
477 }
478 
479 /* bool */
480 
481 static int get_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field)
482 {
483     bool *v = pv;
484     *v = qemu_get_byte(f);
485     return 0;
486 }
487 
488 static int put_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field,
489                     QJSON *vmdesc)
490 {
491     bool *v = pv;
492     qemu_put_byte(f, *v);
493     return 0;
494 }
495 
496 const VMStateInfo vmstate_info_bool = {
497     .name = "bool",
498     .get  = get_bool,
499     .put  = put_bool,
500 };
501 
502 /* 8 bit int */
503 
504 static int get_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field)
505 {
506     int8_t *v = pv;
507     qemu_get_s8s(f, v);
508     return 0;
509 }
510 
511 static int put_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field,
512                      QJSON *vmdesc)
513 {
514     int8_t *v = pv;
515     qemu_put_s8s(f, v);
516     return 0;
517 }
518 
519 const VMStateInfo vmstate_info_int8 = {
520     .name = "int8",
521     .get  = get_int8,
522     .put  = put_int8,
523 };
524 
525 /* 16 bit int */
526 
527 static int get_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field)
528 {
529     int16_t *v = pv;
530     qemu_get_sbe16s(f, v);
531     return 0;
532 }
533 
534 static int put_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field,
535                      QJSON *vmdesc)
536 {
537     int16_t *v = pv;
538     qemu_put_sbe16s(f, v);
539     return 0;
540 }
541 
542 const VMStateInfo vmstate_info_int16 = {
543     .name = "int16",
544     .get  = get_int16,
545     .put  = put_int16,
546 };
547 
548 /* 32 bit int */
549 
550 static int get_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field)
551 {
552     int32_t *v = pv;
553     qemu_get_sbe32s(f, v);
554     return 0;
555 }
556 
557 static int put_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field,
558                      QJSON *vmdesc)
559 {
560     int32_t *v = pv;
561     qemu_put_sbe32s(f, v);
562     return 0;
563 }
564 
565 const VMStateInfo vmstate_info_int32 = {
566     .name = "int32",
567     .get  = get_int32,
568     .put  = put_int32,
569 };
570 
571 /* 32 bit int. See that the received value is the same than the one
572    in the field */
573 
574 static int get_int32_equal(QEMUFile *f, void *pv, size_t size,
575                            VMStateField *field)
576 {
577     int32_t *v = pv;
578     int32_t v2;
579     qemu_get_sbe32s(f, &v2);
580 
581     if (*v == v2) {
582         return 0;
583     }
584     error_report("%" PRIx32 " != %" PRIx32, *v, v2);
585     return -EINVAL;
586 }
587 
588 const VMStateInfo vmstate_info_int32_equal = {
589     .name = "int32 equal",
590     .get  = get_int32_equal,
591     .put  = put_int32,
592 };
593 
594 /* 32 bit int. Check that the received value is non-negative
595  * and less than or equal to the one in the field.
596  */
597 
598 static int get_int32_le(QEMUFile *f, void *pv, size_t size, VMStateField *field)
599 {
600     int32_t *cur = pv;
601     int32_t loaded;
602     qemu_get_sbe32s(f, &loaded);
603 
604     if (loaded >= 0 && loaded <= *cur) {
605         *cur = loaded;
606         return 0;
607     }
608     error_report("Invalid value %" PRId32
609                  " expecting positive value <= %" PRId32,
610                  loaded, *cur);
611     return -EINVAL;
612 }
613 
614 const VMStateInfo vmstate_info_int32_le = {
615     .name = "int32 le",
616     .get  = get_int32_le,
617     .put  = put_int32,
618 };
619 
620 /* 64 bit int */
621 
622 static int get_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field)
623 {
624     int64_t *v = pv;
625     qemu_get_sbe64s(f, v);
626     return 0;
627 }
628 
629 static int put_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
630                       QJSON *vmdesc)
631 {
632     int64_t *v = pv;
633     qemu_put_sbe64s(f, v);
634     return 0;
635 }
636 
637 const VMStateInfo vmstate_info_int64 = {
638     .name = "int64",
639     .get  = get_int64,
640     .put  = put_int64,
641 };
642 
643 /* 8 bit unsigned int */
644 
645 static int get_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field)
646 {
647     uint8_t *v = pv;
648     qemu_get_8s(f, v);
649     return 0;
650 }
651 
652 static int put_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field,
653                      QJSON *vmdesc)
654 {
655     uint8_t *v = pv;
656     qemu_put_8s(f, v);
657     return 0;
658 }
659 
660 const VMStateInfo vmstate_info_uint8 = {
661     .name = "uint8",
662     .get  = get_uint8,
663     .put  = put_uint8,
664 };
665 
666 /* 16 bit unsigned int */
667 
668 static int get_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field)
669 {
670     uint16_t *v = pv;
671     qemu_get_be16s(f, v);
672     return 0;
673 }
674 
675 static int put_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field,
676                       QJSON *vmdesc)
677 {
678     uint16_t *v = pv;
679     qemu_put_be16s(f, v);
680     return 0;
681 }
682 
683 const VMStateInfo vmstate_info_uint16 = {
684     .name = "uint16",
685     .get  = get_uint16,
686     .put  = put_uint16,
687 };
688 
689 /* 32 bit unsigned int */
690 
691 static int get_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field)
692 {
693     uint32_t *v = pv;
694     qemu_get_be32s(f, v);
695     return 0;
696 }
697 
698 static int put_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field,
699                       QJSON *vmdesc)
700 {
701     uint32_t *v = pv;
702     qemu_put_be32s(f, v);
703     return 0;
704 }
705 
706 const VMStateInfo vmstate_info_uint32 = {
707     .name = "uint32",
708     .get  = get_uint32,
709     .put  = put_uint32,
710 };
711 
712 /* 32 bit uint. See that the received value is the same than the one
713    in the field */
714 
715 static int get_uint32_equal(QEMUFile *f, void *pv, size_t size,
716                             VMStateField *field)
717 {
718     uint32_t *v = pv;
719     uint32_t v2;
720     qemu_get_be32s(f, &v2);
721 
722     if (*v == v2) {
723         return 0;
724     }
725     error_report("%" PRIx32 " != %" PRIx32, *v, v2);
726     return -EINVAL;
727 }
728 
729 const VMStateInfo vmstate_info_uint32_equal = {
730     .name = "uint32 equal",
731     .get  = get_uint32_equal,
732     .put  = put_uint32,
733 };
734 
735 /* 64 bit unsigned int */
736 
737 static int get_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field)
738 {
739     uint64_t *v = pv;
740     qemu_get_be64s(f, v);
741     return 0;
742 }
743 
744 static int put_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
745                       QJSON *vmdesc)
746 {
747     uint64_t *v = pv;
748     qemu_put_be64s(f, v);
749     return 0;
750 }
751 
752 const VMStateInfo vmstate_info_uint64 = {
753     .name = "uint64",
754     .get  = get_uint64,
755     .put  = put_uint64,
756 };
757 
758 static int get_nullptr(QEMUFile *f, void *pv, size_t size, VMStateField *field)
759 
760 {
761     if (qemu_get_byte(f) == VMS_NULLPTR_MARKER) {
762         return  0;
763     }
764     error_report("vmstate: get_nullptr expected VMS_NULLPTR_MARKER");
765     return -EINVAL;
766 }
767 
768 static int put_nullptr(QEMUFile *f, void *pv, size_t size,
769                         VMStateField *field, QJSON *vmdesc)
770 
771 {
772     if (pv == NULL) {
773         qemu_put_byte(f, VMS_NULLPTR_MARKER);
774         return 0;
775     }
776     error_report("vmstate: put_nullptr must be called with pv == NULL");
777     return -EINVAL;
778 }
779 
780 const VMStateInfo vmstate_info_nullptr = {
781     .name = "uint64",
782     .get  = get_nullptr,
783     .put  = put_nullptr,
784 };
785 
786 /* 64 bit unsigned int. See that the received value is the same than the one
787    in the field */
788 
789 static int get_uint64_equal(QEMUFile *f, void *pv, size_t size,
790                             VMStateField *field)
791 {
792     uint64_t *v = pv;
793     uint64_t v2;
794     qemu_get_be64s(f, &v2);
795 
796     if (*v == v2) {
797         return 0;
798     }
799     error_report("%" PRIx64 " != %" PRIx64, *v, v2);
800     return -EINVAL;
801 }
802 
803 const VMStateInfo vmstate_info_uint64_equal = {
804     .name = "int64 equal",
805     .get  = get_uint64_equal,
806     .put  = put_uint64,
807 };
808 
809 /* 8 bit int. See that the received value is the same than the one
810    in the field */
811 
812 static int get_uint8_equal(QEMUFile *f, void *pv, size_t size,
813                            VMStateField *field)
814 {
815     uint8_t *v = pv;
816     uint8_t v2;
817     qemu_get_8s(f, &v2);
818 
819     if (*v == v2) {
820         return 0;
821     }
822     error_report("%x != %x", *v, v2);
823     return -EINVAL;
824 }
825 
826 const VMStateInfo vmstate_info_uint8_equal = {
827     .name = "uint8 equal",
828     .get  = get_uint8_equal,
829     .put  = put_uint8,
830 };
831 
832 /* 16 bit unsigned int int. See that the received value is the same than the one
833    in the field */
834 
835 static int get_uint16_equal(QEMUFile *f, void *pv, size_t size,
836                             VMStateField *field)
837 {
838     uint16_t *v = pv;
839     uint16_t v2;
840     qemu_get_be16s(f, &v2);
841 
842     if (*v == v2) {
843         return 0;
844     }
845     error_report("%x != %x", *v, v2);
846     return -EINVAL;
847 }
848 
849 const VMStateInfo vmstate_info_uint16_equal = {
850     .name = "uint16 equal",
851     .get  = get_uint16_equal,
852     .put  = put_uint16,
853 };
854 
855 /* floating point */
856 
857 static int get_float64(QEMUFile *f, void *pv, size_t size,
858                        VMStateField *field)
859 {
860     float64 *v = pv;
861 
862     *v = make_float64(qemu_get_be64(f));
863     return 0;
864 }
865 
866 static int put_float64(QEMUFile *f, void *pv, size_t size, VMStateField *field,
867                        QJSON *vmdesc)
868 {
869     uint64_t *v = pv;
870 
871     qemu_put_be64(f, float64_val(*v));
872     return 0;
873 }
874 
875 const VMStateInfo vmstate_info_float64 = {
876     .name = "float64",
877     .get  = get_float64,
878     .put  = put_float64,
879 };
880 
881 /* CPU_DoubleU type */
882 
883 static int get_cpudouble(QEMUFile *f, void *pv, size_t size,
884                          VMStateField *field)
885 {
886     CPU_DoubleU *v = pv;
887     qemu_get_be32s(f, &v->l.upper);
888     qemu_get_be32s(f, &v->l.lower);
889     return 0;
890 }
891 
892 static int put_cpudouble(QEMUFile *f, void *pv, size_t size,
893                          VMStateField *field, QJSON *vmdesc)
894 {
895     CPU_DoubleU *v = pv;
896     qemu_put_be32s(f, &v->l.upper);
897     qemu_put_be32s(f, &v->l.lower);
898     return 0;
899 }
900 
901 const VMStateInfo vmstate_info_cpudouble = {
902     .name = "CPU_Double_U",
903     .get  = get_cpudouble,
904     .put  = put_cpudouble,
905 };
906 
907 /* uint8_t buffers */
908 
909 static int get_buffer(QEMUFile *f, void *pv, size_t size,
910                       VMStateField *field)
911 {
912     uint8_t *v = pv;
913     qemu_get_buffer(f, v, size);
914     return 0;
915 }
916 
917 static int put_buffer(QEMUFile *f, void *pv, size_t size, VMStateField *field,
918                       QJSON *vmdesc)
919 {
920     uint8_t *v = pv;
921     qemu_put_buffer(f, v, size);
922     return 0;
923 }
924 
925 const VMStateInfo vmstate_info_buffer = {
926     .name = "buffer",
927     .get  = get_buffer,
928     .put  = put_buffer,
929 };
930 
931 /* unused buffers: space that was used for some fields that are
932    not useful anymore */
933 
934 static int get_unused_buffer(QEMUFile *f, void *pv, size_t size,
935                              VMStateField *field)
936 {
937     uint8_t buf[1024];
938     int block_len;
939 
940     while (size > 0) {
941         block_len = MIN(sizeof(buf), size);
942         size -= block_len;
943         qemu_get_buffer(f, buf, block_len);
944     }
945    return 0;
946 }
947 
948 static int put_unused_buffer(QEMUFile *f, void *pv, size_t size,
949                              VMStateField *field, QJSON *vmdesc)
950 {
951     static const uint8_t buf[1024];
952     int block_len;
953 
954     while (size > 0) {
955         block_len = MIN(sizeof(buf), size);
956         size -= block_len;
957         qemu_put_buffer(f, buf, block_len);
958     }
959 
960     return 0;
961 }
962 
963 const VMStateInfo vmstate_info_unused_buffer = {
964     .name = "unused_buffer",
965     .get  = get_unused_buffer,
966     .put  = put_unused_buffer,
967 };
968 
969 /* vmstate_info_tmp, see VMSTATE_WITH_TMP, the idea is that we allocate
970  * a temporary buffer and the pre_load/pre_save methods in the child vmsd
971  * copy stuff from the parent into the child and do calculations to fill
972  * in fields that don't really exist in the parent but need to be in the
973  * stream.
974  */
975 static int get_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field)
976 {
977     int ret;
978     const VMStateDescription *vmsd = field->vmsd;
979     int version_id = field->version_id;
980     void *tmp = g_malloc(size);
981 
982     /* Writes the parent field which is at the start of the tmp */
983     *(void **)tmp = pv;
984     ret = vmstate_load_state(f, vmsd, tmp, version_id);
985     g_free(tmp);
986     return ret;
987 }
988 
989 static int put_tmp(QEMUFile *f, void *pv, size_t size, VMStateField *field,
990                     QJSON *vmdesc)
991 {
992     const VMStateDescription *vmsd = field->vmsd;
993     void *tmp = g_malloc(size);
994 
995     /* Writes the parent field which is at the start of the tmp */
996     *(void **)tmp = pv;
997     vmstate_save_state(f, vmsd, tmp, vmdesc);
998     g_free(tmp);
999 
1000     return 0;
1001 }
1002 
1003 const VMStateInfo vmstate_info_tmp = {
1004     .name = "tmp",
1005     .get = get_tmp,
1006     .put = put_tmp,
1007 };
1008 
1009 /* bitmaps (as defined by bitmap.h). Note that size here is the size
1010  * of the bitmap in bits. The on-the-wire format of a bitmap is 64
1011  * bit words with the bits in big endian order. The in-memory format
1012  * is an array of 'unsigned long', which may be either 32 or 64 bits.
1013  */
1014 /* This is the number of 64 bit words sent over the wire */
1015 #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
1016 static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field)
1017 {
1018     unsigned long *bmp = pv;
1019     int i, idx = 0;
1020     for (i = 0; i < BITS_TO_U64S(size); i++) {
1021         uint64_t w = qemu_get_be64(f);
1022         bmp[idx++] = w;
1023         if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
1024             bmp[idx++] = w >> 32;
1025         }
1026     }
1027     return 0;
1028 }
1029 
1030 static int put_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field,
1031                       QJSON *vmdesc)
1032 {
1033     unsigned long *bmp = pv;
1034     int i, idx = 0;
1035     for (i = 0; i < BITS_TO_U64S(size); i++) {
1036         uint64_t w = bmp[idx++];
1037         if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
1038             w |= ((uint64_t)bmp[idx++]) << 32;
1039         }
1040         qemu_put_be64(f, w);
1041     }
1042 
1043     return 0;
1044 }
1045 
1046 const VMStateInfo vmstate_info_bitmap = {
1047     .name = "bitmap",
1048     .get = get_bitmap,
1049     .put = put_bitmap,
1050 };
1051 
1052 /* get for QTAILQ
1053  * meta data about the QTAILQ is encoded in a VMStateField structure
1054  */
1055 static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size,
1056                       VMStateField *field)
1057 {
1058     int ret = 0;
1059     const VMStateDescription *vmsd = field->vmsd;
1060     /* size of a QTAILQ element */
1061     size_t size = field->size;
1062     /* offset of the QTAILQ entry in a QTAILQ element */
1063     size_t entry_offset = field->start;
1064     int version_id = field->version_id;
1065     void *elm;
1066 
1067     trace_get_qtailq(vmsd->name, version_id);
1068     if (version_id > vmsd->version_id) {
1069         error_report("%s %s",  vmsd->name, "too new");
1070         trace_get_qtailq_end(vmsd->name, "too new", -EINVAL);
1071 
1072         return -EINVAL;
1073     }
1074     if (version_id < vmsd->minimum_version_id) {
1075         error_report("%s %s",  vmsd->name, "too old");
1076         trace_get_qtailq_end(vmsd->name, "too old", -EINVAL);
1077         return -EINVAL;
1078     }
1079 
1080     while (qemu_get_byte(f)) {
1081         elm = g_malloc(size);
1082         ret = vmstate_load_state(f, vmsd, elm, version_id);
1083         if (ret) {
1084             return ret;
1085         }
1086         QTAILQ_RAW_INSERT_TAIL(pv, elm, entry_offset);
1087     }
1088 
1089     trace_get_qtailq_end(vmsd->name, "end", ret);
1090     return ret;
1091 }
1092 
1093 /* put for QTAILQ */
1094 static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size,
1095                       VMStateField *field, QJSON *vmdesc)
1096 {
1097     const VMStateDescription *vmsd = field->vmsd;
1098     /* offset of the QTAILQ entry in a QTAILQ element*/
1099     size_t entry_offset = field->start;
1100     void *elm;
1101 
1102     trace_put_qtailq(vmsd->name, vmsd->version_id);
1103 
1104     QTAILQ_RAW_FOREACH(elm, pv, entry_offset) {
1105         qemu_put_byte(f, true);
1106         vmstate_save_state(f, vmsd, elm, vmdesc);
1107     }
1108     qemu_put_byte(f, false);
1109 
1110     trace_put_qtailq_end(vmsd->name, "end");
1111 
1112     return 0;
1113 }
1114 const VMStateInfo vmstate_info_qtailq = {
1115     .name = "qtailq",
1116     .get  = get_qtailq,
1117     .put  = put_qtailq,
1118 };
1119