Skip to content

Commit af6c0bd

Browse files
b49020willdeacon
authored andcommitted
arm64: kgdb: Set PSTATE.SS to 1 to re-enable single-step
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: 44679a4 ("arm64: KGDB: Add step debugging support") Co-developed-by: Wei Li <[email protected]> Signed-off-by: Wei Li <[email protected]> Signed-off-by: Sumit Garg <[email protected]> Tested-by: Douglas Anderson <[email protected]> Acked-by: Daniel Thompson <[email protected]> Tested-by: Daniel Thompson <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 97b5576 commit af6c0bd

File tree

3 files changed

+8
-0
lines changed

3 files changed

+8
-0
lines changed

arch/arm64/include/asm/debug-monitors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ void user_regs_reset_single_step(struct user_pt_regs *regs,
104104
void kernel_enable_single_step(struct pt_regs *regs);
105105
void kernel_disable_single_step(void);
106106
int kernel_active_single_step(void);
107+
void kernel_rewind_single_step(struct pt_regs *regs);
107108

108109
#ifdef CONFIG_HAVE_HW_BREAKPOINT
109110
int reinstall_suspended_bps(struct pt_regs *regs);

arch/arm64/kernel/debug-monitors.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,11 @@ int kernel_active_single_step(void)
438438
}
439439
NOKPROBE_SYMBOL(kernel_active_single_step);
440440

441+
void kernel_rewind_single_step(struct pt_regs *regs)
442+
{
443+
set_regs_spsr_ss(regs);
444+
}
445+
441446
/* ptrace API */
442447
void user_enable_single_step(struct task_struct *task)
443448
{

arch/arm64/kernel/kgdb.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,8 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
224224
*/
225225
if (!kernel_active_single_step())
226226
kernel_enable_single_step(linux_regs);
227+
else
228+
kernel_rewind_single_step(linux_regs);
227229
err = 0;
228230
break;
229231
default:

0 commit comments

Comments
 (0)