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