1d73abd6dSPavel Dovgalyuk /* 25b5968c4SPhilippe Mathieu-Daudé * QEMU replay (system interface) 3d73abd6dSPavel Dovgalyuk * 4d73abd6dSPavel Dovgalyuk * Copyright (c) 2010-2015 Institute for System Programming 5d73abd6dSPavel Dovgalyuk * of the Russian Academy of Sciences. 6d73abd6dSPavel Dovgalyuk * 7d73abd6dSPavel Dovgalyuk * This work is licensed under the terms of the GNU GPL, version 2 or later. 8d73abd6dSPavel Dovgalyuk * See the COPYING file in the top-level directory. 9d73abd6dSPavel Dovgalyuk * 10d73abd6dSPavel Dovgalyuk */ 11*16ad9788SPhilippe Mathieu-Daudé #ifndef SYSEMU_REPLAY_H 12*16ad9788SPhilippe Mathieu-Daudé #define SYSEMU_REPLAY_H 13*16ad9788SPhilippe Mathieu-Daudé 14*16ad9788SPhilippe Mathieu-Daudé #ifdef CONFIG_USER_ONLY 15*16ad9788SPhilippe Mathieu-Daudé #error Cannot include this header from user emulation 16*16ad9788SPhilippe Mathieu-Daudé #endif 17d73abd6dSPavel Dovgalyuk 185b5968c4SPhilippe Mathieu-Daudé #include "exec/replay-core.h" 19112ed241SMarkus Armbruster #include "qapi/qapi-types-misc.h" 20d5938f29SMarkus Armbruster #include "qapi/qapi-types-run-state.h" 21112ed241SMarkus Armbruster #include "qapi/qapi-types-ui.h" 22e4ec5ad4SPavel Dovgalyuk #include "block/aio.h" 23d73abd6dSPavel Dovgalyuk 248eda206eSPavel Dovgalyuk /* replay clock kinds */ 258eda206eSPavel Dovgalyuk enum ReplayClockKind { 268eda206eSPavel Dovgalyuk /* host_clock */ 278eda206eSPavel Dovgalyuk REPLAY_CLOCK_HOST, 288eda206eSPavel Dovgalyuk /* virtual_rt_clock */ 298eda206eSPavel Dovgalyuk REPLAY_CLOCK_VIRTUAL_RT, 308eda206eSPavel Dovgalyuk REPLAY_CLOCK_COUNT 318eda206eSPavel Dovgalyuk }; 328eda206eSPavel Dovgalyuk typedef enum ReplayClockKind ReplayClockKind; 338eda206eSPavel Dovgalyuk 348bd7f71dSPavel Dovgalyuk /* IDs of the checkpoints */ 358bd7f71dSPavel Dovgalyuk enum ReplayCheckpoint { 36e76d1798SPavel Dovgalyuk CHECKPOINT_CLOCK_WARP_START, 37e76d1798SPavel Dovgalyuk CHECKPOINT_CLOCK_WARP_ACCOUNT, 388bd7f71dSPavel Dovgalyuk CHECKPOINT_RESET_REQUESTED, 398bd7f71dSPavel Dovgalyuk CHECKPOINT_SUSPEND_REQUESTED, 408bd7f71dSPavel Dovgalyuk CHECKPOINT_CLOCK_VIRTUAL, 418bd7f71dSPavel Dovgalyuk CHECKPOINT_CLOCK_HOST, 428bd7f71dSPavel Dovgalyuk CHECKPOINT_CLOCK_VIRTUAL_RT, 438bd7f71dSPavel Dovgalyuk CHECKPOINT_INIT, 448bd7f71dSPavel Dovgalyuk CHECKPOINT_RESET, 458bd7f71dSPavel Dovgalyuk CHECKPOINT_COUNT 468bd7f71dSPavel Dovgalyuk }; 478bd7f71dSPavel Dovgalyuk typedef enum ReplayCheckpoint ReplayCheckpoint; 488bd7f71dSPavel Dovgalyuk 49646c5478SPavel Dovgalyuk typedef struct ReplayNetState ReplayNetState; 50646c5478SPavel Dovgalyuk 519c2037d0SPavel Dovgalyuk /* Name of the initial VM snapshot */ 529c2037d0SPavel Dovgalyuk extern char *replay_snapshot; 539c2037d0SPavel Dovgalyuk 54a36544d3SAlex Bennée /* Replay locking 55a36544d3SAlex Bennée * 56a36544d3SAlex Bennée * The locks are needed to protect the shared structures and log file 57a36544d3SAlex Bennée * when doing record/replay. They also are the main sync-point between 58a36544d3SAlex Bennée * the main-loop thread and the vCPU thread. This was a role 59a36544d3SAlex Bennée * previously filled by the BQL which has been busy trying to reduce 60a36544d3SAlex Bennée * its impact across the code. This ensures blocks of events stay 61a36544d3SAlex Bennée * sequential and reproducible. 62a36544d3SAlex Bennée */ 63a36544d3SAlex Bennée 64a36544d3SAlex Bennée void replay_mutex_lock(void); 65a36544d3SAlex Bennée void replay_mutex_unlock(void); 66a36544d3SAlex Bennée 6726bc60acSPavel Dovgalyuk /* Processing the instructions */ 6826bc60acSPavel Dovgalyuk 6926bc60acSPavel Dovgalyuk /*! Returns number of executed instructions. */ 7013f26713SPavel Dovgalyuk uint64_t replay_get_current_icount(void); 718b427044SPavel Dovgalyuk /*! Returns number of instructions to execute in replay mode. */ 728b427044SPavel Dovgalyuk int replay_get_instructions(void); 738b427044SPavel Dovgalyuk /*! Updates instructions counter in replay mode. */ 748b427044SPavel Dovgalyuk void replay_account_executed_instructions(void); 7526bc60acSPavel Dovgalyuk 768eda206eSPavel Dovgalyuk /* Processing clocks and other time sources */ 778eda206eSPavel Dovgalyuk 788eda206eSPavel Dovgalyuk /*! Save the specified clock */ 7974c0b816SPaolo Bonzini int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, 8074c0b816SPaolo Bonzini int64_t raw_icount); 818eda206eSPavel Dovgalyuk /*! Read the specified clock from the log or return cached data */ 82366a85e4SPavel Dovgalyuk int64_t replay_read_clock(ReplayClockKind kind, int64_t raw_icount); 838eda206eSPavel Dovgalyuk /*! Saves or reads the clock depending on the current replay mode. */ 848eda206eSPavel Dovgalyuk #define REPLAY_CLOCK(clock, value) \ 85*16ad9788SPhilippe Mathieu-Daudé !icount_enabled() ? (value) : \ 86366a85e4SPavel Dovgalyuk (replay_mode == REPLAY_MODE_PLAY \ 87366a85e4SPavel Dovgalyuk ? replay_read_clock((clock), icount_get_raw()) \ 888eda206eSPavel Dovgalyuk : replay_mode == REPLAY_MODE_RECORD \ 898191d368SClaudio Fontana ? replay_save_clock((clock), (value), icount_get_raw()) \ 9074c0b816SPaolo Bonzini : (value)) 9174c0b816SPaolo Bonzini #define REPLAY_CLOCK_LOCKED(clock, value) \ 92*16ad9788SPhilippe Mathieu-Daudé !icount_enabled() ? (value) : \ 93366a85e4SPavel Dovgalyuk (replay_mode == REPLAY_MODE_PLAY \ 94366a85e4SPavel Dovgalyuk ? replay_read_clock((clock), icount_get_raw_locked()) \ 9574c0b816SPaolo Bonzini : replay_mode == REPLAY_MODE_RECORD \ 968191d368SClaudio Fontana ? replay_save_clock((clock), (value), icount_get_raw_locked()) \ 978eda206eSPavel Dovgalyuk : (value)) 988eda206eSPavel Dovgalyuk 99b60c48a7SPavel Dovgalyuk /* Events */ 100b60c48a7SPavel Dovgalyuk 101b60c48a7SPavel Dovgalyuk /*! Called when qemu shutdown is requested. */ 102802f045aSEric Blake void replay_shutdown_request(ShutdownCause cause); 1038bd7f71dSPavel Dovgalyuk /*! Should be called at check points in the execution. 1048bd7f71dSPavel Dovgalyuk These check points are skipped, if they were not met. 1058bd7f71dSPavel Dovgalyuk Saves checkpoint in the SAVE mode and validates in the PLAY mode. 1068bd7f71dSPavel Dovgalyuk Returns 0 in PLAY mode if checkpoint was not found. 1078bd7f71dSPavel Dovgalyuk Returns 1 in all other cases. */ 1088bd7f71dSPavel Dovgalyuk bool replay_checkpoint(ReplayCheckpoint checkpoint); 10960618e2dSPavel Dovgalyuk /*! Used to determine that checkpoint or async event is pending. 1100c08185fSPavel Dovgalyuk Does not proceed to the next event in the log. */ 11160618e2dSPavel Dovgalyuk bool replay_has_event(void); 11260618e2dSPavel Dovgalyuk /* 11360618e2dSPavel Dovgalyuk * Processes the async events added to the queue (while recording) 11460618e2dSPavel Dovgalyuk * or reads the events from the file (while replaying). 11560618e2dSPavel Dovgalyuk */ 11660618e2dSPavel Dovgalyuk void replay_async_events(void); 117b60c48a7SPavel Dovgalyuk 118c0c071d0SPavel Dovgalyuk /* Asynchronous events queue */ 119c0c071d0SPavel Dovgalyuk 1206d0ceb80SPavel Dovgalyuk /*! Enables storing events in the queue */ 1216d0ceb80SPavel Dovgalyuk void replay_enable_events(void); 122c0c071d0SPavel Dovgalyuk /*! Returns true when saving events is enabled */ 123c0c071d0SPavel Dovgalyuk bool replay_events_enabled(void); 124f9a9fb65SPavel Dovgalyuk /* Flushes events queue */ 125f9a9fb65SPavel Dovgalyuk void replay_flush_events(void); 1268a354bd9SPavel Dovgalyuk /*! Adds bottom half event to the queue */ 1278a354bd9SPavel Dovgalyuk void replay_bh_schedule_event(QEMUBH *bh); 128e4ec5ad4SPavel Dovgalyuk /* Adds oneshot bottom half event to the queue */ 129e4ec5ad4SPavel Dovgalyuk void replay_bh_schedule_oneshot_event(AioContext *ctx, 130e4ec5ad4SPavel Dovgalyuk QEMUBHFunc *cb, void *opaque); 131ee312992SPavel Dovgalyuk /*! Adds input event to the queue */ 132ee312992SPavel Dovgalyuk void replay_input_event(QemuConsole *src, InputEvent *evt); 133ee312992SPavel Dovgalyuk /*! Adds input sync event to the queue */ 134ee312992SPavel Dovgalyuk void replay_input_sync_event(void); 13563785678SPavel Dovgalyuk /*! Adds block layer event to the queue */ 13663785678SPavel Dovgalyuk void replay_block_event(QEMUBH *bh, uint64_t id); 1376d0ceb80SPavel Dovgalyuk /*! Returns ID for the next block event */ 1386d0ceb80SPavel Dovgalyuk uint64_t blkreplay_next_id(void); 1396f060969SPavel Dovgalyuk 14033577b47SPavel Dovgalyuk /* Character device */ 14133577b47SPavel Dovgalyuk 14233577b47SPavel Dovgalyuk /*! Registers char driver to save it's events */ 1430ec7b3e7SMarc-André Lureau void replay_register_char_driver(struct Chardev *chr); 14433577b47SPavel Dovgalyuk /*! Saves write to char device event to the log */ 1458f9abdf5SArwed Meyer void replay_chr_be_write(struct Chardev *s, const uint8_t *buf, int len); 14633577b47SPavel Dovgalyuk /*! Writes char write return value to the replay log. */ 14733577b47SPavel Dovgalyuk void replay_char_write_event_save(int res, int offset); 14833577b47SPavel Dovgalyuk /*! Reads char write return value from the replay log. */ 14933577b47SPavel Dovgalyuk void replay_char_write_event_load(int *res, int *offset); 15033577b47SPavel Dovgalyuk /*! Reads information about read_all character event. */ 15133577b47SPavel Dovgalyuk int replay_char_read_all_load(uint8_t *buf); 15233577b47SPavel Dovgalyuk /*! Writes character read_all error code into the replay log. */ 15333577b47SPavel Dovgalyuk void replay_char_read_all_save_error(int res); 15433577b47SPavel Dovgalyuk /*! Writes character read_all execution result into the replay log. */ 15533577b47SPavel Dovgalyuk void replay_char_read_all_save_buf(uint8_t *buf, int offset); 15633577b47SPavel Dovgalyuk 157646c5478SPavel Dovgalyuk /* Network */ 158646c5478SPavel Dovgalyuk 159646c5478SPavel Dovgalyuk /*! Registers replay network filter attached to some backend. */ 160646c5478SPavel Dovgalyuk ReplayNetState *replay_register_net(NetFilterState *nfs); 161646c5478SPavel Dovgalyuk /*! Unregisters replay network filter. */ 162646c5478SPavel Dovgalyuk void replay_unregister_net(ReplayNetState *rns); 163646c5478SPavel Dovgalyuk /*! Called to write network packet to the replay log. */ 164646c5478SPavel Dovgalyuk void replay_net_packet_event(ReplayNetState *rns, unsigned flags, 165646c5478SPavel Dovgalyuk const struct iovec *iov, int iovcnt); 166646c5478SPavel Dovgalyuk 1673d4d16f4SPavel Dovgalyuk /* Audio */ 1683d4d16f4SPavel Dovgalyuk 1693d4d16f4SPavel Dovgalyuk /*! Saves/restores number of played samples of audio out operation. */ 1707520462bSKővágó, Zoltán void replay_audio_out(size_t *played); 1713d4d16f4SPavel Dovgalyuk /*! Saves/restores recorded samples of audio in operation. */ 1727520462bSKővágó, Zoltán void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size); 1733d4d16f4SPavel Dovgalyuk 1749c2037d0SPavel Dovgalyuk /* VM state operations */ 1759c2037d0SPavel Dovgalyuk 1769c2037d0SPavel Dovgalyuk /*! Called at the start of execution. 1779c2037d0SPavel Dovgalyuk Loads or saves initial vmstate depending on execution mode. */ 1789c2037d0SPavel Dovgalyuk void replay_vmstate_init(void); 179377b21ccSPavel Dovgalyuk /*! Called to ensure that replay state is consistent and VM snapshot 180377b21ccSPavel Dovgalyuk can be created */ 181377b21ccSPavel Dovgalyuk bool replay_can_snapshot(void); 1829c2037d0SPavel Dovgalyuk 183d73abd6dSPavel Dovgalyuk #endif 184