diff options
Diffstat (limited to 'arch/arm64/kernel/suspend.c')
-rw-r--r-- | arch/arm64/kernel/suspend.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c index 491acebf64a6..7f1235099361 100644 --- a/arch/arm64/kernel/suspend.c +++ b/arch/arm64/kernel/suspend.c @@ -32,6 +32,22 @@ void __cpu_suspend_save(struct cpu_suspend_ctx *ptr, u64 *save_ptr) __flush_dcache_area(save_ptr, sizeof(*save_ptr)); } +/* + * This hook is provided so that cpu_suspend code can restore HW + * breakpoints as early as possible in the resume path, before reenabling + * debug exceptions. Code cannot be run from a CPU PM notifier since by the + * time the notifier runs debug exceptions might have been enabled already, + * with HW breakpoints registers content still in an unknown state. + */ +void (*hw_breakpoint_restore)(void *); +void __init cpu_suspend_set_dbg_restorer(void (*hw_bp_restore)(void *)) +{ + /* Prevent multiple restore hook initializations */ + if (WARN_ON(hw_breakpoint_restore)) + return; + hw_breakpoint_restore = hw_bp_restore; +} + /** * cpu_suspend * @@ -53,6 +69,13 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) if (ret == 0) { cpu_switch_mm(mm->pgd, mm); flush_tlb_all(); + /* + * Restore HW breakpoint registers to sane values + * before debug exceptions are possibly reenabled + * through local_dbg_restore. + */ + if (hw_breakpoint_restore) + hw_breakpoint_restore(NULL); } return ret; |