xref: /openbmc/qemu/include/sysemu/replay.h (revision a3fb4e93a3a7cf2be355c41cd550bef856f5ffe4)
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