replay-internal.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  1. /*
  2. * replay-internal.c
  3. *
  4. * Copyright (c) 2010-2015 Institute for System Programming
  5. * of the Russian Academy of Sciences.
  6. *
  7. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  8. * See the COPYING file in the top-level directory.
  9. *
  10. */
  11. #include "qemu/osdep.h"
  12. #include "sysemu/replay.h"
  13. #include "sysemu/runstate.h"
  14. #include "replay-internal.h"
  15. #include "qemu/error-report.h"
  16. #include "qemu/main-loop.h"
  17. /* Mutex to protect reading and writing events to the log.
  18. data_kind and has_unread_data are also protected
  19. by this mutex.
  20. It also protects replay events queue which stores events to be
  21. written or read to the log. */
  22. static QemuMutex lock;
  23. /* Condition and queue for fair ordering of mutex lock requests. */
  24. static QemuCond mutex_cond;
  25. static unsigned long mutex_head, mutex_tail;
  26. /* File for replay writing */
  27. static bool write_error;
  28. FILE *replay_file;
  29. static void replay_write_error(void)
  30. {
  31. if (!write_error) {
  32. error_report("replay write error");
  33. write_error = true;
  34. }
  35. }
  36. static void replay_read_error(void)
  37. {
  38. error_report("error reading the replay data");
  39. exit(1);
  40. }
  41. void replay_put_byte(uint8_t byte)
  42. {
  43. if (replay_file) {
  44. if (putc(byte, replay_file) == EOF) {
  45. replay_write_error();
  46. }
  47. }
  48. }
  49. void replay_put_event(uint8_t event)
  50. {
  51. assert(event < EVENT_COUNT);
  52. replay_put_byte(event);
  53. }
  54. void replay_put_word(uint16_t word)
  55. {
  56. replay_put_byte(word >> 8);
  57. replay_put_byte(word);
  58. }
  59. void replay_put_dword(uint32_t dword)
  60. {
  61. replay_put_word(dword >> 16);
  62. replay_put_word(dword);
  63. }
  64. void replay_put_qword(int64_t qword)
  65. {
  66. replay_put_dword(qword >> 32);
  67. replay_put_dword(qword);
  68. }
  69. void replay_put_array(const uint8_t *buf, size_t size)
  70. {
  71. if (replay_file) {
  72. replay_put_dword(size);
  73. if (fwrite(buf, 1, size, replay_file) != size) {
  74. replay_write_error();
  75. }
  76. }
  77. }
  78. uint8_t replay_get_byte(void)
  79. {
  80. uint8_t byte = 0;
  81. if (replay_file) {
  82. int r = getc(replay_file);
  83. if (r == EOF) {
  84. replay_read_error();
  85. }
  86. byte = r;
  87. }
  88. return byte;
  89. }
  90. uint16_t replay_get_word(void)
  91. {
  92. uint16_t word = 0;
  93. if (replay_file) {
  94. word = replay_get_byte();
  95. word = (word << 8) + replay_get_byte();
  96. }
  97. return word;
  98. }
  99. uint32_t replay_get_dword(void)
  100. {
  101. uint32_t dword = 0;
  102. if (replay_file) {
  103. dword = replay_get_word();
  104. dword = (dword << 16) + replay_get_word();
  105. }
  106. return dword;
  107. }
  108. int64_t replay_get_qword(void)
  109. {
  110. int64_t qword = 0;
  111. if (replay_file) {
  112. qword = replay_get_dword();
  113. qword = (qword << 32) + replay_get_dword();
  114. }
  115. return qword;
  116. }
  117. void replay_get_array(uint8_t *buf, size_t *size)
  118. {
  119. if (replay_file) {
  120. *size = replay_get_dword();
  121. if (fread(buf, 1, *size, replay_file) != *size) {
  122. replay_read_error();
  123. }
  124. }
  125. }
  126. void replay_get_array_alloc(uint8_t **buf, size_t *size)
  127. {
  128. if (replay_file) {
  129. *size = replay_get_dword();
  130. *buf = g_malloc(*size);
  131. if (fread(*buf, 1, *size, replay_file) != *size) {
  132. replay_read_error();
  133. }
  134. }
  135. }
  136. void replay_check_error(void)
  137. {
  138. if (replay_file) {
  139. if (feof(replay_file)) {
  140. error_report("replay file is over");
  141. qemu_system_vmstop_request_prepare();
  142. qemu_system_vmstop_request(RUN_STATE_PAUSED);
  143. } else if (ferror(replay_file)) {
  144. error_report("replay file is over or something goes wrong");
  145. qemu_system_vmstop_request_prepare();
  146. qemu_system_vmstop_request(RUN_STATE_INTERNAL_ERROR);
  147. }
  148. }
  149. }
  150. void replay_fetch_data_kind(void)
  151. {
  152. if (replay_file) {
  153. if (!replay_state.has_unread_data) {
  154. replay_state.data_kind = replay_get_byte();
  155. if (replay_state.data_kind == EVENT_INSTRUCTION) {
  156. replay_state.instruction_count = replay_get_dword();
  157. }
  158. replay_check_error();
  159. replay_state.has_unread_data = 1;
  160. if (replay_state.data_kind >= EVENT_COUNT) {
  161. error_report("Replay: unknown event kind %d",
  162. replay_state.data_kind);
  163. exit(1);
  164. }
  165. }
  166. }
  167. }
  168. void replay_finish_event(void)
  169. {
  170. replay_state.has_unread_data = 0;
  171. replay_fetch_data_kind();
  172. }
  173. static __thread bool replay_locked;
  174. void replay_mutex_init(void)
  175. {
  176. qemu_mutex_init(&lock);
  177. qemu_cond_init(&mutex_cond);
  178. /* Hold the mutex while we start-up */
  179. replay_locked = true;
  180. ++mutex_tail;
  181. }
  182. bool replay_mutex_locked(void)
  183. {
  184. return replay_locked;
  185. }
  186. /* Ordering constraints, replay_lock must be taken before BQL */
  187. void replay_mutex_lock(void)
  188. {
  189. if (replay_mode != REPLAY_MODE_NONE) {
  190. unsigned long id;
  191. g_assert(!qemu_mutex_iothread_locked());
  192. g_assert(!replay_mutex_locked());
  193. qemu_mutex_lock(&lock);
  194. id = mutex_tail++;
  195. while (id != mutex_head) {
  196. qemu_cond_wait(&mutex_cond, &lock);
  197. }
  198. replay_locked = true;
  199. qemu_mutex_unlock(&lock);
  200. }
  201. }
  202. void replay_mutex_unlock(void)
  203. {
  204. if (replay_mode != REPLAY_MODE_NONE) {
  205. g_assert(replay_mutex_locked());
  206. qemu_mutex_lock(&lock);
  207. ++mutex_head;
  208. replay_locked = false;
  209. qemu_cond_broadcast(&mutex_cond);
  210. qemu_mutex_unlock(&lock);
  211. }
  212. }
  213. void replay_advance_current_icount(uint64_t current_icount)
  214. {
  215. int diff = (int)(current_icount - replay_state.current_icount);
  216. /* Time can only go forward */
  217. assert(diff >= 0);
  218. if (replay_mode == REPLAY_MODE_RECORD) {
  219. if (diff > 0) {
  220. replay_put_event(EVENT_INSTRUCTION);
  221. replay_put_dword(diff);
  222. replay_state.current_icount += diff;
  223. }
  224. } else if (replay_mode == REPLAY_MODE_PLAY) {
  225. if (diff > 0) {
  226. replay_state.instruction_count -= diff;
  227. replay_state.current_icount += diff;
  228. if (replay_state.instruction_count == 0) {
  229. assert(replay_state.data_kind == EVENT_INSTRUCTION);
  230. replay_finish_event();
  231. /* Wake up iothread. This is required because
  232. timers will not expire until clock counters
  233. will be read from the log. */
  234. qemu_notify_event();
  235. }
  236. }
  237. /* Execution reached the break step */
  238. if (replay_break_icount == replay_state.current_icount) {
  239. /* Cannot make callback directly from the vCPU thread */
  240. timer_mod_ns(replay_break_timer,
  241. qemu_clock_get_ns(QEMU_CLOCK_REALTIME));
  242. }
  243. }
  244. }
  245. /*! Saves cached instructions. */
  246. void replay_save_instructions(void)
  247. {
  248. if (replay_file && replay_mode == REPLAY_MODE_RECORD) {
  249. g_assert(replay_mutex_locked());
  250. replay_advance_current_icount(replay_get_current_icount());
  251. }
  252. }