Skip to content

Commit 7be02db

Browse files
committed
arm64: debug: split bkpt32 exception entry
JIRA: https://issues.redhat.com/browse/RHEL-65658 commit fc5e5d0 Author: Ada Couprie Diaz <ada.coupriediaz@arm.com> Date: Mon Jul 7 12:41:08 2025 +0100 arm64: debug: split bkpt32 exception entry Currently all debug exceptions share common entry code and are routed to `do_debug_exception()`, which calls dynamically-registered handlers for each specific debug exception. This is unfortunate as different debug exceptions have different entry handling requirements, and it would be better to handle these distinct requirements earlier. The BKPT32 exception can only be triggered by a BKPT instruction. Thus, we know that the PC is a legitimate address and isn't being used to train a branch predictor with a bogus address : we don't need to call `arm64_apply_bp_hardening()`. The handler for this exception only pends a signal and doesn't depend on any per-CPU state : we don't need to inhibit preemption, nor do we need to keep the DAIF exceptions masked, so we can unmask them earlier. Split the BKPT32 exception entry and adjust function signatures and its behaviour to match its relaxed constraints compared to other debug exceptions. We can also remove `NOKRPOBE_SYMBOL`, as this cannot lead to a kprobe recursion. This replaces the last usage of `el0_dbg()`, so remove it. Signed-off-by: Ada Couprie Diaz <ada.coupriediaz@arm.com> Tested-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Reviewed-by: Will Deacon <will@kernel.org> Acked-by: Mark Rutland <mark.rutland@arm.com> Link: https://lore.kernel.org/r/20250707114109.35672-13-ada.coupriediaz@arm.com Signed-off-by: Will Deacon <will@kernel.org> Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com>
1 parent 68c5786 commit 7be02db

File tree

3 files changed

+17
-13
lines changed

3 files changed

+17
-13
lines changed

arch/arm64/include/asm/exception.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void do_el0_softstep(unsigned long esr, struct pt_regs *regs);
7272
void do_el1_softstep(unsigned long esr, struct pt_regs *regs);
7373
void do_el0_brk64(unsigned long esr, struct pt_regs *regs);
7474
void do_el1_brk64(unsigned long esr, struct pt_regs *regs);
75+
void do_bkpt32(unsigned long esr, struct pt_regs *regs);
7576
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs);
7677
void do_sve_acc(unsigned long esr, struct pt_regs *regs);
7778
void do_sme_acc(unsigned long esr, struct pt_regs *regs);

arch/arm64/kernel/debug-monitors.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,13 @@ void do_el1_brk64(unsigned long esr, struct pt_regs *regs)
267267
}
268268
NOKPROBE_SYMBOL(do_el1_brk64);
269269

270+
#ifdef CONFIG_COMPAT
271+
void do_bkpt32(unsigned long esr, struct pt_regs *regs)
272+
{
273+
arm64_notify_die("aarch32 BKPT", regs, SIGTRAP, TRAP_BRKPT, regs->pc, esr);
274+
}
275+
#endif /* CONFIG_COMPAT */
276+
270277
bool try_handle_aarch32_break(struct pt_regs *regs)
271278
{
272279
u32 arm_instr;

arch/arm64/kernel/entry-common.c

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -811,18 +811,6 @@ static void noinstr el0_brk64(struct pt_regs *regs, unsigned long esr)
811811
exit_to_user_mode(regs);
812812
}
813813

814-
static void noinstr __maybe_unused
815-
el0_dbg(struct pt_regs *regs, unsigned long esr)
816-
{
817-
/* Only watchpoints write FAR_EL1, otherwise its UNKNOWN */
818-
unsigned long far = read_sysreg(far_el1);
819-
820-
enter_from_user_mode(regs);
821-
do_debug_exception(far, esr, regs);
822-
local_daif_restore(DAIF_PROCCTX);
823-
exit_to_user_mode(regs);
824-
}
825-
826814
static void noinstr el0_svc(struct pt_regs *regs)
827815
{
828816
enter_from_user_mode(regs);
@@ -979,6 +967,14 @@ static void noinstr el0_svc_compat(struct pt_regs *regs)
979967
exit_to_user_mode(regs);
980968
}
981969

970+
static void noinstr el0_bkpt32(struct pt_regs *regs, unsigned long esr)
971+
{
972+
enter_from_user_mode(regs);
973+
local_daif_restore(DAIF_PROCCTX);
974+
do_bkpt32(esr, regs);
975+
exit_to_user_mode(regs);
976+
}
977+
982978
asmlinkage void noinstr el0t_32_sync_handler(struct pt_regs *regs)
983979
{
984980
unsigned long esr = read_sysreg(esr_el1);
@@ -1022,7 +1018,7 @@ asmlinkage void noinstr el0t_32_sync_handler(struct pt_regs *regs)
10221018
el0_watchpt(regs, esr);
10231019
break;
10241020
case ESR_ELx_EC_BKPT32:
1025-
el0_dbg(regs, esr);
1021+
el0_bkpt32(regs, esr);
10261022
break;
10271023
default:
10281024
el0_inv(regs, esr);

0 commit comments

Comments
 (0)