diff options
author | Will Deacon | 2019-04-29 14:03:57 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2019-05-31 15:46:03 +0200 |
commit | 2eefb4a3894ef33a92615cfb6f391025d245b550 (patch) | |
tree | d7127d0e213a237170774b57c2a5d88c8e55f7ee /arch/arm64/mm | |
parent | brcmfmac: add subtype check for event handling in data path (diff) | |
download | kernel-qcow2-linux-2eefb4a3894ef33a92615cfb6f391025d245b550.tar.gz kernel-qcow2-linux-2eefb4a3894ef33a92615cfb6f391025d245b550.tar.xz kernel-qcow2-linux-2eefb4a3894ef33a92615cfb6f391025d245b550.zip |
arm64: errata: Add workaround for Cortex-A76 erratum #1463225
commit 969f5ea627570e91c9d54403287ee3ed657f58fe upstream.
Revisions of the Cortex-A76 CPU prior to r4p0 are affected by an erratum
that can prevent interrupts from being taken when single-stepping.
This patch implements a software workaround to prevent userspace from
effectively being able to disable interrupts.
Cc: <stable@vger.kernel.org>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch/arm64/mm')
-rw-r--r-- | arch/arm64/mm/fault.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index a4c134677285..88cf0a0cb616 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -827,14 +827,47 @@ void __init hook_debug_fault_code(int nr, debug_fault_info[nr].name = name; } +#ifdef CONFIG_ARM64_ERRATUM_1463225 +DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa); + +static int __exception +cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) +{ + if (user_mode(regs)) + return 0; + + if (!__this_cpu_read(__in_cortex_a76_erratum_1463225_wa)) + return 0; + + /* + * We've taken a dummy step exception from the kernel to ensure + * that interrupts are re-enabled on the syscall path. Return back + * to cortex_a76_erratum_1463225_svc_handler() with debug exceptions + * masked so that we can safely restore the mdscr and get on with + * handling the syscall. + */ + regs->pstate |= PSR_D_BIT; + return 1; +} +#else +static int __exception +cortex_a76_erratum_1463225_debug_handler(struct pt_regs *regs) +{ + return 0; +} +#endif /* CONFIG_ARM64_ERRATUM_1463225 */ + asmlinkage int __exception do_debug_exception(unsigned long addr_if_watchpoint, - unsigned int esr, - struct pt_regs *regs) + unsigned int esr, + struct pt_regs *regs) { const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr); unsigned long pc = instruction_pointer(regs); int rv; + if (cortex_a76_erratum_1463225_debug_handler(regs)) + return 0; + /* * Tell lockdep we disabled irqs in entry.S. Do nothing if they were * already disabled to preserve the last enabled/disabled addresses. |