qemu-devel
[Top][All Lists]
Advanced

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

Re: Possible bug in Aarch64 single-stepping


From: Peter Maydell
Subject: Re: Possible bug in Aarch64 single-stepping
Date: Sun, 8 May 2022 13:08:10 +0100

On Sat, 7 May 2022 at 14:44, Chris Howard <cvz185@web.de> wrote:
>
> Hi, I’m writing a simple debugger in assembly code for the Raspberry Pi 3B 
> (in aarch64).
>
> I’m using QEMU 7.0.0. Everything is running in EL1. (I have MDE and KDE set 
> in MDSCR_EL1).
>
> I’m coming across Unexpected Behaviour when playing with single-stepping:
>
> It appears that single-stepping is enabled (ie. an exception is generated 
> after every instruction) when the SS bit (bit-0) is set in MDSCR_EL1 and 
> debug events are enabled in the CPSR (“D” bit clear) *** irrespective of 
> whether the SS bit (bit-21) is set in CPSR or not ***.
>
> I thought the SS bit (bit-21) needs to be set in CPSR for single-stepping to 
> occur (and that it gets cleared whenever an exception is taken and needs to 
> be reset if one wants to single-step again).
>
> Have I misunderstood / misconfigured something, or is this a bug?

I think you've misunderstood how the architectural single
step works. This is described in section D2.12 of the Arm ARM
(DDI0487H.a), but briefly, there is a state machine with three
states: Inactive, Active-not-pending, and Active-pending.

* Inactive is when MDSCR_EL1.SS is 0 or debug exceptions are
disabled from the current EL or security state.

* Active-not-pending is when we're not Inactive (ie MDSCR_EL1.SS is 1
and so on) and PSTATE.SS is 1. This is the state for "we're currently
pointing at the instruction we would like to step". The CPU
does the step by doing "execute this one instruction, and then
clear PSTATE.SS". It does *not* take a "single step completed"
exception. (I ignore for the moment the possibility that the
insn resulted in some other exception.)

* Active-pending is when we're not Inactive and PSTATE.SS is 0.
This state means "Software step is active, and a software step
is pending on the current instruction".
The usual way we get here is that we were in Active-not-pending
and then we executed the instruction and cleared PSTATE.SS.
But you can also get here in other ways (as your test case does).
In Active-pending state, the CPU does "take a software step
exception immediately, without doing anything else" -- which is
what you see.

In other words, the design effectively separates out the
"execute one instruction" part from the "take the exception
that says we completed a step" part. (This separation is
irrelevant for the 'normal case' where the stepped instruction
doesn't cause any exceptions and no interrupts arrive either,
but it can matter if there is some interrupt to be taken. For
instance, suppose that we do a step, and while the insn is
executing an interrupt comes in that is routed to EL3. We
want to take that interrupt first, before taking the
'single step complete' exception. Because the distinction
between 'active-not-pending' and 'active-pending' is stored
in PSTATE.SS, this works automatically -- we go to EL3, do
whatever the interrupt handler does, and then on the eret
to where we started, PSTATE.SS is restored to 0: so we then
correctly take the 'single step complete' exception without
executing another instruction.)

So if you don't want to see single-step exceptions you need
to make sure you stay in the Inactive state.

thanks
-- PMM



reply via email to

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