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