Skip to content

Commit d920eaa

Browse files
author
Russell King (Oracle)
committed
ARM: Fix kgdb breakpoint for Thumb2
The kgdb code needs to register an undef hook for the Thumb UDF instruction that will fault in order to be functional on Thumb2 platforms. Reported-by: Johannes Stezenbach <[email protected]> Tested-by: Johannes Stezenbach <[email protected]> Fixes: 5cbad0e ("kgdb: support for ARCH=arm") Signed-off-by: Russell King (Oracle) <[email protected]>
1 parent 9f80ccd commit d920eaa

File tree

1 file changed

+28
-8
lines changed

1 file changed

+28
-8
lines changed

arch/arm/kernel/kgdb.c

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct pt_regs *regs, unsigned int instr)
154154
return 0;
155155
}
156156

157-
static struct undef_hook kgdb_brkpt_hook = {
157+
static struct undef_hook kgdb_brkpt_arm_hook = {
158158
.instr_mask = 0xffffffff,
159159
.instr_val = KGDB_BREAKINST,
160-
.cpsr_mask = MODE_MASK,
160+
.cpsr_mask = PSR_T_BIT | MODE_MASK,
161161
.cpsr_val = SVC_MODE,
162162
.fn = kgdb_brk_fn
163163
};
164164

165-
static struct undef_hook kgdb_compiled_brkpt_hook = {
165+
static struct undef_hook kgdb_brkpt_thumb_hook = {
166+
.instr_mask = 0xffff,
167+
.instr_val = KGDB_BREAKINST & 0xffff,
168+
.cpsr_mask = PSR_T_BIT | MODE_MASK,
169+
.cpsr_val = PSR_T_BIT | SVC_MODE,
170+
.fn = kgdb_brk_fn
171+
};
172+
173+
static struct undef_hook kgdb_compiled_brkpt_arm_hook = {
166174
.instr_mask = 0xffffffff,
167175
.instr_val = KGDB_COMPILED_BREAK,
168-
.cpsr_mask = MODE_MASK,
176+
.cpsr_mask = PSR_T_BIT | MODE_MASK,
169177
.cpsr_val = SVC_MODE,
170178
.fn = kgdb_compiled_brk_fn
171179
};
172180

181+
static struct undef_hook kgdb_compiled_brkpt_thumb_hook = {
182+
.instr_mask = 0xffff,
183+
.instr_val = KGDB_COMPILED_BREAK & 0xffff,
184+
.cpsr_mask = PSR_T_BIT | MODE_MASK,
185+
.cpsr_val = PSR_T_BIT | SVC_MODE,
186+
.fn = kgdb_compiled_brk_fn
187+
};
188+
173189
static int __kgdb_notify(struct die_args *args, unsigned long cmd)
174190
{
175191
struct pt_regs *regs = args->regs;
@@ -210,8 +226,10 @@ int kgdb_arch_init(void)
210226
if (ret != 0)
211227
return ret;
212228

213-
register_undef_hook(&kgdb_brkpt_hook);
214-
register_undef_hook(&kgdb_compiled_brkpt_hook);
229+
register_undef_hook(&kgdb_brkpt_arm_hook);
230+
register_undef_hook(&kgdb_brkpt_thumb_hook);
231+
register_undef_hook(&kgdb_compiled_brkpt_arm_hook);
232+
register_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
215233

216234
return 0;
217235
}
@@ -224,8 +242,10 @@ int kgdb_arch_init(void)
224242
*/
225243
void kgdb_arch_exit(void)
226244
{
227-
unregister_undef_hook(&kgdb_brkpt_hook);
228-
unregister_undef_hook(&kgdb_compiled_brkpt_hook);
245+
unregister_undef_hook(&kgdb_brkpt_arm_hook);
246+
unregister_undef_hook(&kgdb_brkpt_thumb_hook);
247+
unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook);
248+
unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook);
229249
unregister_die_notifier(&kgdb_notifier);
230250
}
231251

0 commit comments

Comments
 (0)