linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/2] arm64: Fix pending single-step debugging issues
@ 2023-02-02  7:31 Sumit Garg
  2023-02-02  7:31 ` [PATCH v6 1/2] arm64: entry: Skip single stepping into interrupt handlers Sumit Garg
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Sumit Garg @ 2023-02-02  7:31 UTC (permalink / raw)
  To: will, catalin.marinas
  Cc: mark.rutland, daniel.thompson, dianders, liwei391, mhiramat, maz,
	ardb, linux-arm-kernel, linux-kernel, Sumit Garg

This patch-set reworks pending fixes from Wei's series [1] to make
single-step debugging via kgdb/kdb on arm64 work as expected. There was
a prior discussion on ML [2] regarding if we should keep the interrupts
enabled during single-stepping. So patch #1 follows suggestion from Will
[3] to not disable interrupts during single stepping but rather skip
single stepping within interrupt handler.

[1] https://lore.kernel.org/all/20200509214159.19680-1-liwei391@huawei.com/
[2] https://lore.kernel.org/all/CAD=FV=Voyfq3Qz0T3RY+aYWYJ0utdH=P_AweB=13rcV8GDBeyQ@mail.gmail.com/
[3] https://lore.kernel.org/all/20200626095551.GA9312@willie-the-truck/

Changes in v6:
- Fix incorrect rescheduling check introduced by rework for v5.
- Patch #2: s/kernel_regs_reset_single_step/kernel_rewind_single_step/
- Collected Daniel's tags.

Changes in v5:
- Incorporated misc. comments from Mark.

Changes in v4:
- Rebased to the tip of mainline.
- Picked up Doug's Tested-by tag.

Changes in v3:
- Reword commit descriptions as per Daniel's suggestions.

Changes in v2:
- Replace patch #1 to rather follow Will's suggestion.

Sumit Garg (2):
  arm64: entry: Skip single stepping into interrupt handlers
  arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step

 arch/arm64/include/asm/debug-monitors.h |  1 +
 arch/arm64/kernel/debug-monitors.c      |  5 +++++
 arch/arm64/kernel/entry-common.c        | 22 ++++++++++++++++++++--
 arch/arm64/kernel/kgdb.c                |  2 ++
 4 files changed, 28 insertions(+), 2 deletions(-)

-- 
2.34.1


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v6 1/2] arm64: entry: Skip single stepping into interrupt handlers
  2023-02-02  7:31 [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
@ 2023-02-02  7:31 ` Sumit Garg
  2023-02-02  7:31 ` [PATCH v6 2/2] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step Sumit Garg
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Sumit Garg @ 2023-02-02  7:31 UTC (permalink / raw)
  To: will, catalin.marinas
  Cc: mark.rutland, daniel.thompson, dianders, liwei391, mhiramat, maz,
	ardb, linux-arm-kernel, linux-kernel, Sumit Garg

Currently on systems where the timer interrupt (or any other
fast-at-human-scale periodic interrupt) is active then it is impossible
to step any code with interrupts unlocked because we will always end up
stepping into the timer interrupt instead of stepping the user code.

The common user's goal while single stepping is that when they step then
the system will stop at PC+4 or PC+I for a branch that gets taken
relative to the instruction they are stepping. So, fix broken single step
implementation via skipping single stepping into interrupt handlers.

The methodology is when we receive an interrupt from EL1, check if we
are single stepping (pstate.SS). If yes then we save MDSCR_EL1.SS and
clear the register bit if it was set. Then unmask only D and leave I set.
On return from the interrupt, set D and restore MDSCR_EL1.SS. Along with
this skip reschedule if we were stepping.

Suggested-by: Will Deacon <will@kernel.org>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Daniel Thompson <daniel.thompson@linaro.org>
Tested-by: Daniel Thompson <daniel.thompson@linaro.org>
---
 arch/arm64/kernel/entry-common.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index cce1167199e3..568481f66977 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -231,11 +231,15 @@ DEFINE_STATIC_KEY_TRUE(sk_dynamic_irqentry_exit_cond_resched);
 #define need_irq_preemption()	(IS_ENABLED(CONFIG_PREEMPTION))
 #endif
 
-static void __sched arm64_preempt_schedule_irq(void)
+static void __sched arm64_preempt_schedule_irq(struct pt_regs *regs)
 {
 	if (!need_irq_preemption())
 		return;
 
+	/* Don't reschedule in case we are single stepping */
+	if (regs->pstate & DBG_SPSR_SS)
+		return;
+
 	/*
 	 * Note: thread_info::preempt_count includes both thread_info::count
 	 * and thread_info::need_resched, and is not equivalent to
@@ -471,19 +475,33 @@ static __always_inline void __el1_irq(struct pt_regs *regs,
 	do_interrupt_handler(regs, handler);
 	irq_exit_rcu();
 
-	arm64_preempt_schedule_irq();
+	arm64_preempt_schedule_irq(regs);
 
 	exit_to_kernel_mode(regs);
 }
+
 static void noinstr el1_interrupt(struct pt_regs *regs,
 				  void (*handler)(struct pt_regs *))
 {
+	unsigned long mdscr;
+
+	/* Disable single stepping within interrupt handler */
+	if (regs->pstate & DBG_SPSR_SS) {
+		mdscr = read_sysreg(mdscr_el1);
+		write_sysreg(mdscr & ~DBG_MDSCR_SS, mdscr_el1);
+	}
+
 	write_sysreg(DAIF_PROCCTX_NOIRQ, daif);
 
 	if (IS_ENABLED(CONFIG_ARM64_PSEUDO_NMI) && !interrupts_enabled(regs))
 		__el1_pnmi(regs, handler);
 	else
 		__el1_irq(regs, handler);
+
+	if (regs->pstate & DBG_SPSR_SS) {
+		write_sysreg(DAIF_PROCCTX_NOIRQ | PSR_D_BIT, daif);
+		write_sysreg(mdscr, mdscr_el1);
+	}
 }
 
 asmlinkage void noinstr el1h_64_irq_handler(struct pt_regs *regs)
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH v6 2/2] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step
  2023-02-02  7:31 [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
  2023-02-02  7:31 ` [PATCH v6 1/2] arm64: entry: Skip single stepping into interrupt handlers Sumit Garg
@ 2023-02-02  7:31 ` Sumit Garg
  2023-02-22  7:06 ` [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
  2023-04-14 14:38 ` Will Deacon
  3 siblings, 0 replies; 5+ messages in thread
From: Sumit Garg @ 2023-02-02  7:31 UTC (permalink / raw)
  To: will, catalin.marinas
  Cc: mark.rutland, daniel.thompson, dianders, liwei391, mhiramat, maz,
	ardb, linux-arm-kernel, linux-kernel, Sumit Garg

Currently only the first attempt to single-step has any effect. After
that all further stepping remains "stuck" at the same program counter
value.

Refer to the ARM Architecture Reference Manual (ARM DDI 0487E.a) D2.12,
PSTATE.SS=1 should be set at each step before transferring the PE to the
'Active-not-pending' state. The problem here is PSTATE.SS=1 is not set
since the second single-step.

After the first single-step, the PE transferes to the 'Inactive' state,
with PSTATE.SS=0 and MDSCR.SS=1, thus PSTATE.SS won't be set to 1 due to
kernel_active_single_step()=true. Then the PE transferes to the
'Active-pending' state when ERET and returns to the debugger by step
exception.

Before this patch:
==================
Entering kdb (current=0xffff3376039f0000, pid 1) on processor 0 due to Keyboard Entry
[0]kdb>

[0]kdb>
[0]kdb> bp write_sysrq_trigger
Instruction(i) BP #0 at 0xffffa45c13d09290 (write_sysrq_trigger)
    is enabled   addr at ffffa45c13d09290, hardtype=0 installed=0

[0]kdb> go
$ echo h > /proc/sysrq-trigger

Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to Breakpoint @ 0xffffad651a309290
[1]kdb> ss

Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294
[1]kdb> ss

Entering kdb (current=0xffff4f7e453f8000, pid 175) on processor 1 due to SS trap @ 0xffffad651a309294
[1]kdb>

After this patch:
=================
Entering kdb (current=0xffff6851c39f0000, pid 1) on processor 0 due to Keyboard Entry
[0]kdb> bp write_sysrq_trigger
Instruction(i) BP #0 at 0xffffc02d2dd09290 (write_sysrq_trigger)
    is enabled   addr at ffffc02d2dd09290, hardtype=0 installed=0

[0]kdb> go
$ echo h > /proc/sysrq-trigger

Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to Breakpoint @ 0xffffc02d2dd09290
[1]kdb> ss

Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09294
[1]kdb> ss

Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd09298
[1]kdb> ss

Entering kdb (current=0xffff6851c53c1840, pid 174) on processor 1 due to SS trap @ 0xffffc02d2dd0929c
[1]kdb>

Fixes: 44679a4f142b ("arm64: KGDB: Add step debugging support")
Co-developed-by: Wei Li <liwei391@huawei.com>
Signed-off-by: Wei Li <liwei391@huawei.com>
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>
Tested-by: Douglas Anderson <dianders@chromium.org>
Acked-by: Daniel Thompson <daniel.thompson@linaro.org>
Tested-by: Daniel Thompson <daniel.thompson@linaro.org>
---
 arch/arm64/include/asm/debug-monitors.h | 1 +
 arch/arm64/kernel/debug-monitors.c      | 5 +++++
 arch/arm64/kernel/kgdb.c                | 2 ++
 3 files changed, 8 insertions(+)

diff --git a/arch/arm64/include/asm/debug-monitors.h b/arch/arm64/include/asm/debug-monitors.h
index 7b7e05c02691..13d437bcbf58 100644
--- a/arch/arm64/include/asm/debug-monitors.h
+++ b/arch/arm64/include/asm/debug-monitors.h
@@ -104,6 +104,7 @@ void user_regs_reset_single_step(struct user_pt_regs *regs,
 void kernel_enable_single_step(struct pt_regs *regs);
 void kernel_disable_single_step(void);
 int kernel_active_single_step(void);
+void kernel_rewind_single_step(struct pt_regs *regs);
 
 #ifdef CONFIG_HAVE_HW_BREAKPOINT
 int reinstall_suspended_bps(struct pt_regs *regs);
diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index 3da09778267e..64f2ecbdfe5c 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -438,6 +438,11 @@ int kernel_active_single_step(void)
 }
 NOKPROBE_SYMBOL(kernel_active_single_step);
 
+void kernel_rewind_single_step(struct pt_regs *regs)
+{
+	set_regs_spsr_ss(regs);
+}
+
 /* ptrace API */
 void user_enable_single_step(struct task_struct *task)
 {
diff --git a/arch/arm64/kernel/kgdb.c b/arch/arm64/kernel/kgdb.c
index cda9c1e9864f..4e1f983df3d1 100644
--- a/arch/arm64/kernel/kgdb.c
+++ b/arch/arm64/kernel/kgdb.c
@@ -224,6 +224,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
 		 */
 		if (!kernel_active_single_step())
 			kernel_enable_single_step(linux_regs);
+		else
+			kernel_rewind_single_step(linux_regs);
 		err = 0;
 		break;
 	default:
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 0/2] arm64: Fix pending single-step debugging issues
  2023-02-02  7:31 [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
  2023-02-02  7:31 ` [PATCH v6 1/2] arm64: entry: Skip single stepping into interrupt handlers Sumit Garg
  2023-02-02  7:31 ` [PATCH v6 2/2] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step Sumit Garg
@ 2023-02-22  7:06 ` Sumit Garg
  2023-04-14 14:38 ` Will Deacon
  3 siblings, 0 replies; 5+ messages in thread
From: Sumit Garg @ 2023-02-22  7:06 UTC (permalink / raw)
  To: will
  Cc: catalin.marinas, mark.rutland, daniel.thompson, dianders,
	liwei391, mhiramat, maz, ardb, linux-arm-kernel, linux-kernel

Hi Will,

On Thu, 2 Feb 2023 at 13:02, Sumit Garg <sumit.garg@linaro.org> wrote:
>
> This patch-set reworks pending fixes from Wei's series [1] to make
> single-step debugging via kgdb/kdb on arm64 work as expected. There was
> a prior discussion on ML [2] regarding if we should keep the interrupts
> enabled during single-stepping. So patch #1 follows suggestion from Will
> [3] to not disable interrupts during single stepping but rather skip
> single stepping within interrupt handler.
>
> [1] https://lore.kernel.org/all/20200509214159.19680-1-liwei391@huawei.com/
> [2] https://lore.kernel.org/all/CAD=FV=Voyfq3Qz0T3RY+aYWYJ0utdH=P_AweB=13rcV8GDBeyQ@mail.gmail.com/
> [3] https://lore.kernel.org/all/20200626095551.GA9312@willie-the-truck/
>
> Changes in v6:
> - Fix incorrect rescheduling check introduced by rework for v5.
> - Patch #2: s/kernel_regs_reset_single_step/kernel_rewind_single_step/
> - Collected Daniel's tags.
>

Would you be happy to pick up patch #2 independently? Also, it would
be great if you can provide some guidance regarding patch #1 which
certainly fixes single stepping on arm64 but I am not sure how it
would have side-effects.

-Sumit

> Changes in v5:
> - Incorporated misc. comments from Mark.
>
> Changes in v4:
> - Rebased to the tip of mainline.
> - Picked up Doug's Tested-by tag.
>
> Changes in v3:
> - Reword commit descriptions as per Daniel's suggestions.
>
> Changes in v2:
> - Replace patch #1 to rather follow Will's suggestion.
>
> Sumit Garg (2):
>   arm64: entry: Skip single stepping into interrupt handlers
>   arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step
>
>  arch/arm64/include/asm/debug-monitors.h |  1 +
>  arch/arm64/kernel/debug-monitors.c      |  5 +++++
>  arch/arm64/kernel/entry-common.c        | 22 ++++++++++++++++++++--
>  arch/arm64/kernel/kgdb.c                |  2 ++
>  4 files changed, 28 insertions(+), 2 deletions(-)
>
> --
> 2.34.1
>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH v6 0/2] arm64: Fix pending single-step debugging issues
  2023-02-02  7:31 [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
                   ` (2 preceding siblings ...)
  2023-02-22  7:06 ` [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
@ 2023-04-14 14:38 ` Will Deacon
  3 siblings, 0 replies; 5+ messages in thread
From: Will Deacon @ 2023-04-14 14:38 UTC (permalink / raw)
  To: Sumit Garg, catalin.marinas
  Cc: kernel-team, Will Deacon, liwei391, mhiramat, linux-kernel,
	daniel.thompson, linux-arm-kernel, mark.rutland, ardb, dianders,
	maz

On Thu, 2 Feb 2023 13:01:46 +0530, Sumit Garg wrote:
> This patch-set reworks pending fixes from Wei's series [1] to make
> single-step debugging via kgdb/kdb on arm64 work as expected. There was
> a prior discussion on ML [2] regarding if we should keep the interrupts
> enabled during single-stepping. So patch #1 follows suggestion from Will
> [3] to not disable interrupts during single stepping but rather skip
> single stepping within interrupt handler.
> 
> [...]

Applied second patch to arm64 (for-next/misc), thanks!

[2/2] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step
      https://git.kernel.org/arm64/c/af6c0bd59f4f

Cheers,
-- 
Will

https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-04-14 14:42 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-02  7:31 [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
2023-02-02  7:31 ` [PATCH v6 1/2] arm64: entry: Skip single stepping into interrupt handlers Sumit Garg
2023-02-02  7:31 ` [PATCH v6 2/2] arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step Sumit Garg
2023-02-22  7:06 ` [PATCH v6 0/2] arm64: Fix pending single-step debugging issues Sumit Garg
2023-04-14 14:38 ` 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).