aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/syscall.c')
-rw-r--r--arch/arm64/kernel/syscall.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 5610ac01c1ec..871c739f060a 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c
@@ -8,6 +8,7 @@
8#include <linux/syscalls.h> 8#include <linux/syscalls.h>
9 9
10#include <asm/daifflags.h> 10#include <asm/daifflags.h>
11#include <asm/debug-monitors.h>
11#include <asm/fpsimd.h> 12#include <asm/fpsimd.h>
12#include <asm/syscall.h> 13#include <asm/syscall.h>
13#include <asm/thread_info.h> 14#include <asm/thread_info.h>
@@ -60,6 +61,35 @@ static inline bool has_syscall_work(unsigned long flags)
60int syscall_trace_enter(struct pt_regs *regs); 61int syscall_trace_enter(struct pt_regs *regs);
61void syscall_trace_exit(struct pt_regs *regs); 62void syscall_trace_exit(struct pt_regs *regs);
62 63
64#ifdef CONFIG_ARM64_ERRATUM_1463225
65DECLARE_PER_CPU(int, __in_cortex_a76_erratum_1463225_wa);
66
67static void cortex_a76_erratum_1463225_svc_handler(void)
68{
69 u32 reg, val;
70
71 if (!unlikely(test_thread_flag(TIF_SINGLESTEP)))
72 return;
73
74 if (!unlikely(this_cpu_has_cap(ARM64_WORKAROUND_1463225)))
75 return;
76
77 __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 1);
78 reg = read_sysreg(mdscr_el1);
79 val = reg | DBG_MDSCR_SS | DBG_MDSCR_KDE;
80 write_sysreg(val, mdscr_el1);
81 asm volatile("msr daifclr, #8");
82 isb();
83
84 /* We will have taken a single-step exception by this point */
85
86 write_sysreg(reg, mdscr_el1);
87 __this_cpu_write(__in_cortex_a76_erratum_1463225_wa, 0);
88}
89#else
90static void cortex_a76_erratum_1463225_svc_handler(void) { }
91#endif /* CONFIG_ARM64_ERRATUM_1463225 */
92
63static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, 93static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
64 const syscall_fn_t syscall_table[]) 94 const syscall_fn_t syscall_table[])
65{ 95{
@@ -68,6 +98,7 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr,
68 regs->orig_x0 = regs->regs[0]; 98 regs->orig_x0 = regs->regs[0];
69 regs->syscallno = scno; 99 regs->syscallno = scno;
70 100
101 cortex_a76_erratum_1463225_svc_handler();
71 local_daif_restore(DAIF_PROCCTX); 102 local_daif_restore(DAIF_PROCCTX);
72 user_exit(); 103 user_exit();
73 104