Skip to content

Commit 00470c1

Browse files
committed
Merge: arm64: debug: remove hook registration, split exception entry
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-10/-/merge_requests/1350 JIRA: https://issues.redhat.com/browse/RHEL-69599 CONFLICTS: minor conflict, more context than functionality, as RHEL-10 does not have commit d683a85 ("ubsan: Remove regs from report_ubsan_failure()") This series simplifies the debug exception entry path by removing handler registration mechanisms for the debug exception handlers, a holdover from the arm kernel, as well as the break and stepping handlers. This moves much of the code related to debug exceptions outside of `mm/fault.c` where it didn't make much sense. This allows us to split the debug exception entries: going from one common path per EL for all debug exceptions to a unique one per exception and EL. The result is a much simpler and fully static exception entry path, which we tailor to the different exceptions and their constraints. ... Original cover letter and testing procedure can be found here: arm64: debug: remove hook registration, split exception entry (v6) https://lore.kernel.org/linux-arm-kernel/20250707114109.35672-1-ada.coupriediaz@arm.com/ These are the upstream commits backported for this MR: ad8b226 arm64: debug: clean up single_step_handler logic b1e2d95 arm64: refactor aarch32_break_handler() dc1fd37 arm64: Introduce esr_is_ubsan_brk() 6adfdc5 arm64: debug: call software breakpoint handlers statically 403b48a arm64: debug: call step handlers statically d4e0b12 arm64: debug: remove break/step handler registration infrastructure 398edaa arm64/fpsimd: Do not discard modified SVE state eaff68b arm64: entry: Add entry and exit functions for debug exceptions 43e2ae7 arm64: debug: split hardware breakpoint exception entry 80691d3 arm64: debug: refactor reinstall_suspended_bps() 0ac7584 arm64: debug: split single stepping exception entry 413f0bb arm64: debug: split hardware watchpoint exception entry 31575e1 arm64: debug: split brk64 exception entry fc5e5d0 arm64: debug: split bkpt32 exception entry a8b8cce arm64: debug: remove debug exception registration infrastructure Special note goes for commit dc1fd37 that was added to fix a minor context conflict and commit 398edaa that is both required context and a fix. Signed-off-by: Luis Claudio R. Goncalves <lgoncalv@redhat.com> Approved-by: Gabriele Monaco <gmonaco@redhat.com> Approved-by: Rafael Aquini <raquini@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Scott Weaver <scweaver@redhat.com>
2 parents bbca8b6 + 08c83ee commit 00470c1

File tree

19 files changed

+377
-479
lines changed

19 files changed

+377
-479
lines changed

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

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,30 +62,6 @@ struct task_struct;
6262
#define DBG_HOOK_HANDLED 0
6363
#define DBG_HOOK_ERROR 1
6464

65-
struct step_hook {
66-
struct list_head node;
67-
int (*fn)(struct pt_regs *regs, unsigned long esr);
68-
};
69-
70-
void register_user_step_hook(struct step_hook *hook);
71-
void unregister_user_step_hook(struct step_hook *hook);
72-
73-
void register_kernel_step_hook(struct step_hook *hook);
74-
void unregister_kernel_step_hook(struct step_hook *hook);
75-
76-
struct break_hook {
77-
struct list_head node;
78-
int (*fn)(struct pt_regs *regs, unsigned long esr);
79-
u16 imm;
80-
u16 mask; /* These bits are ignored when comparing with imm */
81-
};
82-
83-
void register_user_break_hook(struct break_hook *hook);
84-
void unregister_user_break_hook(struct break_hook *hook);
85-
86-
void register_kernel_break_hook(struct break_hook *hook);
87-
void unregister_kernel_break_hook(struct break_hook *hook);
88-
8965
u8 debug_monitors_arch(void);
9066

9167
enum dbg_active_el {
@@ -108,17 +84,15 @@ void kernel_rewind_single_step(struct pt_regs *regs);
10884
void kernel_fastforward_single_step(struct pt_regs *regs);
10985

11086
#ifdef CONFIG_HAVE_HW_BREAKPOINT
111-
int reinstall_suspended_bps(struct pt_regs *regs);
87+
bool try_step_suspended_breakpoints(struct pt_regs *regs);
11288
#else
113-
static inline int reinstall_suspended_bps(struct pt_regs *regs)
89+
static inline bool try_step_suspended_breakpoints(struct pt_regs *regs)
11490
{
115-
return -ENODEV;
91+
return false;
11692
}
11793
#endif
11894

119-
int aarch32_break_handler(struct pt_regs *regs);
120-
121-
void debug_traps_init(void);
95+
bool try_handle_aarch32_break(struct pt_regs *regs);
12296

12397
#endif /* __ASSEMBLY */
12498
#endif /* __ASM_DEBUG_MONITORS_H */

arch/arm64/include/asm/esr.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,11 @@ static inline bool esr_is_cfi_brk(unsigned long esr)
440440
(esr_brk_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE;
441441
}
442442

443+
static inline bool esr_is_ubsan_brk(unsigned long esr)
444+
{
445+
return (esr_brk_comment(esr) & ~UBSAN_BRK_MASK) == UBSAN_BRK_IMM;
446+
}
447+
443448
static inline bool esr_fsc_is_translation_fault(unsigned long esr)
444449
{
445450
esr = esr & ESR_ELx_FSC;

arch/arm64/include/asm/exception.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,20 @@ void do_el0_bti(struct pt_regs *regs);
5959
void do_el1_bti(struct pt_regs *regs, unsigned long esr);
6060
void do_el0_gcs(struct pt_regs *regs, unsigned long esr);
6161
void do_el1_gcs(struct pt_regs *regs, unsigned long esr);
62-
void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr,
62+
#ifdef CONFIG_HAVE_HW_BREAKPOINT
63+
void do_breakpoint(unsigned long esr, struct pt_regs *regs);
64+
void do_watchpoint(unsigned long addr, unsigned long esr,
6365
struct pt_regs *regs);
66+
#else
67+
static inline void do_breakpoint(unsigned long esr, struct pt_regs *regs) {}
68+
static inline void do_watchpoint(unsigned long addr, unsigned long esr,
69+
struct pt_regs *regs) {}
70+
#endif /* CONFIG_HAVE_HW_BREAKPOINT */
71+
void do_el0_softstep(unsigned long esr, struct pt_regs *regs);
72+
void do_el1_softstep(unsigned long esr, struct pt_regs *regs);
73+
void do_el0_brk64(unsigned long esr, struct pt_regs *regs);
74+
void do_el1_brk64(unsigned long esr, struct pt_regs *regs);
75+
void do_bkpt32(unsigned long esr, struct pt_regs *regs);
6476
void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs);
6577
void do_sve_acc(unsigned long esr, struct pt_regs *regs);
6678
void do_sme_acc(unsigned long esr, struct pt_regs *regs);

arch/arm64/include/asm/fpsimd.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#define __ASM_FP_H
77

88
#include <asm/errno.h>
9+
#include <asm/percpu.h>
910
#include <asm/ptrace.h>
1011
#include <asm/processor.h>
1112
#include <asm/sigcontext.h>
@@ -94,6 +95,8 @@ struct cpu_fp_state {
9495
enum fp_type to_save;
9596
};
9697

98+
DECLARE_PER_CPU(struct cpu_fp_state, fpsimd_last_state);
99+
97100
extern void fpsimd_bind_state_to_cpu(struct cpu_fp_state *fp_state);
98101

99102
extern void fpsimd_flush_task_state(struct task_struct *target);

arch/arm64/include/asm/kgdb.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,18 @@ static inline void arch_kgdb_breakpoint(void)
2424
extern void kgdb_handle_bus_error(void);
2525
extern int kgdb_fault_expected;
2626

27+
int kgdb_brk_handler(struct pt_regs *regs, unsigned long esr);
28+
int kgdb_compiled_brk_handler(struct pt_regs *regs, unsigned long esr);
29+
#ifdef CONFIG_KGDB
30+
int kgdb_single_step_handler(struct pt_regs *regs, unsigned long esr);
31+
#else
32+
static inline int kgdb_single_step_handler(struct pt_regs *regs,
33+
unsigned long esr)
34+
{
35+
return DBG_HOOK_ERROR;
36+
}
37+
#endif
38+
2739
#endif /* !__ASSEMBLY__ */
2840

2941
/*

arch/arm64/include/asm/kprobes.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,12 @@ void __kretprobe_trampoline(void);
4141
void __kprobes *trampoline_probe_handler(struct pt_regs *regs);
4242

4343
#endif /* CONFIG_KPROBES */
44+
45+
int __kprobes kprobe_brk_handler(struct pt_regs *regs,
46+
unsigned long esr);
47+
int __kprobes kprobe_ss_brk_handler(struct pt_regs *regs,
48+
unsigned long esr);
49+
int __kprobes kretprobe_brk_handler(struct pt_regs *regs,
50+
unsigned long esr);
51+
4452
#endif /* _ARM_KPROBES_H */

arch/arm64/include/asm/system_misc.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,6 @@ void arm64_notify_die(const char *str, struct pt_regs *regs,
2525
int signo, int sicode, unsigned long far,
2626
unsigned long err);
2727

28-
void hook_debug_fault_code(int nr, int (*fn)(unsigned long, unsigned long,
29-
struct pt_regs *),
30-
int sig, int code, const char *name);
31-
3228
struct mm_struct;
3329
extern void __show_regs(struct pt_regs *);
3430

arch/arm64/include/asm/traps.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ void arm64_force_sig_fault_pkey(unsigned long far, const char *str, int pkey);
2929
void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str);
3030
void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str);
3131

32+
int bug_brk_handler(struct pt_regs *regs, unsigned long esr);
33+
int cfi_brk_handler(struct pt_regs *regs, unsigned long esr);
34+
int reserved_fault_brk_handler(struct pt_regs *regs, unsigned long esr);
35+
int kasan_brk_handler(struct pt_regs *regs, unsigned long esr);
36+
int ubsan_brk_handler(struct pt_regs *regs, unsigned long esr);
37+
3238
int early_brk64(unsigned long addr, unsigned long esr, struct pt_regs *regs);
3339

3440
/*

arch/arm64/include/asm/uprobes.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,15 @@ struct arch_uprobe {
2828
bool simulate;
2929
};
3030

31+
int uprobe_brk_handler(struct pt_regs *regs, unsigned long esr);
32+
#ifdef CONFIG_UPROBES
33+
int uprobe_single_step_handler(struct pt_regs *regs, unsigned long esr);
34+
#else
35+
static inline int uprobe_single_step_handler(struct pt_regs *regs,
36+
unsigned long esr)
37+
{
38+
return DBG_HOOK_ERROR;
39+
}
40+
#endif
41+
3142
#endif

0 commit comments

Comments
 (0)