Skip to content

Commit 44679a4

Browse files
Vijaya Kumar Kctmarinas
authored andcommitted
arm64: KGDB: Add step debugging support
Add KGDB software step debugging support for EL1 debug in AArch64 mode. KGDB registers step debug handler with debug monitor. On receiving 'step' command from GDB tool, target enables software step debugging and step address is updated in ELR. Software Step debugging is disabled when 'continue' command is received Signed-off-by: Vijaya Kumar K <Vijaya.Kumar@caviumnetworks.com> Reviewed-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
1 parent bcf5763 commit 44679a4

File tree

1 file changed

+56
-8
lines changed

1 file changed

+56
-8
lines changed

arch/arm64/kernel/kgdb.c

Lines changed: 56 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,26 @@ void kgdb_arch_set_pc(struct pt_regs *regs, unsigned long pc)
137137

138138
static int compiled_break;
139139

140+
static void kgdb_arch_update_addr(struct pt_regs *regs,
141+
char *remcom_in_buffer)
142+
{
143+
unsigned long addr;
144+
char *ptr;
145+
146+
ptr = &remcom_in_buffer[1];
147+
if (kgdb_hex2long(&ptr, &addr))
148+
kgdb_arch_set_pc(regs, addr);
149+
else if (compiled_break == 1)
150+
kgdb_arch_set_pc(regs, regs->pc + 4);
151+
152+
compiled_break = 0;
153+
}
154+
140155
int kgdb_arch_handle_exception(int exception_vector, int signo,
141156
int err_code, char *remcom_in_buffer,
142157
char *remcom_out_buffer,
143158
struct pt_regs *linux_regs)
144159
{
145-
unsigned long addr;
146-
char *ptr;
147160
int err;
148161

149162
switch (remcom_in_buffer[0]) {
@@ -162,13 +175,36 @@ int kgdb_arch_handle_exception(int exception_vector, int signo,
162175
* to the next instruction else we will just breakpoint
163176
* over and over again.
164177
*/
165-
ptr = &remcom_in_buffer[1];
166-
if (kgdb_hex2long(&ptr, &addr))
167-
kgdb_arch_set_pc(linux_regs, addr);
168-
else if (compiled_break == 1)
169-
kgdb_arch_set_pc(linux_regs, linux_regs->pc + 4);
178+
kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
179+
atomic_set(&kgdb_cpu_doing_single_step, -1);
180+
kgdb_single_step = 0;
181+
182+
/*
183+
* Received continue command, disable single step
184+
*/
185+
if (kernel_active_single_step())
186+
kernel_disable_single_step();
187+
188+
err = 0;
189+
break;
190+
case 's':
191+
/*
192+
* Update step address value with address passed
193+
* with step packet.
194+
* On debug exception return PC is copied to ELR
195+
* So just update PC.
196+
* If no step address is passed, resume from the address
197+
* pointed by PC. Do not update PC
198+
*/
199+
kgdb_arch_update_addr(linux_regs, remcom_in_buffer);
200+
atomic_set(&kgdb_cpu_doing_single_step, raw_smp_processor_id());
201+
kgdb_single_step = 1;
170202

171-
compiled_break = 0;
203+
/*
204+
* Enable single step handling
205+
*/
206+
if (!kernel_active_single_step())
207+
kernel_enable_single_step(linux_regs);
172208
err = 0;
173209
break;
174210
default:
@@ -191,6 +227,12 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int esr)
191227
return 0;
192228
}
193229

230+
static int kgdb_step_brk_fn(struct pt_regs *regs, unsigned int esr)
231+
{
232+
kgdb_handle_exception(1, SIGTRAP, 0, regs);
233+
return 0;
234+
}
235+
194236
static struct break_hook kgdb_brkpt_hook = {
195237
.esr_mask = 0xffffffff,
196238
.esr_val = DBG_ESR_VAL_BRK(KGDB_DYN_DGB_BRK_IMM),
@@ -203,6 +245,10 @@ static struct break_hook kgdb_compiled_brkpt_hook = {
203245
.fn = kgdb_compiled_brk_fn
204246
};
205247

248+
static struct step_hook kgdb_step_hook = {
249+
.fn = kgdb_step_brk_fn
250+
};
251+
206252
static void kgdb_call_nmi_hook(void *ignored)
207253
{
208254
kgdb_nmicallback(raw_smp_processor_id(), get_irq_regs());
@@ -259,6 +305,7 @@ int kgdb_arch_init(void)
259305

260306
register_break_hook(&kgdb_brkpt_hook);
261307
register_break_hook(&kgdb_compiled_brkpt_hook);
308+
register_step_hook(&kgdb_step_hook);
262309
return 0;
263310
}
264311

@@ -271,6 +318,7 @@ void kgdb_arch_exit(void)
271318
{
272319
unregister_break_hook(&kgdb_brkpt_hook);
273320
unregister_break_hook(&kgdb_compiled_brkpt_hook);
321+
unregister_step_hook(&kgdb_step_hook);
274322
unregister_die_notifier(&kgdb_notifier);
275323
}
276324

0 commit comments

Comments
 (0)