So here it is, let's see what happens.
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQEcBAABCAAGBQJWPHM6AAoJEL/70l94x66DK5YIAJTNthYWL8eNhQ1iek6CLlV+ etVXm3JDmkV0zOfYVHLBb44VLZ6I1ocas+57F/kmz7SKpMLiI6bMXRxhTSkiO4D+ 3N36cWQf3fq+P0DmxuikMlYGz8V6QQ5PQE2xJKV0ZIWAkiqInxilkN3qt81sNR+A A9Ohom3sc0eGHyYJcVDK4krbnNSAZjIB2yMWperw61x+GYAhxjA02HPUgB32KK6q KrdnKmnRu9Cw6y4wTCbbDITJztPexZYsX2DOJh30wC0eNcE+MZ7J2im8Frpxe+Ml C8MUuvSqLOyeu9tUfrXGzd6kMtEKrmU+fh2nNbxJbtfowDjkW2jcIEgC0UjkGE4= =BF1q -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream-replay' into staging So here it is, let's see what happens. # gpg: Signature made Fri 06 Nov 2015 09:30:34 GMT using RSA key ID 78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" * remotes/bonzini/tags/for-upstream-replay: replay: recording of the user input replay: command line options replay: replay blockers for devices replay: initialization and deinitialization replay: ptimer bottom halves: introduce bh call function replay: checkpoints icount: improve counting for record/replay replay: shutdown event replay: recording and replaying clock ticks replay: asynchronous events infrastructure replay: interrupts and exceptions cpu: replay instructions sequence cpu-exec: allow temporary disabling icount replay: introduce icount event replay: introduce mutex to protect the replay log replay: internal functions for replay log replay: global variables and function stubs Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
9319738080
30 changed files with 1803 additions and 58 deletions
|
|
@ -208,6 +208,11 @@ void aio_notify(AioContext *ctx);
|
|||
*/
|
||||
void aio_notify_accept(AioContext *ctx);
|
||||
|
||||
/**
|
||||
* aio_bh_call: Executes callback function of the specified BH.
|
||||
*/
|
||||
void aio_bh_call(QEMUBH *bh);
|
||||
|
||||
/**
|
||||
* aio_bh_poll: Poll bottom halves for an AioContext.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -190,6 +190,7 @@ struct TranslationBlock {
|
|||
#define CF_LAST_IO 0x8000 /* Last insn may be an IO access. */
|
||||
#define CF_NOCACHE 0x10000 /* To be freed after execution */
|
||||
#define CF_USE_ICOUNT 0x20000
|
||||
#define CF_IGNORE_ICOUNT 0x40000 /* Do not generate icount code */
|
||||
|
||||
void *tc_ptr; /* pointer to the translated code */
|
||||
uint8_t *tc_search; /* pointer to search data */
|
||||
|
|
|
|||
|
|
@ -106,4 +106,7 @@
|
|||
#define QERR_UNSUPPORTED \
|
||||
"this feature or command is not currently supported"
|
||||
|
||||
#define QERR_REPLAY_NOT_SUPPORTED \
|
||||
"Record/replay feature is not supported for '%s'"
|
||||
|
||||
#endif /* QERROR_H */
|
||||
|
|
|
|||
120
include/sysemu/replay.h
Normal file
120
include/sysemu/replay.h
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
#ifndef REPLAY_H
|
||||
#define REPLAY_H
|
||||
|
||||
/*
|
||||
* replay.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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "qapi-types.h"
|
||||
#include "qapi/error.h"
|
||||
#include "qemu/typedefs.h"
|
||||
|
||||
/* replay clock kinds */
|
||||
enum ReplayClockKind {
|
||||
/* host_clock */
|
||||
REPLAY_CLOCK_HOST,
|
||||
/* virtual_rt_clock */
|
||||
REPLAY_CLOCK_VIRTUAL_RT,
|
||||
REPLAY_CLOCK_COUNT
|
||||
};
|
||||
typedef enum ReplayClockKind ReplayClockKind;
|
||||
|
||||
/* IDs of the checkpoints */
|
||||
enum ReplayCheckpoint {
|
||||
CHECKPOINT_CLOCK_WARP,
|
||||
CHECKPOINT_RESET_REQUESTED,
|
||||
CHECKPOINT_SUSPEND_REQUESTED,
|
||||
CHECKPOINT_CLOCK_VIRTUAL,
|
||||
CHECKPOINT_CLOCK_HOST,
|
||||
CHECKPOINT_CLOCK_VIRTUAL_RT,
|
||||
CHECKPOINT_INIT,
|
||||
CHECKPOINT_RESET,
|
||||
CHECKPOINT_COUNT
|
||||
};
|
||||
typedef enum ReplayCheckpoint ReplayCheckpoint;
|
||||
|
||||
extern ReplayMode replay_mode;
|
||||
|
||||
/* Replay process control functions */
|
||||
|
||||
/*! Enables recording or saving event log with specified parameters */
|
||||
void replay_configure(struct QemuOpts *opts);
|
||||
/*! Initializes timers used for snapshotting and enables events recording */
|
||||
void replay_start(void);
|
||||
/*! Closes replay log file and frees other resources. */
|
||||
void replay_finish(void);
|
||||
/*! Adds replay blocker with the specified error description */
|
||||
void replay_add_blocker(Error *reason);
|
||||
|
||||
/* Processing the instructions */
|
||||
|
||||
/*! Returns number of executed instructions. */
|
||||
uint64_t replay_get_current_step(void);
|
||||
/*! Returns number of instructions to execute in replay mode. */
|
||||
int replay_get_instructions(void);
|
||||
/*! Updates instructions counter in replay mode. */
|
||||
void replay_account_executed_instructions(void);
|
||||
|
||||
/* Interrupts and exceptions */
|
||||
|
||||
/*! Called by exception handler to write or read
|
||||
exception processing events. */
|
||||
bool replay_exception(void);
|
||||
/*! Used to determine that exception is pending.
|
||||
Does not proceed to the next event in the log. */
|
||||
bool replay_has_exception(void);
|
||||
/*! Called by interrupt handlers to write or read
|
||||
interrupt processing events.
|
||||
\return true if interrupt should be processed */
|
||||
bool replay_interrupt(void);
|
||||
/*! Tries to read interrupt event from the file.
|
||||
Returns true, when interrupt request is pending */
|
||||
bool replay_has_interrupt(void);
|
||||
|
||||
/* Processing clocks and other time sources */
|
||||
|
||||
/*! Save the specified clock */
|
||||
int64_t replay_save_clock(ReplayClockKind kind, int64_t clock);
|
||||
/*! Read the specified clock from the log or return cached data */
|
||||
int64_t replay_read_clock(ReplayClockKind kind);
|
||||
/*! Saves or reads the clock depending on the current replay mode. */
|
||||
#define REPLAY_CLOCK(clock, value) \
|
||||
(replay_mode == REPLAY_MODE_PLAY ? replay_read_clock((clock)) \
|
||||
: replay_mode == REPLAY_MODE_RECORD \
|
||||
? replay_save_clock((clock), (value)) \
|
||||
: (value))
|
||||
|
||||
/* Events */
|
||||
|
||||
/*! Called when qemu shutdown is requested. */
|
||||
void replay_shutdown_request(void);
|
||||
/*! Should be called at check points in the execution.
|
||||
These check points are skipped, if they were not met.
|
||||
Saves checkpoint in the SAVE mode and validates in the PLAY mode.
|
||||
Returns 0 in PLAY mode if checkpoint was not found.
|
||||
Returns 1 in all other cases. */
|
||||
bool replay_checkpoint(ReplayCheckpoint checkpoint);
|
||||
|
||||
/* Asynchronous events queue */
|
||||
|
||||
/*! Disables storing events in the queue */
|
||||
void replay_disable_events(void);
|
||||
/*! Returns true when saving events is enabled */
|
||||
bool replay_events_enabled(void);
|
||||
/*! Adds bottom half event to the queue */
|
||||
void replay_bh_schedule_event(QEMUBH *bh);
|
||||
/*! Adds input event to the queue */
|
||||
void replay_input_event(QemuConsole *src, InputEvent *evt);
|
||||
/*! Adds input sync event to the queue */
|
||||
void replay_input_sync_event(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -33,7 +33,9 @@ void qemu_input_handler_bind(QemuInputHandlerState *s,
|
|||
const char *device_id, int head,
|
||||
Error **errp);
|
||||
void qemu_input_event_send(QemuConsole *src, InputEvent *evt);
|
||||
void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt);
|
||||
void qemu_input_event_sync(void);
|
||||
void qemu_input_event_sync_impl(void);
|
||||
|
||||
InputEvent *qemu_input_event_new_key(KeyValue *key, bool down);
|
||||
void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue