From 08bcbfbf7c003c884dcb3f53a4fa14347be75a58 Mon Sep 17 00:00:00 2001 From: Mark Salyzyn Date: Mon, 24 Feb 2020 15:02:45 -0800 Subject: [PATCH] ANDROID: GKI: arm64: fault: do_tlb_conf_fault_cb register fault callback Allow for vendor components or modules to override "TLB conflict abort" handler, Signed-off-by: Mark Salyzyn Test: Verified with scripts/gki/device_snapshot Test: No impact on /sys/ (except new module files) and /dev/ Test: All devices probed as before Bug: 141888626 Change-Id: I7d0a4d7440412f2ffc611fe597d5d39d18a2a03a (cherry picked from commit 75c07a4fbd301fbff1522e66996bad91617cd06f) Bug: 149990629 --- arch/arm64/include/asm/traps.h | 8 ++++++++ arch/arm64/mm/fault.c | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/traps.h b/arch/arm64/include/asm/traps.h index c320f3bf6c57..8c64bf7d2387 100644 --- a/arch/arm64/include/asm/traps.h +++ b/arch/arm64/include/asm/traps.h @@ -120,4 +120,12 @@ static inline u32 arm64_ras_serror_get_severity(u32 esr) bool arm64_is_fatal_ras_serror(struct pt_regs *regs, unsigned int esr); void __noreturn arm64_serror_panic(struct pt_regs *regs, u32 esr); + +extern int (*do_tlb_conf_fault_cb)(unsigned long addr, + unsigned int esr, + struct pt_regs *regs); +extern int do_tlb_conf_fault(unsigned long addr, + unsigned int esr, + struct pt_regs *regs); + #endif diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index fe6eca4ca4de..d44543c445d3 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -613,6 +613,26 @@ no_context: return 0; } +int __weak do_tlb_conf_fault(unsigned long addr, + unsigned int esr, + struct pt_regs *regs) +{ + return 1; /* do_bad default */ +} + +int (*do_tlb_conf_fault_cb)(unsigned long addr, + unsigned int esr, + struct pt_regs *regs) + = do_tlb_conf_fault; /* initialization saves us a branch */ +EXPORT_SYMBOL_GPL(do_tlb_conf_fault_cb); + +static int _do_tlb_conf_fault(unsigned long addr, + unsigned int esr, + struct pt_regs *regs) +{ + return (*do_tlb_conf_fault_cb)(addr, esr, regs); +} + static int __kprobes do_translation_fault(unsigned long addr, unsigned int esr, struct pt_regs *regs) @@ -720,7 +740,7 @@ static const struct fault_info fault_info[] = { { do_bad, SIGKILL, SI_KERNEL, "unknown 45" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 46" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 47" }, - { do_bad, SIGKILL, SI_KERNEL, "TLB conflict abort" }, + { _do_tlb_conf_fault, SIGKILL, SI_KERNEL, "TLB conflict abort" }, { do_bad, SIGKILL, SI_KERNEL, "Unsupported atomic hardware update fault" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 50" }, { do_bad, SIGKILL, SI_KERNEL, "unknown 51" },