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 + field->start) = g_malloc(size); 72 } 73 } 74 base_addr = *(void **)base_addr + field->start; 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 if (vmsd->pre_save) { 310 vmsd->pre_save(opaque); 311 } 312 313 if (vmdesc) { 314 json_prop_str(vmdesc, "vmsd_name", vmsd->name); 315 json_prop_int(vmdesc, "version", vmsd->version_id); 316 json_start_array(vmdesc, "fields"); 317 } 318 319 while (field->name) { 320 if (!field->field_exists || 321 field->field_exists(opaque, vmsd->version_id)) { 322 void *base_addr = vmstate_base_addr(opaque, field, false); 323 int i, n_elems = vmstate_n_elems(opaque, field); 324 int size = vmstate_size(opaque, field); 325 int64_t old_offset, written_bytes; 326 QJSON *vmdesc_loop = vmdesc; 327 328 for (i = 0; i < n_elems; i++) { 329 void *addr = base_addr + size * i; 330 331 vmsd_desc_field_start(vmsd, vmdesc_loop, field, i, n_elems); 332 old_offset = qemu_ftell_fast(f); 333 334 if (field->flags & VMS_ARRAY_OF_POINTER) { 335 addr = *(void **)addr; 336 } 337 if (field->flags & VMS_STRUCT) { 338 vmstate_save_state(f, field->vmsd, addr, vmdesc_loop); 339 } else { 340 field->info->put(f, addr, size, field, vmdesc_loop); 341 } 342 343 written_bytes = qemu_ftell_fast(f) - old_offset; 344 vmsd_desc_field_end(vmsd, vmdesc_loop, field, written_bytes, i); 345 346 /* Compressed arrays only care about the first element */ 347 if (vmdesc_loop && vmsd_can_compress(field)) { 348 vmdesc_loop = NULL; 349 } 350 } 351 } else { 352 if (field->flags & VMS_MUST_EXIST) { 353 error_report("Output state validation failed: %s/%s", 354 vmsd->name, field->name); 355 assert(!(field->flags & VMS_MUST_EXIST)); 356 } 357 } 358 field++; 359 } 360 361 if (vmdesc) { 362 json_end_array(vmdesc); 363 } 364 365 vmstate_subsection_save(f, vmsd, opaque, vmdesc); 366 } 367 368 static const VMStateDescription * 369 vmstate_get_subsection(const VMStateDescription **sub, char *idstr) 370 { 371 while (sub && *sub && (*sub)->needed) { 372 if (strcmp(idstr, (*sub)->name) == 0) { 373 return *sub; 374 } 375 sub++; 376 } 377 return NULL; 378 } 379 380 static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd, 381 void *opaque) 382 { 383 trace_vmstate_subsection_load(vmsd->name); 384 385 while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) { 386 char idstr[256], *idstr_ret; 387 int ret; 388 uint8_t version_id, len, size; 389 const VMStateDescription *sub_vmsd; 390 391 len = qemu_peek_byte(f, 1); 392 if (len < strlen(vmsd->name) + 1) { 393 /* subsection name has be be "section_name/a" */ 394 trace_vmstate_subsection_load_bad(vmsd->name, "(short)", ""); 395 return 0; 396 } 397 size = qemu_peek_buffer(f, (uint8_t **)&idstr_ret, len, 2); 398 if (size != len) { 399 trace_vmstate_subsection_load_bad(vmsd->name, "(peek fail)", ""); 400 return 0; 401 } 402 memcpy(idstr, idstr_ret, size); 403 idstr[size] = 0; 404 405 if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) { 406 trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(prefix)"); 407 /* it doesn't have a valid subsection name */ 408 return 0; 409 } 410 sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr); 411 if (sub_vmsd == NULL) { 412 trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(lookup)"); 413 return -ENOENT; 414 } 415 qemu_file_skip(f, 1); /* subsection */ 416 qemu_file_skip(f, 1); /* len */ 417 qemu_file_skip(f, len); /* idstr */ 418 version_id = qemu_get_be32(f); 419 420 ret = vmstate_load_state(f, sub_vmsd, opaque, version_id); 421 if (ret) { 422 trace_vmstate_subsection_load_bad(vmsd->name, idstr, "(child)"); 423 return ret; 424 } 425 } 426 427 trace_vmstate_subsection_load_good(vmsd->name); 428 return 0; 429 } 430 431 static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd, 432 void *opaque, QJSON *vmdesc) 433 { 434 const VMStateDescription **sub = vmsd->subsections; 435 bool subsection_found = false; 436 437 while (sub && *sub && (*sub)->needed) { 438 if ((*sub)->needed(opaque)) { 439 const VMStateDescription *vmsd = *sub; 440 uint8_t len; 441 442 if (vmdesc) { 443 /* Only create subsection array when we have any */ 444 if (!subsection_found) { 445 json_start_array(vmdesc, "subsections"); 446 subsection_found = true; 447 } 448 449 json_start_object(vmdesc, NULL); 450 } 451 452 qemu_put_byte(f, QEMU_VM_SUBSECTION); 453 len = strlen(vmsd->name); 454 qemu_put_byte(f, len); 455 qemu_put_buffer(f, (uint8_t *)vmsd->name, len); 456 qemu_put_be32(f, vmsd->version_id); 457 vmstate_save_state(f, vmsd, opaque, vmdesc); 458 459 if (vmdesc) { 460 json_end_object(vmdesc); 461 } 462 } 463 sub++; 464 } 465 466 if (vmdesc && subsection_found) { 467 json_end_array(vmdesc); 468 } 469 } 470 471 /* bool */ 472 473 static int get_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field) 474 { 475 bool *v = pv; 476 *v = qemu_get_byte(f); 477 return 0; 478 } 479 480 static int put_bool(QEMUFile *f, void *pv, size_t size, VMStateField *field, 481 QJSON *vmdesc) 482 { 483 bool *v = pv; 484 qemu_put_byte(f, *v); 485 return 0; 486 } 487 488 const VMStateInfo vmstate_info_bool = { 489 .name = "bool", 490 .get = get_bool, 491 .put = put_bool, 492 }; 493 494 /* 8 bit int */ 495 496 static int get_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field) 497 { 498 int8_t *v = pv; 499 qemu_get_s8s(f, v); 500 return 0; 501 } 502 503 static int put_int8(QEMUFile *f, void *pv, size_t size, VMStateField *field, 504 QJSON *vmdesc) 505 { 506 int8_t *v = pv; 507 qemu_put_s8s(f, v); 508 return 0; 509 } 510 511 const VMStateInfo vmstate_info_int8 = { 512 .name = "int8", 513 .get = get_int8, 514 .put = put_int8, 515 }; 516 517 /* 16 bit int */ 518 519 static int get_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field) 520 { 521 int16_t *v = pv; 522 qemu_get_sbe16s(f, v); 523 return 0; 524 } 525 526 static int put_int16(QEMUFile *f, void *pv, size_t size, VMStateField *field, 527 QJSON *vmdesc) 528 { 529 int16_t *v = pv; 530 qemu_put_sbe16s(f, v); 531 return 0; 532 } 533 534 const VMStateInfo vmstate_info_int16 = { 535 .name = "int16", 536 .get = get_int16, 537 .put = put_int16, 538 }; 539 540 /* 32 bit int */ 541 542 static int get_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field) 543 { 544 int32_t *v = pv; 545 qemu_get_sbe32s(f, v); 546 return 0; 547 } 548 549 static int put_int32(QEMUFile *f, void *pv, size_t size, VMStateField *field, 550 QJSON *vmdesc) 551 { 552 int32_t *v = pv; 553 qemu_put_sbe32s(f, v); 554 return 0; 555 } 556 557 const VMStateInfo vmstate_info_int32 = { 558 .name = "int32", 559 .get = get_int32, 560 .put = put_int32, 561 }; 562 563 /* 32 bit int. See that the received value is the same than the one 564 in the field */ 565 566 static int get_int32_equal(QEMUFile *f, void *pv, size_t size, 567 VMStateField *field) 568 { 569 int32_t *v = pv; 570 int32_t v2; 571 qemu_get_sbe32s(f, &v2); 572 573 if (*v == v2) { 574 return 0; 575 } 576 error_report("%" PRIx32 " != %" PRIx32, *v, v2); 577 return -EINVAL; 578 } 579 580 const VMStateInfo vmstate_info_int32_equal = { 581 .name = "int32 equal", 582 .get = get_int32_equal, 583 .put = put_int32, 584 }; 585 586 /* 32 bit int. Check that the received value is non-negative 587 * and less than or equal to the one in the field. 588 */ 589 590 static int get_int32_le(QEMUFile *f, void *pv, size_t size, VMStateField *field) 591 { 592 int32_t *cur = pv; 593 int32_t loaded; 594 qemu_get_sbe32s(f, &loaded); 595 596 if (loaded >= 0 && loaded <= *cur) { 597 *cur = loaded; 598 return 0; 599 } 600 error_report("Invalid value %" PRId32 601 " expecting positive value <= %" PRId32, 602 loaded, *cur); 603 return -EINVAL; 604 } 605 606 const VMStateInfo vmstate_info_int32_le = { 607 .name = "int32 le", 608 .get = get_int32_le, 609 .put = put_int32, 610 }; 611 612 /* 64 bit int */ 613 614 static int get_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field) 615 { 616 int64_t *v = pv; 617 qemu_get_sbe64s(f, v); 618 return 0; 619 } 620 621 static int put_int64(QEMUFile *f, void *pv, size_t size, VMStateField *field, 622 QJSON *vmdesc) 623 { 624 int64_t *v = pv; 625 qemu_put_sbe64s(f, v); 626 return 0; 627 } 628 629 const VMStateInfo vmstate_info_int64 = { 630 .name = "int64", 631 .get = get_int64, 632 .put = put_int64, 633 }; 634 635 /* 8 bit unsigned int */ 636 637 static int get_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field) 638 { 639 uint8_t *v = pv; 640 qemu_get_8s(f, v); 641 return 0; 642 } 643 644 static int put_uint8(QEMUFile *f, void *pv, size_t size, VMStateField *field, 645 QJSON *vmdesc) 646 { 647 uint8_t *v = pv; 648 qemu_put_8s(f, v); 649 return 0; 650 } 651 652 const VMStateInfo vmstate_info_uint8 = { 653 .name = "uint8", 654 .get = get_uint8, 655 .put = put_uint8, 656 }; 657 658 /* 16 bit unsigned int */ 659 660 static int get_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field) 661 { 662 uint16_t *v = pv; 663 qemu_get_be16s(f, v); 664 return 0; 665 } 666 667 static int put_uint16(QEMUFile *f, void *pv, size_t size, VMStateField *field, 668 QJSON *vmdesc) 669 { 670 uint16_t *v = pv; 671 qemu_put_be16s(f, v); 672 return 0; 673 } 674 675 const VMStateInfo vmstate_info_uint16 = { 676 .name = "uint16", 677 .get = get_uint16, 678 .put = put_uint16, 679 }; 680 681 /* 32 bit unsigned int */ 682 683 static int get_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field) 684 { 685 uint32_t *v = pv; 686 qemu_get_be32s(f, v); 687 return 0; 688 } 689 690 static int put_uint32(QEMUFile *f, void *pv, size_t size, VMStateField *field, 691 QJSON *vmdesc) 692 { 693 uint32_t *v = pv; 694 qemu_put_be32s(f, v); 695 return 0; 696 } 697 698 const VMStateInfo vmstate_info_uint32 = { 699 .name = "uint32", 700 .get = get_uint32, 701 .put = put_uint32, 702 }; 703 704 /* 32 bit uint. See that the received value is the same than the one 705 in the field */ 706 707 static int get_uint32_equal(QEMUFile *f, void *pv, size_t size, 708 VMStateField *field) 709 { 710 uint32_t *v = pv; 711 uint32_t v2; 712 qemu_get_be32s(f, &v2); 713 714 if (*v == v2) { 715 return 0; 716 } 717 error_report("%" PRIx32 " != %" PRIx32, *v, v2); 718 return -EINVAL; 719 } 720 721 const VMStateInfo vmstate_info_uint32_equal = { 722 .name = "uint32 equal", 723 .get = get_uint32_equal, 724 .put = put_uint32, 725 }; 726 727 /* 64 bit unsigned int */ 728 729 static int get_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field) 730 { 731 uint64_t *v = pv; 732 qemu_get_be64s(f, v); 733 return 0; 734 } 735 736 static int put_uint64(QEMUFile *f, void *pv, size_t size, VMStateField *field, 737 QJSON *vmdesc) 738 { 739 uint64_t *v = pv; 740 qemu_put_be64s(f, v); 741 return 0; 742 } 743 744 const VMStateInfo vmstate_info_uint64 = { 745 .name = "uint64", 746 .get = get_uint64, 747 .put = put_uint64, 748 }; 749 750 /* 64 bit unsigned int. See that the received value is the same than the one 751 in the field */ 752 753 static int get_uint64_equal(QEMUFile *f, void *pv, size_t size, 754 VMStateField *field) 755 { 756 uint64_t *v = pv; 757 uint64_t v2; 758 qemu_get_be64s(f, &v2); 759 760 if (*v == v2) { 761 return 0; 762 } 763 error_report("%" PRIx64 " != %" PRIx64, *v, v2); 764 return -EINVAL; 765 } 766 767 const VMStateInfo vmstate_info_uint64_equal = { 768 .name = "int64 equal", 769 .get = get_uint64_equal, 770 .put = put_uint64, 771 }; 772 773 /* 8 bit int. See that the received value is the same than the one 774 in the field */ 775 776 static int get_uint8_equal(QEMUFile *f, void *pv, size_t size, 777 VMStateField *field) 778 { 779 uint8_t *v = pv; 780 uint8_t v2; 781 qemu_get_8s(f, &v2); 782 783 if (*v == v2) { 784 return 0; 785 } 786 error_report("%x != %x", *v, v2); 787 return -EINVAL; 788 } 789 790 const VMStateInfo vmstate_info_uint8_equal = { 791 .name = "uint8 equal", 792 .get = get_uint8_equal, 793 .put = put_uint8, 794 }; 795 796 /* 16 bit unsigned int int. See that the received value is the same than the one 797 in the field */ 798 799 static int get_uint16_equal(QEMUFile *f, void *pv, size_t size, 800 VMStateField *field) 801 { 802 uint16_t *v = pv; 803 uint16_t v2; 804 qemu_get_be16s(f, &v2); 805 806 if (*v == v2) { 807 return 0; 808 } 809 error_report("%x != %x", *v, v2); 810 return -EINVAL; 811 } 812 813 const VMStateInfo vmstate_info_uint16_equal = { 814 .name = "uint16 equal", 815 .get = get_uint16_equal, 816 .put = put_uint16, 817 }; 818 819 /* floating point */ 820 821 static int get_float64(QEMUFile *f, void *pv, size_t size, 822 VMStateField *field) 823 { 824 float64 *v = pv; 825 826 *v = make_float64(qemu_get_be64(f)); 827 return 0; 828 } 829 830 static int put_float64(QEMUFile *f, void *pv, size_t size, VMStateField *field, 831 QJSON *vmdesc) 832 { 833 uint64_t *v = pv; 834 835 qemu_put_be64(f, float64_val(*v)); 836 return 0; 837 } 838 839 const VMStateInfo vmstate_info_float64 = { 840 .name = "float64", 841 .get = get_float64, 842 .put = put_float64, 843 }; 844 845 /* CPU_DoubleU type */ 846 847 static int get_cpudouble(QEMUFile *f, void *pv, size_t size, 848 VMStateField *field) 849 { 850 CPU_DoubleU *v = pv; 851 qemu_get_be32s(f, &v->l.upper); 852 qemu_get_be32s(f, &v->l.lower); 853 return 0; 854 } 855 856 static int put_cpudouble(QEMUFile *f, void *pv, size_t size, 857 VMStateField *field, QJSON *vmdesc) 858 { 859 CPU_DoubleU *v = pv; 860 qemu_put_be32s(f, &v->l.upper); 861 qemu_put_be32s(f, &v->l.lower); 862 return 0; 863 } 864 865 const VMStateInfo vmstate_info_cpudouble = { 866 .name = "CPU_Double_U", 867 .get = get_cpudouble, 868 .put = put_cpudouble, 869 }; 870 871 /* uint8_t buffers */ 872 873 static int get_buffer(QEMUFile *f, void *pv, size_t size, 874 VMStateField *field) 875 { 876 uint8_t *v = pv; 877 qemu_get_buffer(f, v, size); 878 return 0; 879 } 880 881 static int put_buffer(QEMUFile *f, void *pv, size_t size, VMStateField *field, 882 QJSON *vmdesc) 883 { 884 uint8_t *v = pv; 885 qemu_put_buffer(f, v, size); 886 return 0; 887 } 888 889 const VMStateInfo vmstate_info_buffer = { 890 .name = "buffer", 891 .get = get_buffer, 892 .put = put_buffer, 893 }; 894 895 /* unused buffers: space that was used for some fields that are 896 not useful anymore */ 897 898 static int get_unused_buffer(QEMUFile *f, void *pv, size_t size, 899 VMStateField *field) 900 { 901 uint8_t buf[1024]; 902 int block_len; 903 904 while (size > 0) { 905 block_len = MIN(sizeof(buf), size); 906 size -= block_len; 907 qemu_get_buffer(f, buf, block_len); 908 } 909 return 0; 910 } 911 912 static int put_unused_buffer(QEMUFile *f, void *pv, size_t size, 913 VMStateField *field, QJSON *vmdesc) 914 { 915 static const uint8_t buf[1024]; 916 int block_len; 917 918 while (size > 0) { 919 block_len = MIN(sizeof(buf), size); 920 size -= block_len; 921 qemu_put_buffer(f, buf, block_len); 922 } 923 924 return 0; 925 } 926 927 const VMStateInfo vmstate_info_unused_buffer = { 928 .name = "unused_buffer", 929 .get = get_unused_buffer, 930 .put = put_unused_buffer, 931 }; 932 933 /* bitmaps (as defined by bitmap.h). Note that size here is the size 934 * of the bitmap in bits. The on-the-wire format of a bitmap is 64 935 * bit words with the bits in big endian order. The in-memory format 936 * is an array of 'unsigned long', which may be either 32 or 64 bits. 937 */ 938 /* This is the number of 64 bit words sent over the wire */ 939 #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64) 940 static int get_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field) 941 { 942 unsigned long *bmp = pv; 943 int i, idx = 0; 944 for (i = 0; i < BITS_TO_U64S(size); i++) { 945 uint64_t w = qemu_get_be64(f); 946 bmp[idx++] = w; 947 if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) { 948 bmp[idx++] = w >> 32; 949 } 950 } 951 return 0; 952 } 953 954 static int put_bitmap(QEMUFile *f, void *pv, size_t size, VMStateField *field, 955 QJSON *vmdesc) 956 { 957 unsigned long *bmp = pv; 958 int i, idx = 0; 959 for (i = 0; i < BITS_TO_U64S(size); i++) { 960 uint64_t w = bmp[idx++]; 961 if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) { 962 w |= ((uint64_t)bmp[idx++]) << 32; 963 } 964 qemu_put_be64(f, w); 965 } 966 967 return 0; 968 } 969 970 const VMStateInfo vmstate_info_bitmap = { 971 .name = "bitmap", 972 .get = get_bitmap, 973 .put = put_bitmap, 974 }; 975 976 /* get for QTAILQ 977 * meta data about the QTAILQ is encoded in a VMStateField structure 978 */ 979 static int get_qtailq(QEMUFile *f, void *pv, size_t unused_size, 980 VMStateField *field) 981 { 982 int ret = 0; 983 const VMStateDescription *vmsd = field->vmsd; 984 /* size of a QTAILQ element */ 985 size_t size = field->size; 986 /* offset of the QTAILQ entry in a QTAILQ element */ 987 size_t entry_offset = field->start; 988 int version_id = field->version_id; 989 void *elm; 990 991 trace_get_qtailq(vmsd->name, version_id); 992 if (version_id > vmsd->version_id) { 993 error_report("%s %s", vmsd->name, "too new"); 994 trace_get_qtailq_end(vmsd->name, "too new", -EINVAL); 995 996 return -EINVAL; 997 } 998 if (version_id < vmsd->minimum_version_id) { 999 error_report("%s %s", vmsd->name, "too old"); 1000 trace_get_qtailq_end(vmsd->name, "too old", -EINVAL); 1001 return -EINVAL; 1002 } 1003 1004 while (qemu_get_byte(f)) { 1005 elm = g_malloc(size); 1006 ret = vmstate_load_state(f, vmsd, elm, version_id); 1007 if (ret) { 1008 return ret; 1009 } 1010 QTAILQ_RAW_INSERT_TAIL(pv, elm, entry_offset); 1011 } 1012 1013 trace_get_qtailq_end(vmsd->name, "end", ret); 1014 return ret; 1015 } 1016 1017 /* put for QTAILQ */ 1018 static int put_qtailq(QEMUFile *f, void *pv, size_t unused_size, 1019 VMStateField *field, QJSON *vmdesc) 1020 { 1021 const VMStateDescription *vmsd = field->vmsd; 1022 /* offset of the QTAILQ entry in a QTAILQ element*/ 1023 size_t entry_offset = field->start; 1024 void *elm; 1025 1026 trace_put_qtailq(vmsd->name, vmsd->version_id); 1027 1028 QTAILQ_RAW_FOREACH(elm, pv, entry_offset) { 1029 qemu_put_byte(f, true); 1030 vmstate_save_state(f, vmsd, elm, vmdesc); 1031 } 1032 qemu_put_byte(f, false); 1033 1034 trace_put_qtailq_end(vmsd->name, "end"); 1035 1036 return 0; 1037 } 1038 const VMStateInfo vmstate_info_qtailq = { 1039 .name = "qtailq", 1040 .get = get_qtailq, 1041 .put = put_qtailq, 1042 }; 1043