* Single-stepping ARMv7 with KDB...
@ 2011-03-10 9:12 Andrei Warkentin
2011-03-11 16:33 ` Will Deacon
[not found] ` <766766263404232078@unknownmsgid>
0 siblings, 2 replies; 6+ messages in thread
From: Andrei Warkentin @ 2011-03-10 9:12 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
I know that there has been a lot of work recently in cleaning -up
hardware single stepping / bp support, and from what I have seen this
has been to support user mode stepping. I'm sorry ahead of time if
someone already had done something to implement hardware single
stepping for kernel code. It would be great to be able to single-step
kernel code from KDB with the 'ss' command.
x86-like single-stepping could be implemented with non-matching IVA,
but there is the problem that enabling monitor mode in SVC mode will
immediately result in a trap. That can be worked around by always
exiting SVC through ABT mode, where we can then turn on the debug
monitor... On every CPU exception we'd make sure to clear the monitor,
since with single-stepping on that would immediately fault again when
we switch to SVC.
To create semantics similar to single-stepping TF flag in x86 EFLAGS,
the kernel single-stepping BRV/BRC pair would be saved/restored in
__switch_to, single-stepping would skip the user-mode switches (would
step across), and single-stepping would step across preemption
(preemption transparent or even disabled).
The other difficulty is handling ldrex/strex, since blindly stepping
over them will result in a persistent acquire failure (due to the
clrex in svc_exit), but this can be worked around by doing something
like -
1) If next instruction is strex, we know it will fail. Wait for next
instruction.
2) This is the instruction we want to put a matching bp on, but can't
do it now since we haven't run it yet, and we will
just trip on it. Wait for next instruction.
3) Set matching bp on prev instruction.
4) Let the ldrex/strex code repeat itself. Hit the matching bp.
5) Continue single-stepping.
I originally thought of this for KGDB, but gdb seems to want to send
anything but an "s-packet" (it tries various BP instructions like X
and Z-packets, then just scribbles over memory to create an invld
exc.). It's still useful for KDB and GDB could be made aware I
suppose...
Thoughts?
A
^ permalink raw reply [flat|nested] 6+ messages in thread* Single-stepping ARMv7 with KDB...
2011-03-10 9:12 Single-stepping ARMv7 with KDB Andrei Warkentin
@ 2011-03-11 16:33 ` Will Deacon
[not found] ` <766766263404232078@unknownmsgid>
1 sibling, 0 replies; 6+ messages in thread
From: Will Deacon @ 2011-03-11 16:33 UTC (permalink / raw)
To: linux-arm-kernel
Hi Andrei,
> I know that there has been a lot of work recently in cleaning -up
> hardware single stepping / bp support, and from what I have seen this
> has been to support user mode stepping. I'm sorry ahead of time if
> someone already had done something to implement hardware single
> stepping for kernel code. It would be great to be able to single-step
> kernel code from KDB with the 'ss' command.
ARM now has support for hardware breakpoints and watchpoints using
the new hw_breakpoint framework (which in turn is built on top of perf).
On v7 debug with the co-processor interface (for example, Cortex-A9) we
use mismatch breakpoints for single-stepping over a hit breakpoint before
reinserting it again. For breakpoints inside the kernel, we require the
debugger to register an `overflow handler' which must handle this
single-stepping itself.
x86 uses the hw_breakpoint framework for handling hardware breakpoints
in KGDB (see kgdb_correct_hw_break for how it converts breakinfo
structures into perf_events) so it might be possible to do something
similar for single-step on ARM if we allow the kernel to specify that
the breakpoint is to be a mismatch by poking the step_ctrl field in
the arch_hw_breakpoint struct.
> The other difficulty is handling ldrex/strex, since blindly stepping
> over them will result in a persistent acquire failure (due to the
> clrex in svc_exit), but this can be worked around by doing something
> like -
> 1) If next instruction is strex, we know it will fail. Wait for next
> instruction.
> 2) This is the instruction we want to put a matching bp on, but can't
> do it now since we haven't run it yet, and we will
> just trip on it. Wait for next instruction.
> 3) Set matching bp on prev instruction.
> 4) Let the ldrex/strex code repeat itself. Hit the matching bp.
> 5) Continue single-stepping.
IIRC the powerpc code in GDB does something similar to this (actually, it
looks ahead to try and find the store to pair with the load).
Will
^ permalink raw reply [flat|nested] 6+ messages in thread[parent not found: <766766263404232078@unknownmsgid>]
* Single-stepping ARMv7 with KDB...
[not found] ` <766766263404232078@unknownmsgid>
@ 2011-03-22 7:43 ` Andrei Warkentin
2011-03-22 19:52 ` Will Deacon
[not found] ` <8808174326287130926@unknownmsgid>
0 siblings, 2 replies; 6+ messages in thread
From: Andrei Warkentin @ 2011-03-22 7:43 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Mar 11, 2011 at 10:33 AM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Andrei,
>
>> I know that there has been a lot of work recently in cleaning -up
>> hardware single stepping / bp support, and from what I have seen this
>> has been to support user mode stepping. I'm sorry ahead of time if
>> someone already had done something to implement hardware single
>> stepping for kernel code. It would be great to be able to single-step
>> kernel code from KDB with the 'ss' command.
>
> ARM now has support for hardware breakpoints and watchpoints using
> the new hw_breakpoint framework (which in turn is built on top of perf).
>
> On v7 debug with the co-processor interface (for example, Cortex-A9) we
> use mismatch breakpoints for single-stepping over a hit breakpoint before
> reinserting it again. For breakpoints inside the kernel, we require the
> debugger to register an `overflow handler' which must handle this
> single-stepping itself.
>
> x86 uses the hw_breakpoint framework for handling hardware breakpoints
> in KGDB (see kgdb_correct_hw_break for how it converts breakinfo
> structures into perf_events) so it might be possible to do something
> similar for single-step on ARM if we allow the kernel to specify that
> the breakpoint is to be a mismatch by poking the step_ctrl field in
> the arch_hw_breakpoint struct.
...in this case monitor mode will have to be turned on outside SVC,
else it will immediately trigger a debug abort inside the code
programming BRV/BRC for mismatch... I guess that's the point I wanted
to bring up. I suppose it's only really useful for KDB, as with KGDB
you can have a debugger take care of branches, and all you would need
to ensure is to save/restore breakpoints across context switches (and
reentrancy). I'll play with enabling 'ss' with KDB as soon as I get
linux-next running on our platform...
A
^ permalink raw reply [flat|nested] 6+ messages in thread* Single-stepping ARMv7 with KDB...
2011-03-22 7:43 ` Andrei Warkentin
@ 2011-03-22 19:52 ` Will Deacon
[not found] ` <8808174326287130926@unknownmsgid>
1 sibling, 0 replies; 6+ messages in thread
From: Will Deacon @ 2011-03-22 19:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi Andrei,
> > x86 uses the hw_breakpoint framework for handling hardware breakpoints
> > in KGDB (see kgdb_correct_hw_break for how it converts breakinfo
> > structures into perf_events) so it might be possible to do something
> > similar for single-step on ARM if we allow the kernel to specify that
> > the breakpoint is to be a mismatch by poking the step_ctrl field in
> > the arch_hw_breakpoint struct.
>
> ...in this case monitor mode will have to be turned on outside SVC,
> else it will immediately trigger a debug abort inside the code
> programming BRV/BRC for mismatch... I guess that's the point I wanted
> to bring up. I suppose it's only really useful for KDB, as with KGDB
> you can have a debugger take care of branches, and all you would need
> to ensure is to save/restore breakpoints across context switches (and
> reentrancy). I'll play with enabling 'ss' with KDB as soon as I get
> linux-next running on our platform...
At the moment monitor mode is enabled all of the time, so you might
want to add a thread flag when a thread is using hardware debugging
resources. You can check that on return to userspace and enable monitor
mode only then (I'm not sure about your ABT trick, need to check the
docs). There will still be places in the hardware breakpoint code where
we need monitor mode enabled so you'll need to bank any mismatch
breakpoints over these regions of code and disable monitor mode before
reinstalling them again.
Note that enabling monitor mode is pretty error prone and might not
even be possible on your CPU so the failure path needs to be graceful.
Will
^ permalink raw reply [flat|nested] 6+ messages in thread[parent not found: <8808174326287130926@unknownmsgid>]
* Single-stepping ARMv7 with KDB...
[not found] ` <8808174326287130926@unknownmsgid>
@ 2011-03-22 22:26 ` Andrei Warkentin
2011-03-23 10:46 ` Will Deacon
0 siblings, 1 reply; 6+ messages in thread
From: Andrei Warkentin @ 2011-03-22 22:26 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Mar 22, 2011 at 2:52 PM, Will Deacon <will.deacon@arm.com> wrote:
> Hi Andrei,
>
>> > x86 uses the hw_breakpoint framework for handling hardware breakpoints
>> > in KGDB (see kgdb_correct_hw_break for how it converts breakinfo
>> > structures into perf_events) so it might be possible to do something
>> > similar for single-step on ARM if we allow the kernel to specify that
>> > the breakpoint is to be a mismatch by poking the step_ctrl field in
>> > the arch_hw_breakpoint struct.
>>
>> ...in this case monitor mode will have to be turned on outside SVC,
>> else it will immediately trigger a debug abort inside the code
>> programming BRV/BRC for mismatch... I guess that's the point I wanted
>> to bring up. I suppose it's only really useful for KDB, as with KGDB
>> you can have a debugger take care of branches, and all you would need
>> to ensure is to save/restore breakpoints across context switches (and
>> reentrancy). I'll play with enabling 'ss' with KDB as soon as I get
>> linux-next running on our platform...
>
> At the moment monitor mode is enabled all of the time, so you might
> want to add a thread flag when a thread is using hardware debugging
> resources. You can check that on return to userspace and enable monitor
> mode only then (I'm not sure about your ABT trick, need to check the
> docs). There will still be places in the hardware breakpoint code where
> we need monitor mode enabled so you'll need to bank any mismatch
> breakpoints over these regions of code and disable monitor mode before
> reinstalling them again.
>
I had an ugly proof-of-concept that worked on a Cortex A9 (more or
less...as long as you didn't step on clrex/strex or used Thumb code).
I guess I mostly thought people would be averse to adding
exit-through-ABT code, but there isn't really a better way to
otherwise be able to step through most of the Linux kernel from KDB
(that I am aware of), and it would be conditionally compiled if KDB
support is enabled.
If you look on Cortex A9 TRM (10.3.3), the SP [2:1] field in the BRC
register let's you condition the breakpoint for either USR/SVC/SYS,
SVC/SYS, USR or 'any'. 'any' is not usable outside of halting mode
for single-stepping purposes, so USR/SVC/SYS it is, and it's not so
bad - you lose the ability to trace the little bit of exception code
that runs before switching to SVC, as well as FIQ handlers, but I feel
that's pretty minor.
> Note that enabling monitor mode is pretty error prone and might not
> even be possible on your CPU so the failure path needs to be graceful.
Toggling it is not a good idea, then, especially since you still want
other active break/watch-points to trigger, so I would just reserve a
BRC/BRV pair if KDB was compiled in and bank the values...
A
^ permalink raw reply [flat|nested] 6+ messages in thread* Single-stepping ARMv7 with KDB...
2011-03-22 22:26 ` Andrei Warkentin
@ 2011-03-23 10:46 ` Will Deacon
0 siblings, 0 replies; 6+ messages in thread
From: Will Deacon @ 2011-03-23 10:46 UTC (permalink / raw)
To: linux-arm-kernel
> > At the moment monitor mode is enabled all of the time, so you might
> > want to add a thread flag when a thread is using hardware debugging
> > resources. You can check that on return to userspace and enable monitor
> > mode only then (I'm not sure about your ABT trick, need to check the
> > docs). There will still be places in the hardware breakpoint code where
> > we need monitor mode enabled so you'll need to bank any mismatch
> > breakpoints over these regions of code and disable monitor mode before
> > reinstalling them again.
> >
>
> I had an ugly proof-of-concept that worked on a Cortex A9 (more or
> less...as long as you didn't step on clrex/strex or used Thumb code).
> I guess I mostly thought people would be averse to adding
> exit-through-ABT code, but there isn't really a better way to
> otherwise be able to step through most of the Linux kernel from KDB
> (that I am aware of), and it would be conditionally compiled if KDB
> support is enabled.
Yes, the ABT stuff is fairly horrible. It also won't work for v6 cores,
which we do support in the hw-breakpoint layer.
> If you look on Cortex A9 TRM (10.3.3), the SP [2:1] field in the BRC
> register let's you condition the breakpoint for either USR/SVC/SYS,
> SVC/SYS, USR or 'any'. 'any' is not usable outside of halting mode
> for single-stepping purposes, so USR/SVC/SYS it is, and it's not so
> bad - you lose the ability to trace the little bit of exception code
> that runs before switching to SVC, as well as FIQ handlers, but I feel
> that's pretty minor.
>
> > Note that enabling monitor mode is pretty error prone and might not
> > even be possible on your CPU so the failure path needs to be graceful.
>
> Toggling it is not a good idea, then, especially since you still want
> other active break/watch-points to trigger, so I would just reserve a
> BRC/BRV pair if KDB was compiled in and bank the values...
I'm not sure. Toggling does offer some advantages if you only do it on
entry/exit from a debug exception (there's already some code to disable
preemption here). You can also use the thread flag to make sure we only
do the horrible ABT trick if the task we are returning to is indeed being
debugged.
However, I'm not convinced this is worth the hassle...
Will
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-03-23 10:46 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-03-10 9:12 Single-stepping ARMv7 with KDB Andrei Warkentin
2011-03-11 16:33 ` Will Deacon
[not found] ` <766766263404232078@unknownmsgid>
2011-03-22 7:43 ` Andrei Warkentin
2011-03-22 19:52 ` Will Deacon
[not found] ` <8808174326287130926@unknownmsgid>
2011-03-22 22:26 ` Andrei Warkentin
2011-03-23 10:46 ` Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).