| From d920eaa4c4559f59be7b4c2d26fa0a2e1aaa3da9 Mon Sep 17 00:00:00 2001 |
| From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk> |
| Date: Wed, 16 Feb 2022 15:37:38 +0000 |
| Subject: ARM: Fix kgdb breakpoint for Thumb2 |
| |
| From: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
| |
| commit d920eaa4c4559f59be7b4c2d26fa0a2e1aaa3da9 upstream. |
| |
| 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 <js@sig21.net> |
| Tested-by: Johannes Stezenbach <js@sig21.net> |
| Fixes: 5cbad0ebf45c ("kgdb: support for ARCH=arm") |
| Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/arm/kernel/kgdb.c | 36 ++++++++++++++++++++++++++++-------- |
| 1 file changed, 28 insertions(+), 8 deletions(-) |
| |
| --- a/arch/arm/kernel/kgdb.c |
| +++ b/arch/arm/kernel/kgdb.c |
| @@ -154,22 +154,38 @@ static int kgdb_compiled_brk_fn(struct p |
| return 0; |
| } |
| |
| -static struct undef_hook kgdb_brkpt_hook = { |
| +static struct undef_hook kgdb_brkpt_arm_hook = { |
| .instr_mask = 0xffffffff, |
| .instr_val = KGDB_BREAKINST, |
| - .cpsr_mask = MODE_MASK, |
| + .cpsr_mask = PSR_T_BIT | MODE_MASK, |
| .cpsr_val = SVC_MODE, |
| .fn = kgdb_brk_fn |
| }; |
| |
| -static struct undef_hook kgdb_compiled_brkpt_hook = { |
| +static struct undef_hook kgdb_brkpt_thumb_hook = { |
| + .instr_mask = 0xffff, |
| + .instr_val = KGDB_BREAKINST & 0xffff, |
| + .cpsr_mask = PSR_T_BIT | MODE_MASK, |
| + .cpsr_val = PSR_T_BIT | SVC_MODE, |
| + .fn = kgdb_brk_fn |
| +}; |
| + |
| +static struct undef_hook kgdb_compiled_brkpt_arm_hook = { |
| .instr_mask = 0xffffffff, |
| .instr_val = KGDB_COMPILED_BREAK, |
| - .cpsr_mask = MODE_MASK, |
| + .cpsr_mask = PSR_T_BIT | MODE_MASK, |
| .cpsr_val = SVC_MODE, |
| .fn = kgdb_compiled_brk_fn |
| }; |
| |
| +static struct undef_hook kgdb_compiled_brkpt_thumb_hook = { |
| + .instr_mask = 0xffff, |
| + .instr_val = KGDB_COMPILED_BREAK & 0xffff, |
| + .cpsr_mask = PSR_T_BIT | MODE_MASK, |
| + .cpsr_val = PSR_T_BIT | SVC_MODE, |
| + .fn = kgdb_compiled_brk_fn |
| +}; |
| + |
| static int __kgdb_notify(struct die_args *args, unsigned long cmd) |
| { |
| struct pt_regs *regs = args->regs; |
| @@ -210,8 +226,10 @@ int kgdb_arch_init(void) |
| if (ret != 0) |
| return ret; |
| |
| - register_undef_hook(&kgdb_brkpt_hook); |
| - register_undef_hook(&kgdb_compiled_brkpt_hook); |
| + register_undef_hook(&kgdb_brkpt_arm_hook); |
| + register_undef_hook(&kgdb_brkpt_thumb_hook); |
| + register_undef_hook(&kgdb_compiled_brkpt_arm_hook); |
| + register_undef_hook(&kgdb_compiled_brkpt_thumb_hook); |
| |
| return 0; |
| } |
| @@ -224,8 +242,10 @@ int kgdb_arch_init(void) |
| */ |
| void kgdb_arch_exit(void) |
| { |
| - unregister_undef_hook(&kgdb_brkpt_hook); |
| - unregister_undef_hook(&kgdb_compiled_brkpt_hook); |
| + unregister_undef_hook(&kgdb_brkpt_arm_hook); |
| + unregister_undef_hook(&kgdb_brkpt_thumb_hook); |
| + unregister_undef_hook(&kgdb_compiled_brkpt_arm_hook); |
| + unregister_undef_hook(&kgdb_compiled_brkpt_thumb_hook); |
| unregister_die_notifier(&kgdb_notifier); |
| } |
| |