1 | #ifndef REPLAY_H |
2 | #define REPLAY_H |
3 | |
4 | /* |
5 | * replay.h |
6 | * |
7 | * Copyright (c) 2010-2015 Institute for System Programming |
8 | * of the Russian Academy of Sciences. |
9 | * |
10 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
11 | * See the COPYING file in the top-level directory. |
12 | * |
13 | */ |
14 | |
15 | #include "qapi/qapi-types-misc.h" |
16 | #include "qapi/qapi-types-run-state.h" |
17 | #include "qapi/qapi-types-ui.h" |
18 | |
19 | /* replay clock kinds */ |
20 | enum ReplayClockKind { |
21 | /* host_clock */ |
22 | REPLAY_CLOCK_HOST, |
23 | /* virtual_rt_clock */ |
24 | REPLAY_CLOCK_VIRTUAL_RT, |
25 | REPLAY_CLOCK_COUNT |
26 | }; |
27 | typedef enum ReplayClockKind ReplayClockKind; |
28 | |
29 | /* IDs of the checkpoints */ |
30 | enum ReplayCheckpoint { |
31 | CHECKPOINT_CLOCK_WARP_START, |
32 | CHECKPOINT_CLOCK_WARP_ACCOUNT, |
33 | CHECKPOINT_RESET_REQUESTED, |
34 | CHECKPOINT_SUSPEND_REQUESTED, |
35 | CHECKPOINT_CLOCK_VIRTUAL, |
36 | CHECKPOINT_CLOCK_HOST, |
37 | CHECKPOINT_CLOCK_VIRTUAL_RT, |
38 | CHECKPOINT_INIT, |
39 | CHECKPOINT_RESET, |
40 | CHECKPOINT_COUNT |
41 | }; |
42 | typedef enum ReplayCheckpoint ReplayCheckpoint; |
43 | |
44 | typedef struct ReplayNetState ReplayNetState; |
45 | |
46 | extern ReplayMode replay_mode; |
47 | |
48 | /* Name of the initial VM snapshot */ |
49 | extern char *replay_snapshot; |
50 | |
51 | /* Replay locking |
52 | * |
53 | * The locks are needed to protect the shared structures and log file |
54 | * when doing record/replay. They also are the main sync-point between |
55 | * the main-loop thread and the vCPU thread. This was a role |
56 | * previously filled by the BQL which has been busy trying to reduce |
57 | * its impact across the code. This ensures blocks of events stay |
58 | * sequential and reproducible. |
59 | */ |
60 | |
61 | void replay_mutex_lock(void); |
62 | void replay_mutex_unlock(void); |
63 | |
64 | /* Replay process control functions */ |
65 | |
66 | /*! Enables recording or saving event log with specified parameters */ |
67 | void replay_configure(struct QemuOpts *opts); |
68 | /*! Initializes timers used for snapshotting and enables events recording */ |
69 | void replay_start(void); |
70 | /*! Closes replay log file and frees other resources. */ |
71 | void replay_finish(void); |
72 | /*! Adds replay blocker with the specified error description */ |
73 | void replay_add_blocker(Error *reason); |
74 | |
75 | /* Processing the instructions */ |
76 | |
77 | /*! Returns number of executed instructions. */ |
78 | uint64_t replay_get_current_icount(void); |
79 | /*! Returns number of instructions to execute in replay mode. */ |
80 | int replay_get_instructions(void); |
81 | /*! Updates instructions counter in replay mode. */ |
82 | void replay_account_executed_instructions(void); |
83 | |
84 | /* Interrupts and exceptions */ |
85 | |
86 | /*! Called by exception handler to write or read |
87 | exception processing events. */ |
88 | bool replay_exception(void); |
89 | /*! Used to determine that exception is pending. |
90 | Does not proceed to the next event in the log. */ |
91 | bool replay_has_exception(void); |
92 | /*! Called by interrupt handlers to write or read |
93 | interrupt processing events. |
94 | \return true if interrupt should be processed */ |
95 | bool replay_interrupt(void); |
96 | /*! Tries to read interrupt event from the file. |
97 | Returns true, when interrupt request is pending */ |
98 | bool replay_has_interrupt(void); |
99 | |
100 | /* Processing clocks and other time sources */ |
101 | |
102 | /*! Save the specified clock */ |
103 | int64_t replay_save_clock(ReplayClockKind kind, int64_t clock, |
104 | int64_t raw_icount); |
105 | /*! Read the specified clock from the log or return cached data */ |
106 | int64_t replay_read_clock(ReplayClockKind kind); |
107 | /*! Saves or reads the clock depending on the current replay mode. */ |
108 | #define REPLAY_CLOCK(clock, value) \ |
109 | (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock)) \ |
110 | : replay_mode == REPLAY_MODE_RECORD \ |
111 | ? replay_save_clock((clock), (value), cpu_get_icount_raw()) \ |
112 | : (value)) |
113 | #define REPLAY_CLOCK_LOCKED(clock, value) \ |
114 | (replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock)) \ |
115 | : replay_mode == REPLAY_MODE_RECORD \ |
116 | ? replay_save_clock((clock), (value), cpu_get_icount_raw_locked()) \ |
117 | : (value)) |
118 | |
119 | /* Events */ |
120 | |
121 | /*! Called when qemu shutdown is requested. */ |
122 | void replay_shutdown_request(ShutdownCause cause); |
123 | /*! Should be called at check points in the execution. |
124 | These check points are skipped, if they were not met. |
125 | Saves checkpoint in the SAVE mode and validates in the PLAY mode. |
126 | Returns 0 in PLAY mode if checkpoint was not found. |
127 | Returns 1 in all other cases. */ |
128 | bool replay_checkpoint(ReplayCheckpoint checkpoint); |
129 | /*! Used to determine that checkpoint is pending. |
130 | Does not proceed to the next event in the log. */ |
131 | bool replay_has_checkpoint(void); |
132 | |
133 | /* Asynchronous events queue */ |
134 | |
135 | /*! Disables storing events in the queue */ |
136 | void replay_disable_events(void); |
137 | /*! Enables storing events in the queue */ |
138 | void replay_enable_events(void); |
139 | /*! Returns true when saving events is enabled */ |
140 | bool replay_events_enabled(void); |
141 | /*! Adds bottom half event to the queue */ |
142 | void replay_bh_schedule_event(QEMUBH *bh); |
143 | /*! Adds input event to the queue */ |
144 | void replay_input_event(QemuConsole *src, InputEvent *evt); |
145 | /*! Adds input sync event to the queue */ |
146 | void replay_input_sync_event(void); |
147 | /*! Adds block layer event to the queue */ |
148 | void replay_block_event(QEMUBH *bh, uint64_t id); |
149 | /*! Returns ID for the next block event */ |
150 | uint64_t blkreplay_next_id(void); |
151 | |
152 | /* Character device */ |
153 | |
154 | /*! Registers char driver to save it's events */ |
155 | void replay_register_char_driver(struct Chardev *chr); |
156 | /*! Saves write to char device event to the log */ |
157 | void replay_chr_be_write(struct Chardev *s, uint8_t *buf, int len); |
158 | /*! Writes char write return value to the replay log. */ |
159 | void replay_char_write_event_save(int res, int offset); |
160 | /*! Reads char write return value from the replay log. */ |
161 | void replay_char_write_event_load(int *res, int *offset); |
162 | /*! Reads information about read_all character event. */ |
163 | int replay_char_read_all_load(uint8_t *buf); |
164 | /*! Writes character read_all error code into the replay log. */ |
165 | void replay_char_read_all_save_error(int res); |
166 | /*! Writes character read_all execution result into the replay log. */ |
167 | void replay_char_read_all_save_buf(uint8_t *buf, int offset); |
168 | |
169 | /* Network */ |
170 | |
171 | /*! Registers replay network filter attached to some backend. */ |
172 | ReplayNetState *replay_register_net(NetFilterState *nfs); |
173 | /*! Unregisters replay network filter. */ |
174 | void replay_unregister_net(ReplayNetState *rns); |
175 | /*! Called to write network packet to the replay log. */ |
176 | void replay_net_packet_event(ReplayNetState *rns, unsigned flags, |
177 | const struct iovec *iov, int iovcnt); |
178 | |
179 | /* Audio */ |
180 | |
181 | /*! Saves/restores number of played samples of audio out operation. */ |
182 | void replay_audio_out(size_t *played); |
183 | /*! Saves/restores recorded samples of audio in operation. */ |
184 | void replay_audio_in(size_t *recorded, void *samples, size_t *wpos, size_t size); |
185 | |
186 | /* VM state operations */ |
187 | |
188 | /*! Called at the start of execution. |
189 | Loads or saves initial vmstate depending on execution mode. */ |
190 | void replay_vmstate_init(void); |
191 | /*! Called to ensure that replay state is consistent and VM snapshot |
192 | can be created */ |
193 | bool replay_can_snapshot(void); |
194 | |
195 | #endif |
196 | |