> From: Peter Maydell [mailto:[email protected]] > On 9 January 2018 at 13:21, Pavel Dovgalyuk <[email protected]> wrote: > > I tried to get some logs with the following code. > > It prints that there was an exception 5 and it was overwritten by the > > standard code. > > Fixed code prevents this overwrite. > > > > I guess that one of the following is true: > > - unfixed version misses some exceptions > > - fixed version processes some exceptions twice (e.g., when there is no > > clear exception) > > > > diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c > > index 280200f..fa810f7 100644 > > --- a/accel/tcg/cpu-exec.c > > +++ b/accel/tcg/cpu-exec.c > > @@ -605,6 +605,8 @@ static inline bool cpu_handle_interrupt(CPUState *cpu, > > /* Finally, check if we need to exit to the main loop. */ > > if (unlikely(atomic_read(&cpu->exit_request) > > || (use_icount && cpu->icount_decr.u16.low + cpu->icount_extra == > > 0))) > > + if (cpu->exception_index != -1 && cpu->exception_index != > > EXCP_INTERRUP > > + qemu_log("overwriting excp_index %x\n", cpu->exception_index); > > atomic_set(&cpu->exit_request, 0); > > cpu->exception_index = EXCP_INTERRUPT; > > return true; > > This looks like it's just working around whatever is going on > (why should EXCP_INTERRUPT be special?). What we need to do is > find out what's actually happening here...
The failure cause is in incorrect interrupt processing. When ARM processes hardware interrupt in arm_cpu_exec_interrupt(), it executes cs->exception_index = excp_idx; This assumes, that the exception will be processed later. But it is processed immediately by calling cc->do_interrupt(cs); instead of leaving this job to cpu_exec. I guess these calls should be removed to match the cpu_exec execution pattern. Pavel Dovgalyuk
