aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-06 18:54:46 +0000
committermalc <malc@c046a42c-6fe2-441c-8c8c-71466251a162>2008-11-06 18:54:46 +0000
commite1638bd8588d780079e231b109ac94f0c281efda (patch)
treed6c0246ef556bfa38a5165d4a6880d86c84e84ac
parent6d946cdae0b5ba6b45499a124263b57ca5bffe68 (diff)
Fix interrupt exclusion via SSTEP_NOIRQ
Commit #5620 revealed an issue of the SSTEP_NOIRQ masking that was applied on all interrupt sources (including internal ones) when single stepping through the guest. Due to that commit, we now ended up in an infinite loop when CPU_INTERRUPT_EXIT was pending on SSTEP resume. That was due to #5620 eating all TBs while CPU_INTERRUPT_EXIT is pending, but SSTEP_NOIRQ preventing CPU_INTERRUPT_EXIT to be processed. What SSTEP_NOIRQ should actually do is to block the delivery of all external, guest visible interrupts. With the fix below applied, single stepping now works again. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5643 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--cpu-exec.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/cpu-exec.c b/cpu-exec.c
index 6995112353..c6db5adf5e 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -384,8 +384,14 @@ int cpu_exec(CPUState *env1)
next_tb = 0; /* force lookup of first TB */
for(;;) {
interrupt_request = env->interrupt_request;
- if (unlikely(interrupt_request) &&
- likely(!(env->singlestep_enabled & SSTEP_NOIRQ))) {
+ if (unlikely(interrupt_request)) {
+ if (unlikely(env->singlestep_enabled & SSTEP_NOIRQ)) {
+ /* Mask out external interrupts for this step. */
+ interrupt_request &= ~(CPU_INTERRUPT_HARD |
+ CPU_INTERRUPT_FIQ |
+ CPU_INTERRUPT_SMI |
+ CPU_INTERRUPT_NMI);
+ }
if (interrupt_request & CPU_INTERRUPT_DEBUG) {
env->interrupt_request &= ~CPU_INTERRUPT_DEBUG;
env->exception_index = EXCP_DEBUG;