| .. | .. |
|---|
| 2 | 2 | |
|---|
| 3 | 3 | #include <linux/compiler.h> |
|---|
| 4 | 4 | #include <linux/context_tracking.h> |
|---|
| 5 | +#include <linux/irqstage.h> |
|---|
| 5 | 6 | #include <linux/errno.h> |
|---|
| 6 | 7 | #include <linux/nospec.h> |
|---|
| 7 | 8 | #include <linux/ptrace.h> |
|---|
| .. | .. |
|---|
| 94 | 95 | const syscall_fn_t syscall_table[]) |
|---|
| 95 | 96 | { |
|---|
| 96 | 97 | unsigned long flags = current_thread_info()->flags; |
|---|
| 98 | + int ret; |
|---|
| 97 | 99 | |
|---|
| 98 | 100 | regs->orig_x0 = regs->regs[0]; |
|---|
| 99 | 101 | regs->syscallno = scno; |
|---|
| .. | .. |
|---|
| 117 | 119 | */ |
|---|
| 118 | 120 | |
|---|
| 119 | 121 | cortex_a76_erratum_1463225_svc_handler(); |
|---|
| 122 | + WARN_ON_ONCE(dovetail_debug() && |
|---|
| 123 | + running_inband() && test_inband_stall()); |
|---|
| 120 | 124 | local_daif_restore(DAIF_PROCCTX); |
|---|
| 121 | 125 | |
|---|
| 122 | | - if (flags & _TIF_MTE_ASYNC_FAULT) { |
|---|
| 126 | + ret = pipeline_syscall(scno, regs); |
|---|
| 127 | + if (ret > 0) |
|---|
| 128 | + return; |
|---|
| 129 | + |
|---|
| 130 | + if (ret < 0) |
|---|
| 131 | + goto tail_work; |
|---|
| 132 | + |
|---|
| 133 | + if (system_supports_mte() && (flags & _TIF_MTE_ASYNC_FAULT)) { |
|---|
| 123 | 134 | /* |
|---|
| 124 | 135 | * Process the asynchronous tag check fault before the actual |
|---|
| 125 | 136 | * syscall. do_notify_resume() will send a signal to userspace |
|---|
| .. | .. |
|---|
| 159 | 170 | * check again. However, if we were tracing entry, then we always trace |
|---|
| 160 | 171 | * exit regardless, as the old entry assembly did. |
|---|
| 161 | 172 | */ |
|---|
| 173 | +tail_work: |
|---|
| 162 | 174 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { |
|---|
| 163 | 175 | local_daif_mask(); |
|---|
| 176 | + stall_inband(); |
|---|
| 164 | 177 | flags = current_thread_info()->flags; |
|---|
| 165 | | - if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) |
|---|
| 178 | + if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { |
|---|
| 179 | + unstall_inband(); |
|---|
| 166 | 180 | return; |
|---|
| 181 | + } |
|---|
| 182 | + unstall_inband(); |
|---|
| 167 | 183 | local_daif_restore(DAIF_PROCCTX); |
|---|
| 168 | 184 | } |
|---|
| 169 | 185 | |
|---|