33577b47c6
This patch implements record and replay of character devices. It records chardevs communication in replay mode. Recorded information include data read from backend and counter of bytes written from frontend to backend to preserve frontend internal state. If character device was configured through the command line in record mode, then in replay mode it should be also added to command line. Backend of the character device could be changed in replay mode. Replaying of devices that perform ioctl and get_msgfd operations is not supported. gdbstub which also acts as a backend is not recorded to allow controlling the replaying through gdb. Monitor backends are also not recorded. Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> Message-Id: <20160314074436.4980.83856.stgit@PASHA-ISP> [Add stubs. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
158 lines
4.8 KiB
C
158 lines
4.8 KiB
C
#ifndef REPLAY_INTERNAL_H
|
|
#define REPLAY_INTERNAL_H
|
|
|
|
/*
|
|
* replay-internal.h
|
|
*
|
|
* Copyright (c) 2010-2015 Institute for System Programming
|
|
* of the Russian Academy of Sciences.
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
|
|
enum ReplayEvents {
|
|
/* for instruction event */
|
|
EVENT_INSTRUCTION,
|
|
/* for software interrupt */
|
|
EVENT_INTERRUPT,
|
|
/* for emulated exceptions */
|
|
EVENT_EXCEPTION,
|
|
/* for async events */
|
|
EVENT_ASYNC,
|
|
/* for shutdown request */
|
|
EVENT_SHUTDOWN,
|
|
/* for character device write event */
|
|
EVENT_CHAR_WRITE,
|
|
/* for character device read all event */
|
|
EVENT_CHAR_READ_ALL,
|
|
EVENT_CHAR_READ_ALL_ERROR,
|
|
/* for clock read/writes */
|
|
/* some of greater codes are reserved for clocks */
|
|
EVENT_CLOCK,
|
|
EVENT_CLOCK_LAST = EVENT_CLOCK + REPLAY_CLOCK_COUNT - 1,
|
|
/* for checkpoint event */
|
|
/* some of greater codes are reserved for checkpoints */
|
|
EVENT_CHECKPOINT,
|
|
EVENT_CHECKPOINT_LAST = EVENT_CHECKPOINT + CHECKPOINT_COUNT - 1,
|
|
/* end of log event */
|
|
EVENT_END,
|
|
EVENT_COUNT
|
|
};
|
|
|
|
/* Asynchronous events IDs */
|
|
|
|
enum ReplayAsyncEventKind {
|
|
REPLAY_ASYNC_EVENT_BH,
|
|
REPLAY_ASYNC_EVENT_INPUT,
|
|
REPLAY_ASYNC_EVENT_INPUT_SYNC,
|
|
REPLAY_ASYNC_EVENT_CHAR_READ,
|
|
REPLAY_ASYNC_COUNT
|
|
};
|
|
|
|
typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;
|
|
|
|
typedef struct ReplayState {
|
|
/*! Cached clock values. */
|
|
int64_t cached_clock[REPLAY_CLOCK_COUNT];
|
|
/*! Current step - number of processed instructions and timer events. */
|
|
uint64_t current_step;
|
|
/*! Number of instructions to be executed before other events happen. */
|
|
int instructions_count;
|
|
} ReplayState;
|
|
extern ReplayState replay_state;
|
|
|
|
extern unsigned int replay_data_kind;
|
|
|
|
/* File for replay writing */
|
|
extern FILE *replay_file;
|
|
|
|
void replay_put_byte(uint8_t byte);
|
|
void replay_put_event(uint8_t event);
|
|
void replay_put_word(uint16_t word);
|
|
void replay_put_dword(uint32_t dword);
|
|
void replay_put_qword(int64_t qword);
|
|
void replay_put_array(const uint8_t *buf, size_t size);
|
|
|
|
uint8_t replay_get_byte(void);
|
|
uint16_t replay_get_word(void);
|
|
uint32_t replay_get_dword(void);
|
|
int64_t replay_get_qword(void);
|
|
void replay_get_array(uint8_t *buf, size_t *size);
|
|
void replay_get_array_alloc(uint8_t **buf, size_t *size);
|
|
|
|
/* Mutex functions for protecting replay log file */
|
|
|
|
void replay_mutex_init(void);
|
|
void replay_mutex_destroy(void);
|
|
void replay_mutex_lock(void);
|
|
void replay_mutex_unlock(void);
|
|
|
|
/*! Checks error status of the file. */
|
|
void replay_check_error(void);
|
|
|
|
/*! Finishes processing of the replayed event and fetches
|
|
the next event from the log. */
|
|
void replay_finish_event(void);
|
|
/*! Reads data type from the file and stores it in the
|
|
replay_data_kind variable. */
|
|
void replay_fetch_data_kind(void);
|
|
|
|
/*! Saves queued events (like instructions and sound). */
|
|
void replay_save_instructions(void);
|
|
|
|
/*! Skips async events until some sync event will be found.
|
|
\return true, if event was found */
|
|
bool replay_next_event_is(int event);
|
|
|
|
/*! Reads next clock value from the file.
|
|
If clock kind read from the file is different from the parameter,
|
|
the value is not used. */
|
|
void replay_read_next_clock(unsigned int kind);
|
|
|
|
/* Asynchronous events queue */
|
|
|
|
/*! Initializes events' processing internals */
|
|
void replay_init_events(void);
|
|
/*! Clears internal data structures for events handling */
|
|
void replay_finish_events(void);
|
|
/*! Enables storing events in the queue */
|
|
void replay_enable_events(void);
|
|
/*! Flushes events queue */
|
|
void replay_flush_events(void);
|
|
/*! Clears events list before loading new VM state */
|
|
void replay_clear_events(void);
|
|
/*! Returns true if there are any unsaved events in the queue */
|
|
bool replay_has_events(void);
|
|
/*! Saves events from queue into the file */
|
|
void replay_save_events(int checkpoint);
|
|
/*! Read events from the file into the input queue */
|
|
void replay_read_events(int checkpoint);
|
|
/*! Adds specified async event to the queue */
|
|
void replay_add_event(ReplayAsyncEventKind event_kind, void *opaque,
|
|
void *opaque2, uint64_t id);
|
|
|
|
/* Input events */
|
|
|
|
/*! Saves input event to the log */
|
|
void replay_save_input_event(InputEvent *evt);
|
|
/*! Reads input event from the log */
|
|
InputEvent *replay_read_input_event(void);
|
|
/*! Adds input event to the queue */
|
|
void replay_add_input_event(struct InputEvent *event);
|
|
/*! Adds input sync event to the queue */
|
|
void replay_add_input_sync_event(void);
|
|
|
|
/* Character devices */
|
|
|
|
/*! Called to run char device read event. */
|
|
void replay_event_char_read_run(void *opaque);
|
|
/*! Writes char read event to the file. */
|
|
void replay_event_char_read_save(void *opaque);
|
|
/*! Reads char event read from the file. */
|
|
void *replay_event_char_read_load(void);
|
|
|
|
#endif
|