diff mbox

ARM: hw_breakpoint: silent EPERM when setting ARM_DSCR_MDBGEN on ARM_DEBUG_ARCH_V7_ECP14

Message ID 20120913214102.GB11399@mudshark.cambridge.arm.com (mailing list archive)
State New, archived
Headers show

Commit Message

Will Deacon Sept. 13, 2012, 9:41 p.m. UTC
On Thu, Sep 13, 2012 at 07:42:09PM +0100, Valentin Pistol wrote:
> Hi everyone,

Hi Valentin,

> This is my first list post, thanks for bearing with me.

You might want to configure your mail client to wrap lines at 76-80 columns
in order to make your mails more readable.

> Summary:
> Kernel is compiled with CONFIG_HAVE_HW_BREAKPOINT but after boot the DSCR register does not have monitor mode enabled which is required for debug register use.

That means that hardware breakpoints are unusable on your platform, likely
because it has been locked down in the hardware (there is a signal that
can be tied off to prevent monitor mode debug).

> I am interested in using the ptrace interface for hw breakpoints/watchpoints on a Cortex A9. I found out that watchpoints are not triggering and tracked down an issue to the hw_breakpoint.c. The flow is as follows:
> arch_hw_breakpoint_init > on_each_cpu(reset_ctrl_regs, &cpumask, 1);  > reset_ctrl_regs > enable_monitor_mode
> 
> enable_monitor_mode performs ARM_DBG_WRITE(c2, 2, (dscr | ARM_DSCR_MDBGEN));
> Another read on dscr is performed to check if the bit was set and if not it returns -EPERM. In my case the write is not successful so it returns.
> 
> Since the reset_ctrl_regs code just returns on failure setting the monitor mode, there is no reporting of this.
> if (enable_monitor_mode)
>  return ret;

I'll fix this, we should print something here. Thanks.

> After boot, my ptrace test example with PTRACE_GETHBPREGS works fine but PTRACE_SETHBPREGS fails silently inside arch_install_hw_breakpoint due to the same enable_monitor_mode issue.

That's probably because the monitor mode check is at *install* time, which
is asynchronous wrt the ptrace system call (i.e. when the child is next
scheduled). How about we move the check to validation time instead? We
should never try to install an unvalidated breakpoint and trying to support
hardware debuggers and software debuggers simultaneously isn't actually
support by the architecture, requiring some discipline from the guy with the
JTAG cable.

Completely untested patch below, please let me know how you get on...

Will

--->8

Comments

Valentin Pistol Sept. 14, 2012, 8:08 a.m. UTC | #1
> Hi Valentin,

Hi Will,

> You might want to configure your mail client to wrap lines at 76-80 columns
> in order to make your mails more readable.

Thanks for the good suggestion.

>> Summary:
>> Kernel is compiled with CONFIG_HAVE_HW_BREAKPOINT but after boot the DSCR register does not have monitor mode enabled which is required for debug register use.
>
> That means that hardware breakpoints are unusable on your platform, likely
> because it has been locked down in the hardware (there is a signal that
> can be tied off to prevent monitor mode debug).

Is there a reliable way to determine that they are locked down?
Any particular register/bit I can check to confirm?
If they're really locked down I think getting a development board is
likely the only way to have full support (considering a PandaBoard).

> Completely untested patch below, please let me know how you get on...

Looks good, I'll give it a try.

Thanks a lot for your help!
Valentin
Will Deacon Sept. 18, 2012, 10:04 a.m. UTC | #2
On Fri, Sep 14, 2012 at 09:08:24AM +0100, Valentin Pistol wrote:
> Is there a reliable way to determine that they are locked down?
> Any particular register/bit I can check to confirm?

You can take a look at the DBGAUTHSTATUS register and try to determine the
signal values for SPNIDEN, DBGEN and NIDEN.

> > Completely untested patch below, please let me know how you get on...
> 
> Looks good, I'll give it a try.

Great. Let me know if it helps and, if so, I'll merge it.

Will
Valentin Pistol Oct. 9, 2012, 5:05 p.m. UTC | #3
Will,

On Tue, Sep 18, 2012 at 3:04 AM, Will Deacon <will.deacon@arm.com> wrote:
>
> On Fri, Sep 14, 2012 at 09:08:24AM +0100, Valentin Pistol wrote:
> > Is there a reliable way to determine that they are locked down?
> > Any particular register/bit I can check to confirm?
>
> You can take a look at the DBGAUTHSTATUS register and try to determine the
> signal values for SPNIDEN, DBGEN and NIDEN.

DBGAUTHSTATUS=0xaa confirming DBGEN is LOW. Since then I found out
that there are two types of OMAP devices:
GP (General Purpose) and HS (High Security) and supposedly Debug
Capabilities are only available on GP devices.
Thus, I ordered a Pandaboard ES with OMAP4460 and tested it with a
prebuilt Ubuntu 12.04 image.
After boot monitor mode is still not set, the DSCR reads the same
0x01030002 just as with the previous Galaxy Nexus.

I contacted TI and they seem to say hw breakpoints/watchpoints are
available on Pandaboard but they are confused about monitor mode,
saying it's not available on Pandaboard GP.
See http://e2e.ti.com/support/omap/f/849/p/216276/770995.aspx for the
discussion.
Isn't monitor mode and DBGEN on HIGH required for access to
breakpoints/watchpoints?
Maybe they are thinking about Secure Monitor Mode and TrustZone which
is not related?

Have you used a Pandaboard and can comment on how to enable the
breakpoints/watchpoints?
Could you also mention a specific development board that you are using
and recommend for access to these features?

>
> > > Completely untested patch below, please let me know how you get on...
> >
> > Looks good, I'll give it a try.
>
> Great. Let me know if it helps and, if so, I'll merge it.

Sorry I wasn't able to directly apply your patch to the specific
Android kernel version I was using.
Manually merging the code seems to perform as expected.

Thanks a lot for your help,
Valentin
Will Deacon Oct. 9, 2012, 9:08 p.m. UTC | #4
On Tue, Oct 09, 2012 at 06:05:53PM +0100, Valentin Pistol wrote:
> Will,

Hi Valentin,

> On Tue, Sep 18, 2012 at 3:04 AM, Will Deacon <will.deacon@arm.com> wrote:
> >
> > On Fri, Sep 14, 2012 at 09:08:24AM +0100, Valentin Pistol wrote:
> > > Is there a reliable way to determine that they are locked down?
> > > Any particular register/bit I can check to confirm?
> >
> > You can take a look at the DBGAUTHSTATUS register and try to determine the
> > signal values for SPNIDEN, DBGEN and NIDEN.
> 
> DBGAUTHSTATUS=0xaa confirming DBGEN is LOW. Since then I found out
> that there are two types of OMAP devices:
> GP (General Purpose) and HS (High Security) and supposedly Debug
> Capabilities are only available on GP devices.
> Thus, I ordered a Pandaboard ES with OMAP4460 and tested it with a
> prebuilt Ubuntu 12.04 image.
> After boot monitor mode is still not set, the DSCR reads the same
> 0x01030002 just as with the previous Galaxy Nexus.

Can you try this with my hw-breakpoint branch please? I've reworked a fair
amount of code there, so it might at least be more verbose if it fails.

> I contacted TI and they seem to say hw breakpoints/watchpoints are
> available on Pandaboard but they are confused about monitor mode,
> saying it's not available on Pandaboard GP.
> See http://e2e.ti.com/support/omap/f/849/p/216276/770995.aspx for the
> discussion.

In that discussion, the TI folks are confusing `Monitor-mode Debug' with
`Secure Monitor Mode'. They are two completely different things and (for the
purposes of this discussion), unrelated. You should press them further on
this!

> Have you used a Pandaboard and can comment on how to enable the
> breakpoints/watchpoints?

I haven't tried it, but I do have a Panda now so I could give it a go when I
get a chance. I suspect there's something related to power-management at
play... for JTAG, you need to hack MLO as described here:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15314.html

maybe something similar is required for self-hosted (monitor mode) debug?

> Could you also mention a specific development board that you are using
> and recommend for access to these features?

I use the ARM Versatile Express platform, but I think it's probably quite
expensive to get hold of if you don't work for ARM.

Will
Dietmar Eggemann Oct. 12, 2012, 11:26 a.m. UTC | #5
On 09/10/12 18:05, Valentin Pistol wrote:
> Will,
>
> On Tue, Sep 18, 2012 at 3:04 AM, Will Deacon <will.deacon@arm.com> wrote:
>>
>> On Fri, Sep 14, 2012 at 09:08:24AM +0100, Valentin Pistol wrote:
>>> Is there a reliable way to determine that they are locked down?
>>> Any particular register/bit I can check to confirm?
>>
>> You can take a look at the DBGAUTHSTATUS register and try to determine the
>> signal values for SPNIDEN, DBGEN and NIDEN.
>
> DBGAUTHSTATUS=0xaa confirming DBGEN is LOW. Since then I found out
> that there are two types of OMAP devices:
> GP (General Purpose) and HS (High Security) and supposedly Debug
> Capabilities are only available on GP devices.
> Thus, I ordered a Pandaboard ES with OMAP4460 and tested it with a
> prebuilt Ubuntu 12.04 image.
> After boot monitor mode is still not set, the DSCR reads the same
> 0x01030002 just as with the previous Galaxy Nexus.
>
> I contacted TI and they seem to say hw breakpoints/watchpoints are
> available on Pandaboard but they are confused about monitor mode,
> saying it's not available on Pandaboard GP.
> See http://e2e.ti.com/support/omap/f/849/p/216276/770995.aspx for the
> discussion.
> Isn't monitor mode and DBGEN on HIGH required for access to
> breakpoints/watchpoints?
> Maybe they are thinking about Secure Monitor Mode and TrustZone which
> is not related?
>
> Have you used a Pandaboard and can comment on how to enable the
> breakpoints/watchpoints?
> Could you also mention a specific development board that you are using
> and recommend for access to these features?

I'm running Linaro 12.08 on Pandaboard (Rev A1) and on this board 
DBGAUTHSTATUS.NSNE and DBGAUTHSTATUS.NSE are set.

With additional logs in enable_monitor_mode() 
[arch/arm/kernel/hw_breakpoint.c]:

root@linaro-nano:~# dmesg | grep hw-break
[    0.321380] hw-breakpoint: arch_hw_breakpoint_init cpu0 debug_arch=3
[    0.321441] hw-breakpoint: enable_monitor_mode cpu1 
DBGDSCR=03070002
[    0.321441] hw-breakpoint: enable_monitor_mode cpu1 
DBGAUTHSTATUS=000000af
[    0.321502] hw-breakpoint: enable_monitor_mode cpu0 
DBGDSCR=03070002
[    0.321533] hw-breakpoint: enable_monitor_mode cpu0 
DBGAUTHSTATUS=000000af
[    0.321533] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1 
watchpoint registers.
[    0.321563] hw-breakpoint: maximum watchpoint size is 4 bytes.

-- Dietmar

>
>>
>>>> Completely untested patch below, please let me know how you get on...
>>>
>>> Looks good, I'll give it a try.
>>
>> Great. Let me know if it helps and, if so, I'll merge it.
>
> Sorry I wasn't able to directly apply your patch to the specific
> Android kernel version I was using.
> Manually merging the code seems to perform as expected.
>
> Thanks a lot for your help,
> Valentin
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Valentin Pistol Oct. 15, 2012, 8:48 p.m. UTC | #6
> Can you try this with my hw-breakpoint branch please? I've reworked a fair
> amount of code there, so it might at least be more verbose if it fails.

I am trying the Linaro 12.08 images from
http://releases.linaro.org/12.08/android/leb-panda/
After testing it boots fine on my board, I replaced the uImage with
one built from your code at
git://git.kernel.org/pub/scm/linux/kernel/git/will/linux.git and
hw-breakpoint branch.

Unfortunately it gets stuck on "Uncompressing Linux... done, booting
the kernel." on the serial port.
What kernel config are you using? I'm using omap2plus_defconfig
resulting in a Linux-3.7.0-rc1-00015-gd633d80b kernel:
$ make mrproper
$ make ARCH=arm CROSS_COMPILE=arm-eabi- omap2plus_defconfig uImage

I also tried using the Linaro 12.08 kernel config from the above page:
$ make mrproper
$ cp linaro_kernel_config .config
$ make ARCH=arm CROSS_COMPILE=arm-eabi- uImage
[ accept a lot of default values due to kernel version changes ]

Then I mount the SD card and replace the uImage file yet neither uImages boot.
Here is the full serial log: http://pastebin.com/raw.php?i=YQ4vk634

> In that discussion, the TI folks are confusing `Monitor-mode Debug' with
> `Secure Monitor Mode'. They are two completely different things and (for the
> purposes of this discussion), unrelated. You should press them further on
> this!

Thanks for the clarification, I contacted them again and will see how
it turns out.

>> Have you used a Pandaboard and can comment on how to enable the
>> breakpoints/watchpoints?
>
> I haven't tried it, but I do have a Panda now so I could give it a go when I
> get a chance. I suspect there's something related to power-management at
> play... for JTAG, you need to hack MLO as described here:
>
> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka15314.html
>
> maybe something similar is required for self-hosted (monitor mode) debug?

If you could give it a try on your Panda that would be great!

On Fri, Oct 12, 2012 at 7:26 AM, Dietmar Eggemann
<dietmar.eggemann@arm.com> wrote:
> I'm running Linaro 12.08 on Pandaboard (Rev A1) and on this board
> DBGAUTHSTATUS.NSNE and DBGAUTHSTATUS.NSE are set.
>
> With additional logs in enable_monitor_mode()
> [arch/arm/kernel/hw_breakpoint.c]:
>
> root@linaro-nano:~# dmesg | grep hw-break
> [    0.321380] hw-breakpoint: arch_hw_breakpoint_init cpu0 debug_arch=3
> [    0.321441] hw-breakpoint: enable_monitor_mode cpu1 DBGDSCR=03070002
> [    0.321441] hw-breakpoint: enable_monitor_mode cpu1
> DBGAUTHSTATUS=000000af
> [    0.321502] hw-breakpoint: enable_monitor_mode cpu0 DBGDSCR=03070002
> [    0.321533] hw-breakpoint: enable_monitor_mode cpu0
> DBGAUTHSTATUS=000000af
> [    0.321533] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1
> watchpoint registers.
> [    0.321563] hw-breakpoint: maximum watchpoint size is 4 bytes.

Dietmar,

That looks great! Did you flash the prebuilt images from Linaro 12.08
and replaced the kernel with those extra debug messages on top of
kernel at git://android.git.linaro.org/kernel/panda? Or are you using
Will's branch?
I am using a newer Pandaboard ES (Rev B1) and hope this is not the problem.
Could you please provide a few instructions to reproduce your setup?

Thanks!
Valentin
Valentin Pistol Oct. 16, 2012, 4:26 a.m. UTC | #7
> On Fri, Oct 12, 2012 at 7:26 AM, Dietmar Eggemann
> <dietmar.eggemann@arm.com> wrote:
>> I'm running Linaro 12.08 on Pandaboard (Rev A1) and on this board
>> DBGAUTHSTATUS.NSNE and DBGAUTHSTATUS.NSE are set.
>>
>> With additional logs in enable_monitor_mode()
>> [arch/arm/kernel/hw_breakpoint.c]:
>>
>> root@linaro-nano:~# dmesg | grep hw-break
>> [    0.321380] hw-breakpoint: arch_hw_breakpoint_init cpu0 debug_arch=3
>> [    0.321441] hw-breakpoint: enable_monitor_mode cpu1 DBGDSCR=03070002
>> [    0.321441] hw-breakpoint: enable_monitor_mode cpu1
>> DBGAUTHSTATUS=000000af
>> [    0.321502] hw-breakpoint: enable_monitor_mode cpu0 DBGDSCR=03070002
>> [    0.321533] hw-breakpoint: enable_monitor_mode cpu0
>> DBGAUTHSTATUS=000000af
>> [    0.321533] hw-breakpoint: found 5 (+1 reserved) breakpoint and 1
>> watchpoint registers.
>> [    0.321563] hw-breakpoint: maximum watchpoint size is 4 bytes.
>
> Dietmar,
>
> That looks great! Did you flash the prebuilt images from Linaro 12.08
> and replaced the kernel with those extra debug messages on top of
> kernel at git://android.git.linaro.org/kernel/panda? Or are you using
> Will's branch?
> I am using a newer Pandaboard ES (Rev B1) and hope this is not the problem.
> Could you please provide a few instructions to reproduce your setup?
>

I just tried the kernel over at
git://android.git.linaro.org/kernel/panda and used the same branch in
the prebuilt Linaro 12.08:
linaro-tilt-android-tracking e78449e OMAPFB: Asynchronous vsync notification
I used android_omap4_defconfig but CONFIG_HW_HAVE_BREAKPOINT were not
persistent in the .config so I had to manually add HW_HAVE_BREAKPOINT
to arch/arm/Kconfig under ARCH_OMAP and also add PERF_EVENTS
dependency.
Similar to Dietmar I added additional info to
arch/arm/kernel/hw_breakpoint.c and now I can confirm I see the proper
value of DSCR = 0x3078002 and DBGAUTHSTATUS = 0xaf !
Flashing this 3.2 Kernel works without a problem but I am still
interested in getting Will's branch and 3.7 Kernel working.
I tried the above on Will's branch (copy over the
android_omap4_defconfig and edit Kconfig) but the kernel is still
stuck at trying to boot.

I am wondering if I can use all 4 watchpoints available in OMAP4460.
Normally the kernel just reports 1 watchpoint available due to what I
believe is a lack of information on what watchpoint triggered. Would
it be possible to enable all 4 and have a workaround to determine
which WP triggers?

Valentin
diff mbox

Patch

diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index ba386bd..f513b0e 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -322,14 +322,9 @@  int arch_install_hw_breakpoint(struct perf_event *bp)
 {
 	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 	struct perf_event **slot, **slots;
-	int i, max_slots, ctrl_base, val_base, ret = 0;
+	int i, max_slots, ctrl_base, val_base;
 	u32 addr, ctrl;
 
-	/* Ensure that we are in monitor mode and halting mode is disabled. */
-	ret = enable_monitor_mode();
-	if (ret)
-		goto out;
-
 	addr = info->address;
 	ctrl = encode_ctrl_reg(info->ctrl) | 0x1;
 
@@ -356,10 +351,8 @@  int arch_install_hw_breakpoint(struct perf_event *bp)
 		}
 	}
 
-	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n")) {
-		ret = -EBUSY;
-		goto out;
-	}
+	if (WARN_ONCE(i == max_slots, "Can't find any breakpoint slot\n"))
+		return -EBUSY;
 
 	/* Override the breakpoint data with the step data. */
 	if (info->step_ctrl.enabled) {
@@ -378,8 +371,7 @@  int arch_install_hw_breakpoint(struct perf_event *bp)
 	/* Setup the control register. */
 	write_wb_reg(ctrl_base + i, ctrl);
 
-out:
-	return ret;
+	return 0;
 }
 
 void arch_uninstall_hw_breakpoint(struct perf_event *bp)
@@ -590,6 +582,10 @@  int arch_validate_hwbkpt_settings(struct perf_event *bp)
 	int ret = 0;
 	u32 offset, alignment_mask = 0x3;
 
+	/* Ensure that we are in monitor mode and halting mode is disabled. */
+	if (enable_monitor_mode())
+		return -ENODEV;
+
 	/* Build the arch_hw_breakpoint. */
 	ret = arch_build_bp_info(bp);
 	if (ret)
@@ -935,8 +931,10 @@  static void reset_ctrl_regs(void *unused)
 	isb();
 
 reset_regs:
-	if (enable_monitor_mode())
+	if (enable_monitor_mode()) {
+		pr_warning("CPU %d failed to enable monitor mode\n", cpu);
 		return;
+	}
 
 	/* We must also reset any reserved registers. */
 	raw_num_brps = get_num_brp_resources();