2
0

vmstate.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680
  1. #include "qemu-common.h"
  2. #include "migration/migration.h"
  3. #include "migration/qemu-file.h"
  4. #include "migration/vmstate.h"
  5. #include "qemu/bitops.h"
  6. #include "trace.h"
  7. static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
  8. void *opaque);
  9. static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
  10. void *opaque);
  11. static int vmstate_n_elems(void *opaque, VMStateField *field)
  12. {
  13. int n_elems = 1;
  14. if (field->flags & VMS_ARRAY) {
  15. n_elems = field->num;
  16. } else if (field->flags & VMS_VARRAY_INT32) {
  17. n_elems = *(int32_t *)(opaque+field->num_offset);
  18. } else if (field->flags & VMS_VARRAY_UINT32) {
  19. n_elems = *(uint32_t *)(opaque+field->num_offset);
  20. } else if (field->flags & VMS_VARRAY_UINT16) {
  21. n_elems = *(uint16_t *)(opaque+field->num_offset);
  22. } else if (field->flags & VMS_VARRAY_UINT8) {
  23. n_elems = *(uint8_t *)(opaque+field->num_offset);
  24. }
  25. return n_elems;
  26. }
  27. static int vmstate_size(void *opaque, VMStateField *field)
  28. {
  29. int size = field->size;
  30. if (field->flags & VMS_VBUFFER) {
  31. size = *(int32_t *)(opaque+field->size_offset);
  32. if (field->flags & VMS_MULTIPLY) {
  33. size *= field->size;
  34. }
  35. }
  36. return size;
  37. }
  38. static void *vmstate_base_addr(void *opaque, VMStateField *field, bool alloc)
  39. {
  40. void *base_addr = opaque + field->offset;
  41. if (field->flags & VMS_POINTER) {
  42. if (alloc && (field->flags & VMS_ALLOC)) {
  43. int n_elems = vmstate_n_elems(opaque, field);
  44. if (n_elems) {
  45. gsize size = n_elems * field->size;
  46. *((void **)base_addr + field->start) = g_malloc(size);
  47. }
  48. }
  49. base_addr = *(void **)base_addr + field->start;
  50. }
  51. return base_addr;
  52. }
  53. int vmstate_load_state(QEMUFile *f, const VMStateDescription *vmsd,
  54. void *opaque, int version_id)
  55. {
  56. VMStateField *field = vmsd->fields;
  57. int ret;
  58. if (version_id > vmsd->version_id) {
  59. return -EINVAL;
  60. }
  61. if (version_id < vmsd->minimum_version_id) {
  62. if (vmsd->load_state_old &&
  63. version_id >= vmsd->minimum_version_id_old) {
  64. return vmsd->load_state_old(f, opaque, version_id);
  65. }
  66. return -EINVAL;
  67. }
  68. if (vmsd->pre_load) {
  69. int ret = vmsd->pre_load(opaque);
  70. if (ret) {
  71. return ret;
  72. }
  73. }
  74. while (field->name) {
  75. if ((field->field_exists &&
  76. field->field_exists(opaque, version_id)) ||
  77. (!field->field_exists &&
  78. field->version_id <= version_id)) {
  79. void *base_addr = vmstate_base_addr(opaque, field, true);
  80. int i, n_elems = vmstate_n_elems(opaque, field);
  81. int size = vmstate_size(opaque, field);
  82. for (i = 0; i < n_elems; i++) {
  83. void *addr = base_addr + size * i;
  84. if (field->flags & VMS_ARRAY_OF_POINTER) {
  85. addr = *(void **)addr;
  86. }
  87. if (field->flags & VMS_STRUCT) {
  88. ret = vmstate_load_state(f, field->vmsd, addr,
  89. field->vmsd->version_id);
  90. } else {
  91. ret = field->info->get(f, addr, size);
  92. }
  93. if (ret >= 0) {
  94. ret = qemu_file_get_error(f);
  95. }
  96. if (ret < 0) {
  97. qemu_file_set_error(f, ret);
  98. trace_vmstate_load_field_error(field->name, ret);
  99. return ret;
  100. }
  101. }
  102. } else if (field->flags & VMS_MUST_EXIST) {
  103. fprintf(stderr, "Input validation failed: %s/%s\n",
  104. vmsd->name, field->name);
  105. return -1;
  106. }
  107. field++;
  108. }
  109. ret = vmstate_subsection_load(f, vmsd, opaque);
  110. if (ret != 0) {
  111. return ret;
  112. }
  113. if (vmsd->post_load) {
  114. return vmsd->post_load(opaque, version_id);
  115. }
  116. return 0;
  117. }
  118. void vmstate_save_state(QEMUFile *f, const VMStateDescription *vmsd,
  119. void *opaque)
  120. {
  121. VMStateField *field = vmsd->fields;
  122. if (vmsd->pre_save) {
  123. vmsd->pre_save(opaque);
  124. }
  125. while (field->name) {
  126. if (!field->field_exists ||
  127. field->field_exists(opaque, vmsd->version_id)) {
  128. void *base_addr = vmstate_base_addr(opaque, field, false);
  129. int i, n_elems = vmstate_n_elems(opaque, field);
  130. int size = vmstate_size(opaque, field);
  131. for (i = 0; i < n_elems; i++) {
  132. void *addr = base_addr + size * i;
  133. if (field->flags & VMS_ARRAY_OF_POINTER) {
  134. addr = *(void **)addr;
  135. }
  136. if (field->flags & VMS_STRUCT) {
  137. vmstate_save_state(f, field->vmsd, addr);
  138. } else {
  139. field->info->put(f, addr, size);
  140. }
  141. }
  142. } else {
  143. if (field->flags & VMS_MUST_EXIST) {
  144. fprintf(stderr, "Output state validation failed: %s/%s\n",
  145. vmsd->name, field->name);
  146. assert(!(field->flags & VMS_MUST_EXIST));
  147. }
  148. }
  149. field++;
  150. }
  151. vmstate_subsection_save(f, vmsd, opaque);
  152. }
  153. static const VMStateDescription *
  154. vmstate_get_subsection(const VMStateSubsection *sub, char *idstr)
  155. {
  156. while (sub && sub->needed) {
  157. if (strcmp(idstr, sub->vmsd->name) == 0) {
  158. return sub->vmsd;
  159. }
  160. sub++;
  161. }
  162. return NULL;
  163. }
  164. static int vmstate_subsection_load(QEMUFile *f, const VMStateDescription *vmsd,
  165. void *opaque)
  166. {
  167. while (qemu_peek_byte(f, 0) == QEMU_VM_SUBSECTION) {
  168. char idstr[256];
  169. int ret;
  170. uint8_t version_id, len, size;
  171. const VMStateDescription *sub_vmsd;
  172. len = qemu_peek_byte(f, 1);
  173. if (len < strlen(vmsd->name) + 1) {
  174. /* subsection name has be be "section_name/a" */
  175. return 0;
  176. }
  177. size = qemu_peek_buffer(f, (uint8_t *)idstr, len, 2);
  178. if (size != len) {
  179. return 0;
  180. }
  181. idstr[size] = 0;
  182. if (strncmp(vmsd->name, idstr, strlen(vmsd->name)) != 0) {
  183. /* it don't have a valid subsection name */
  184. return 0;
  185. }
  186. sub_vmsd = vmstate_get_subsection(vmsd->subsections, idstr);
  187. if (sub_vmsd == NULL) {
  188. return -ENOENT;
  189. }
  190. qemu_file_skip(f, 1); /* subsection */
  191. qemu_file_skip(f, 1); /* len */
  192. qemu_file_skip(f, len); /* idstr */
  193. version_id = qemu_get_be32(f);
  194. ret = vmstate_load_state(f, sub_vmsd, opaque, version_id);
  195. if (ret) {
  196. return ret;
  197. }
  198. }
  199. return 0;
  200. }
  201. static void vmstate_subsection_save(QEMUFile *f, const VMStateDescription *vmsd,
  202. void *opaque)
  203. {
  204. const VMStateSubsection *sub = vmsd->subsections;
  205. while (sub && sub->needed) {
  206. if (sub->needed(opaque)) {
  207. const VMStateDescription *vmsd = sub->vmsd;
  208. uint8_t len;
  209. qemu_put_byte(f, QEMU_VM_SUBSECTION);
  210. len = strlen(vmsd->name);
  211. qemu_put_byte(f, len);
  212. qemu_put_buffer(f, (uint8_t *)vmsd->name, len);
  213. qemu_put_be32(f, vmsd->version_id);
  214. vmstate_save_state(f, vmsd, opaque);
  215. }
  216. sub++;
  217. }
  218. }
  219. /* bool */
  220. static int get_bool(QEMUFile *f, void *pv, size_t size)
  221. {
  222. bool *v = pv;
  223. *v = qemu_get_byte(f);
  224. return 0;
  225. }
  226. static void put_bool(QEMUFile *f, void *pv, size_t size)
  227. {
  228. bool *v = pv;
  229. qemu_put_byte(f, *v);
  230. }
  231. const VMStateInfo vmstate_info_bool = {
  232. .name = "bool",
  233. .get = get_bool,
  234. .put = put_bool,
  235. };
  236. /* 8 bit int */
  237. static int get_int8(QEMUFile *f, void *pv, size_t size)
  238. {
  239. int8_t *v = pv;
  240. qemu_get_s8s(f, v);
  241. return 0;
  242. }
  243. static void put_int8(QEMUFile *f, void *pv, size_t size)
  244. {
  245. int8_t *v = pv;
  246. qemu_put_s8s(f, v);
  247. }
  248. const VMStateInfo vmstate_info_int8 = {
  249. .name = "int8",
  250. .get = get_int8,
  251. .put = put_int8,
  252. };
  253. /* 16 bit int */
  254. static int get_int16(QEMUFile *f, void *pv, size_t size)
  255. {
  256. int16_t *v = pv;
  257. qemu_get_sbe16s(f, v);
  258. return 0;
  259. }
  260. static void put_int16(QEMUFile *f, void *pv, size_t size)
  261. {
  262. int16_t *v = pv;
  263. qemu_put_sbe16s(f, v);
  264. }
  265. const VMStateInfo vmstate_info_int16 = {
  266. .name = "int16",
  267. .get = get_int16,
  268. .put = put_int16,
  269. };
  270. /* 32 bit int */
  271. static int get_int32(QEMUFile *f, void *pv, size_t size)
  272. {
  273. int32_t *v = pv;
  274. qemu_get_sbe32s(f, v);
  275. return 0;
  276. }
  277. static void put_int32(QEMUFile *f, void *pv, size_t size)
  278. {
  279. int32_t *v = pv;
  280. qemu_put_sbe32s(f, v);
  281. }
  282. const VMStateInfo vmstate_info_int32 = {
  283. .name = "int32",
  284. .get = get_int32,
  285. .put = put_int32,
  286. };
  287. /* 32 bit int. See that the received value is the same than the one
  288. in the field */
  289. static int get_int32_equal(QEMUFile *f, void *pv, size_t size)
  290. {
  291. int32_t *v = pv;
  292. int32_t v2;
  293. qemu_get_sbe32s(f, &v2);
  294. if (*v == v2) {
  295. return 0;
  296. }
  297. return -EINVAL;
  298. }
  299. const VMStateInfo vmstate_info_int32_equal = {
  300. .name = "int32 equal",
  301. .get = get_int32_equal,
  302. .put = put_int32,
  303. };
  304. /* 32 bit int. Check that the received value is non-negative
  305. * and less than or equal to the one in the field.
  306. */
  307. static int get_int32_le(QEMUFile *f, void *pv, size_t size)
  308. {
  309. int32_t *cur = pv;
  310. int32_t loaded;
  311. qemu_get_sbe32s(f, &loaded);
  312. if (loaded >= 0 && loaded <= *cur) {
  313. *cur = loaded;
  314. return 0;
  315. }
  316. return -EINVAL;
  317. }
  318. const VMStateInfo vmstate_info_int32_le = {
  319. .name = "int32 le",
  320. .get = get_int32_le,
  321. .put = put_int32,
  322. };
  323. /* 64 bit int */
  324. static int get_int64(QEMUFile *f, void *pv, size_t size)
  325. {
  326. int64_t *v = pv;
  327. qemu_get_sbe64s(f, v);
  328. return 0;
  329. }
  330. static void put_int64(QEMUFile *f, void *pv, size_t size)
  331. {
  332. int64_t *v = pv;
  333. qemu_put_sbe64s(f, v);
  334. }
  335. const VMStateInfo vmstate_info_int64 = {
  336. .name = "int64",
  337. .get = get_int64,
  338. .put = put_int64,
  339. };
  340. /* 8 bit unsigned int */
  341. static int get_uint8(QEMUFile *f, void *pv, size_t size)
  342. {
  343. uint8_t *v = pv;
  344. qemu_get_8s(f, v);
  345. return 0;
  346. }
  347. static void put_uint8(QEMUFile *f, void *pv, size_t size)
  348. {
  349. uint8_t *v = pv;
  350. qemu_put_8s(f, v);
  351. }
  352. const VMStateInfo vmstate_info_uint8 = {
  353. .name = "uint8",
  354. .get = get_uint8,
  355. .put = put_uint8,
  356. };
  357. /* 16 bit unsigned int */
  358. static int get_uint16(QEMUFile *f, void *pv, size_t size)
  359. {
  360. uint16_t *v = pv;
  361. qemu_get_be16s(f, v);
  362. return 0;
  363. }
  364. static void put_uint16(QEMUFile *f, void *pv, size_t size)
  365. {
  366. uint16_t *v = pv;
  367. qemu_put_be16s(f, v);
  368. }
  369. const VMStateInfo vmstate_info_uint16 = {
  370. .name = "uint16",
  371. .get = get_uint16,
  372. .put = put_uint16,
  373. };
  374. /* 32 bit unsigned int */
  375. static int get_uint32(QEMUFile *f, void *pv, size_t size)
  376. {
  377. uint32_t *v = pv;
  378. qemu_get_be32s(f, v);
  379. return 0;
  380. }
  381. static void put_uint32(QEMUFile *f, void *pv, size_t size)
  382. {
  383. uint32_t *v = pv;
  384. qemu_put_be32s(f, v);
  385. }
  386. const VMStateInfo vmstate_info_uint32 = {
  387. .name = "uint32",
  388. .get = get_uint32,
  389. .put = put_uint32,
  390. };
  391. /* 32 bit uint. See that the received value is the same than the one
  392. in the field */
  393. static int get_uint32_equal(QEMUFile *f, void *pv, size_t size)
  394. {
  395. uint32_t *v = pv;
  396. uint32_t v2;
  397. qemu_get_be32s(f, &v2);
  398. if (*v == v2) {
  399. return 0;
  400. }
  401. return -EINVAL;
  402. }
  403. const VMStateInfo vmstate_info_uint32_equal = {
  404. .name = "uint32 equal",
  405. .get = get_uint32_equal,
  406. .put = put_uint32,
  407. };
  408. /* 64 bit unsigned int */
  409. static int get_uint64(QEMUFile *f, void *pv, size_t size)
  410. {
  411. uint64_t *v = pv;
  412. qemu_get_be64s(f, v);
  413. return 0;
  414. }
  415. static void put_uint64(QEMUFile *f, void *pv, size_t size)
  416. {
  417. uint64_t *v = pv;
  418. qemu_put_be64s(f, v);
  419. }
  420. const VMStateInfo vmstate_info_uint64 = {
  421. .name = "uint64",
  422. .get = get_uint64,
  423. .put = put_uint64,
  424. };
  425. /* 64 bit unsigned int. See that the received value is the same than the one
  426. in the field */
  427. static int get_uint64_equal(QEMUFile *f, void *pv, size_t size)
  428. {
  429. uint64_t *v = pv;
  430. uint64_t v2;
  431. qemu_get_be64s(f, &v2);
  432. if (*v == v2) {
  433. return 0;
  434. }
  435. return -EINVAL;
  436. }
  437. const VMStateInfo vmstate_info_uint64_equal = {
  438. .name = "int64 equal",
  439. .get = get_uint64_equal,
  440. .put = put_uint64,
  441. };
  442. /* 8 bit int. See that the received value is the same than the one
  443. in the field */
  444. static int get_uint8_equal(QEMUFile *f, void *pv, size_t size)
  445. {
  446. uint8_t *v = pv;
  447. uint8_t v2;
  448. qemu_get_8s(f, &v2);
  449. if (*v == v2) {
  450. return 0;
  451. }
  452. return -EINVAL;
  453. }
  454. const VMStateInfo vmstate_info_uint8_equal = {
  455. .name = "uint8 equal",
  456. .get = get_uint8_equal,
  457. .put = put_uint8,
  458. };
  459. /* 16 bit unsigned int int. See that the received value is the same than the one
  460. in the field */
  461. static int get_uint16_equal(QEMUFile *f, void *pv, size_t size)
  462. {
  463. uint16_t *v = pv;
  464. uint16_t v2;
  465. qemu_get_be16s(f, &v2);
  466. if (*v == v2) {
  467. return 0;
  468. }
  469. return -EINVAL;
  470. }
  471. const VMStateInfo vmstate_info_uint16_equal = {
  472. .name = "uint16 equal",
  473. .get = get_uint16_equal,
  474. .put = put_uint16,
  475. };
  476. /* floating point */
  477. static int get_float64(QEMUFile *f, void *pv, size_t size)
  478. {
  479. float64 *v = pv;
  480. *v = make_float64(qemu_get_be64(f));
  481. return 0;
  482. }
  483. static void put_float64(QEMUFile *f, void *pv, size_t size)
  484. {
  485. uint64_t *v = pv;
  486. qemu_put_be64(f, float64_val(*v));
  487. }
  488. const VMStateInfo vmstate_info_float64 = {
  489. .name = "float64",
  490. .get = get_float64,
  491. .put = put_float64,
  492. };
  493. /* uint8_t buffers */
  494. static int get_buffer(QEMUFile *f, void *pv, size_t size)
  495. {
  496. uint8_t *v = pv;
  497. qemu_get_buffer(f, v, size);
  498. return 0;
  499. }
  500. static void put_buffer(QEMUFile *f, void *pv, size_t size)
  501. {
  502. uint8_t *v = pv;
  503. qemu_put_buffer(f, v, size);
  504. }
  505. const VMStateInfo vmstate_info_buffer = {
  506. .name = "buffer",
  507. .get = get_buffer,
  508. .put = put_buffer,
  509. };
  510. /* unused buffers: space that was used for some fields that are
  511. not useful anymore */
  512. static int get_unused_buffer(QEMUFile *f, void *pv, size_t size)
  513. {
  514. uint8_t buf[1024];
  515. int block_len;
  516. while (size > 0) {
  517. block_len = MIN(sizeof(buf), size);
  518. size -= block_len;
  519. qemu_get_buffer(f, buf, block_len);
  520. }
  521. return 0;
  522. }
  523. static void put_unused_buffer(QEMUFile *f, void *pv, size_t size)
  524. {
  525. static const uint8_t buf[1024];
  526. int block_len;
  527. while (size > 0) {
  528. block_len = MIN(sizeof(buf), size);
  529. size -= block_len;
  530. qemu_put_buffer(f, buf, block_len);
  531. }
  532. }
  533. const VMStateInfo vmstate_info_unused_buffer = {
  534. .name = "unused_buffer",
  535. .get = get_unused_buffer,
  536. .put = put_unused_buffer,
  537. };
  538. /* bitmaps (as defined by bitmap.h). Note that size here is the size
  539. * of the bitmap in bits. The on-the-wire format of a bitmap is 64
  540. * bit words with the bits in big endian order. The in-memory format
  541. * is an array of 'unsigned long', which may be either 32 or 64 bits.
  542. */
  543. /* This is the number of 64 bit words sent over the wire */
  544. #define BITS_TO_U64S(nr) DIV_ROUND_UP(nr, 64)
  545. static int get_bitmap(QEMUFile *f, void *pv, size_t size)
  546. {
  547. unsigned long *bmp = pv;
  548. int i, idx = 0;
  549. for (i = 0; i < BITS_TO_U64S(size); i++) {
  550. uint64_t w = qemu_get_be64(f);
  551. bmp[idx++] = w;
  552. if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
  553. bmp[idx++] = w >> 32;
  554. }
  555. }
  556. return 0;
  557. }
  558. static void put_bitmap(QEMUFile *f, void *pv, size_t size)
  559. {
  560. unsigned long *bmp = pv;
  561. int i, idx = 0;
  562. for (i = 0; i < BITS_TO_U64S(size); i++) {
  563. uint64_t w = bmp[idx++];
  564. if (sizeof(unsigned long) == 4 && idx < BITS_TO_LONGS(size)) {
  565. w |= ((uint64_t)bmp[idx++]) << 32;
  566. }
  567. qemu_put_be64(f, w);
  568. }
  569. }
  570. const VMStateInfo vmstate_info_bitmap = {
  571. .name = "bitmap",
  572. .get = get_bitmap,
  573. .put = put_bitmap,
  574. };