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