diff options
author | Pavel Dovgalyuk <Pavel.Dovgaluk@ispras.ru> | 2015-09-17 19:24:16 +0300 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-11-06 10:16:00 +0100 |
commit | 6f0609697f3670bf755a91477487507a8ffee471 (patch) | |
tree | 675e4469cbeb2832fd1e9135bf7db7bfd3dfa65b /replay | |
parent | 8b42704441865611a5ee241ac9fc5cabc47a079b (diff) | |
download | qemu-6f0609697f3670bf755a91477487507a8ffee471.zip qemu-6f0609697f3670bf755a91477487507a8ffee471.tar.gz qemu-6f0609697f3670bf755a91477487507a8ffee471.tar.bz2 |
replay: interrupts and exceptions
This patch includes modifications of common cpu files. All interrupts and
exceptions occured during recording are written into the replay log.
These events allow correct replaying the execution by kicking cpu thread
when one of these events is found in the log.
Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
Message-Id: <20150917162416.8676.57647.stgit@PASHA-ISP.def.inno>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Diffstat (limited to 'replay')
-rw-r--r-- | replay/replay-internal.h | 4 | ||||
-rw-r--r-- | replay/replay.c | 67 |
2 files changed, 71 insertions, 0 deletions
diff --git a/replay/replay-internal.h b/replay/replay-internal.h index ff4fabc..5ff1c14 100644 --- a/replay/replay-internal.h +++ b/replay/replay-internal.h @@ -17,6 +17,10 @@ enum ReplayEvents { /* for instruction event */ EVENT_INSTRUCTION, + /* for software interrupt */ + EVENT_INTERRUPT, + /* for emulated exceptions */ + EVENT_EXCEPTION, EVENT_COUNT }; diff --git a/replay/replay.c b/replay/replay.c index b2c6750..b4fc64a 100644 --- a/replay/replay.c +++ b/replay/replay.c @@ -79,3 +79,70 @@ void replay_account_executed_instructions(void) replay_mutex_unlock(); } } + +bool replay_exception(void) +{ + if (replay_mode == REPLAY_MODE_RECORD) { + replay_save_instructions(); + replay_mutex_lock(); + replay_put_event(EVENT_EXCEPTION); + replay_mutex_unlock(); + return true; + } else if (replay_mode == REPLAY_MODE_PLAY) { + bool res = replay_has_exception(); + if (res) { + replay_mutex_lock(); + replay_finish_event(); + replay_mutex_unlock(); + } + return res; + } + + return true; +} + +bool replay_has_exception(void) +{ + bool res = false; + if (replay_mode == REPLAY_MODE_PLAY) { + replay_account_executed_instructions(); + replay_mutex_lock(); + res = replay_next_event_is(EVENT_EXCEPTION); + replay_mutex_unlock(); + } + + return res; +} + +bool replay_interrupt(void) +{ + if (replay_mode == REPLAY_MODE_RECORD) { + replay_save_instructions(); + replay_mutex_lock(); + replay_put_event(EVENT_INTERRUPT); + replay_mutex_unlock(); + return true; + } else if (replay_mode == REPLAY_MODE_PLAY) { + bool res = replay_has_interrupt(); + if (res) { + replay_mutex_lock(); + replay_finish_event(); + replay_mutex_unlock(); + } + return res; + } + + return true; +} + +bool replay_has_interrupt(void) +{ + bool res = false; + if (replay_mode == REPLAY_MODE_PLAY) { + replay_account_executed_instructions(); + replay_mutex_lock(); + res = replay_next_event_is(EVENT_INTERRUPT); + replay_mutex_unlock(); + } + return res; +} |