qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts wh


From: Richard Henderson
Subject: Re: [Qemu-devel] [PATCH] cpu-exec: Don't mask out external interrupts when single-stepping an invalid instruction.
Date: Fri, 12 Sep 2014 08:37:45 -0700
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.1.0

On 09/12/2014 07:33 AM, Martin Galvan wrote:
> On Thu, Sep 11, 2014 at 8:52 PM, Richard Henderson <address@hidden> wrote:
>> On 09/11/2014 03:13 PM, Peter Maydell wrote:
>> In particular, I'd expect the invalid exception to be recognized, and then 
>> the
>> cpu loop exited, before the single-step exception could overwrite it.  E.g. 
>> how
>> things work on alpha:
>>
>> $ cat z.s
>>         .globl _start
>> _start:
>>         nop
>>         .long (1 << 26)
>>         nop
>> $ alphaev67-linux-as -o z.o z.s
>> $ alphaev67-linux-ld -Ttext-segment 0xfffffc0000100000 -o z z.o
>> $ ./run/bin/qemu-system-alpha -kernel z -S -gdb tcp::12345 &
>> $ alphaev67-linux-gdb ./z
> 
> Can't test this myself since I don't have an alpha cross-toolchain at
> hand right now.

It's pretty simple to build a cross binutils; much easier and quicker than
building a cross gcc.  And you'd need the cross gdb that gets built in the
process anyway...

> So if I understood right, what you do in Alpha is:
> 
> - With your PC pointing to the invalid instruction, single-step once.
> - The generated assembly will contain a call to excp with EXCP_OPCDEC.
> - On excp, it sets cs->exception_index to EXCP_OPCDEC and then does a
> cpu_loop_exit.
> - As it advances through the loop again, it'll notice exception_index
> is greater than 0, thus calling do_interrupt.
> - Inside do_interrupt it sets the PC to point to the exception handler
> entry point.

All true and correct so far.

> - It sets cpu->exception_index to EXCP_DEBUG somehow, thus returning
> control back to gdb.

Ah, well, no.  Certainly target-alpha does no such thing.
I admit I have no idea exactly what happens here, because...

> - The net result is that single-stepping with the PC pointing to an
> invalid instruction
>   immediately leads us to the exception handler.

... it just worked, yes.

> That's exactly what I'm trying to achieve. However, in target-arm we
> end up calling do_interrupt twice:
> the first time in the outer for(;;) to set cpu->interrupt_request to
> CPU_INTERRUPT_HARD,
> and the second time inside the inner for(;;) to actually set the PC to
> point to the exception handler.

Ah, well, that's where we begin to differ.

Alpha do_interrupt doesn't mess with cpu->interrupt_request at all, and doesn't
generate two calls to do_interrupt.  The one call finds the vector for the
given interrupt, modifies the PC, and swaps to the shadow register bank.

Fin.

(Which reminds me, we really, Really, need to get those ifdefs in cpu_exec
factored out into a nice single cpu callback.  Every time I read this code, I
feel I've missed something.)

> How do you set cpu->exception_index in to EXCP_DEBUG after calling
> do_interrupt with EXCP_OPCDEC?

I still don't know, but I know that _I_ don't do it.  I tried stepping through
qemu itself here, but I managed to crash the guest gdb in the process; dunno
what happened there.


r~



reply via email to

[Prev in Thread] Current Thread [Next in Thread]