aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/mm/fault.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/mm/fault.c')
-rw-r--r--arch/arm64/mm/fault.c38
1 files changed, 36 insertions, 2 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 0cb0e09995e1..a30818ed9c60 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -171,9 +171,10 @@ static void show_pte(unsigned long addr)
171 return; 171 return;
172 } 172 }
173 173
174 pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp = %p\n", 174 pr_alert("%s pgtable: %luk pages, %u-bit VAs, pgdp=%016lx\n",
175 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, 175 mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K,
176 mm == &init_mm ? VA_BITS : (int) vabits_user, mm->pgd); 176 mm == &init_mm ? VA_BITS : (int)vabits_user,
177 (unsigned long)virt_to_phys(mm->pgd));
177 pgdp = pgd_offset(mm, addr); 178 pgdp = pgd_offset(mm, addr);
178 pgd = READ_ONCE(*pgdp); 179 pgd = READ_ONCE(*pgdp);
179 pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd)); 180 pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd));
@@ -810,6 +811,36 @@ void __init hook_debug_fault_code(int nr,
810 debug_fault_info[nr].name = name; 811 debug_fault_info[nr].name = name;
811} 812}
812 813
814#ifdef CONFIG_ARM64_ERRATUM_1463225
815DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
816
817static int __exception
818cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
819{
820 if (user_mode(regs))
821 return 0;
822
823 if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa))
824 return 0;
825
826 /*
827 * We've taken a dummy step exception from the kernel to ensure
828 * that interrupts are re-enabled on the syscall path. Return back
829 * to cortex_a76_erratum_1463225_svc_handler() with debug exceptions
830 * masked so that we can safely restore the mdscr and get on with
831 * handling the syscall.
832 */
833 regs->pstate |= PSR_D_BIT;
834 return 1;
835}
836#else
837static int __exception
838cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs)
839{
840 return 0;
841}
842#endif /* CONFIG_ARM64_ERRATUM_1463225 */
843
813asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint, 844asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
814 unsigned int esr, 845 unsigned int esr,
815 struct pt_regs *regs) 846 struct pt_regs *regs)
@@ -817,6 +848,9 @@ asmlinkage void __exception do_debug_exception(unsigned long addr_if_watchpoint,
817 const struct fault_info *inf = esr_to_debug_fault_info(esr); 848 const struct fault_info *inf = esr_to_debug_fault_info(esr);
818 unsigned long pc = instruction_pointer(regs); 849 unsigned long pc = instruction_pointer(regs);
819 850
851 if (cortex_a76_erratum_1463225_debug_handler(regs))
852 return;
853
820 /* 854 /*
821 * Tell lockdep we disabled irqs in entry.S. Do nothing if they were 855 * Tell lockdep we disabled irqs in entry.S. Do nothing if they were
822 * already disabled to preserve the last enabled/disabled addresses. 856 * already disabled to preserve the last enabled/disabled addresses.