vmstate.c 15 KB

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