2
0

vmstate.c 16 KB

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