| .. | .. | 
|---|
| 50 | 50 | ret = do_ni_syscall(regs, scno); | 
|---|
| 51 | 51 | } | 
|---|
| 52 | 52 |  | 
|---|
| 53 |  | -	if (is_compat_task()) | 
|---|
| 54 |  | -		ret = lower_32_bits(ret); | 
|---|
| 55 |  | - | 
|---|
| 56 |  | -	regs->regs[0] = ret; | 
|---|
|  | 53 | +	syscall_set_return_value(current, regs, 0, ret); | 
|---|
| 57 | 54 | } | 
|---|
| 58 | 55 |  | 
|---|
| 59 | 56 | static inline bool has_syscall_work(unsigned long flags) | 
|---|
| .. | .. | 
|---|
| 101 | 98 | regs->orig_x0 = regs->regs[0]; | 
|---|
| 102 | 99 | regs->syscallno = scno; | 
|---|
| 103 | 100 |  | 
|---|
|  | 101 | +	/* | 
|---|
|  | 102 | +	 * BTI note: | 
|---|
|  | 103 | +	 * The architecture does not guarantee that SPSR.BTYPE is zero | 
|---|
|  | 104 | +	 * on taking an SVC, so we could return to userspace with a | 
|---|
|  | 105 | +	 * non-zero BTYPE after the syscall. | 
|---|
|  | 106 | +	 * | 
|---|
|  | 107 | +	 * This shouldn't matter except when userspace is explicitly | 
|---|
|  | 108 | +	 * doing something stupid, such as setting PROT_BTI on a page | 
|---|
|  | 109 | +	 * that lacks conforming BTI/PACIxSP instructions, falling | 
|---|
|  | 110 | +	 * through from one executable page to another with differing | 
|---|
|  | 111 | +	 * PROT_BTI, or messing with BTYPE via ptrace: in such cases, | 
|---|
|  | 112 | +	 * userspace should not be surprised if a SIGILL occurs on | 
|---|
|  | 113 | +	 * syscall return. | 
|---|
|  | 114 | +	 * | 
|---|
|  | 115 | +	 * So, don't touch regs->pstate & PSR_BTYPE_MASK here. | 
|---|
|  | 116 | +	 * (Similarly for HVC and SMC elsewhere.) | 
|---|
|  | 117 | +	 */ | 
|---|
|  | 118 | + | 
|---|
| 104 | 119 | cortex_a76_erratum_1463225_svc_handler(); | 
|---|
| 105 |  | -	user_exit_irqoff(); | 
|---|
| 106 | 120 | local_daif_restore(DAIF_PROCCTX); | 
|---|
| 107 | 121 |  | 
|---|
|  | 122 | +	if (flags & _TIF_MTE_ASYNC_FAULT) { | 
|---|
|  | 123 | +		/* | 
|---|
|  | 124 | +		 * Process the asynchronous tag check fault before the actual | 
|---|
|  | 125 | +		 * syscall. do_notify_resume() will send a signal to userspace | 
|---|
|  | 126 | +		 * before the syscall is restarted. | 
|---|
|  | 127 | +		 */ | 
|---|
|  | 128 | +		syscall_set_return_value(current, regs, -ERESTARTNOINTR, 0); | 
|---|
|  | 129 | +		return; | 
|---|
|  | 130 | +	} | 
|---|
|  | 131 | + | 
|---|
| 108 | 132 | if (has_syscall_work(flags)) { | 
|---|
| 109 |  | -		/* set default errno for user-issued syscall(-1) */ | 
|---|
|  | 133 | +		/* | 
|---|
|  | 134 | +		 * The de-facto standard way to skip a system call using ptrace | 
|---|
|  | 135 | +		 * is to set the system call to -1 (NO_SYSCALL) and set x0 to a | 
|---|
|  | 136 | +		 * suitable error code for consumption by userspace. However, | 
|---|
|  | 137 | +		 * this cannot be distinguished from a user-issued syscall(-1) | 
|---|
|  | 138 | +		 * and so we must set x0 to -ENOSYS here in case the tracer doesn't | 
|---|
|  | 139 | +		 * issue the skip and we fall into trace_exit with x0 preserved. | 
|---|
|  | 140 | +		 * | 
|---|
|  | 141 | +		 * This is slightly odd because it also means that if a tracer | 
|---|
|  | 142 | +		 * sets the system call number to -1 but does not initialise x0, | 
|---|
|  | 143 | +		 * then x0 will be preserved for all system calls apart from a | 
|---|
|  | 144 | +		 * user-issued syscall(-1). However, requesting a skip and not | 
|---|
|  | 145 | +		 * setting the return value is unlikely to do anything sensible | 
|---|
|  | 146 | +		 * anyway. | 
|---|
|  | 147 | +		 */ | 
|---|
| 110 | 148 | if (scno == NO_SYSCALL) | 
|---|
| 111 |  | -			regs->regs[0] = -ENOSYS; | 
|---|
|  | 149 | +			syscall_set_return_value(current, regs, -ENOSYS, 0); | 
|---|
| 112 | 150 | scno = syscall_trace_enter(regs); | 
|---|
| 113 | 151 | if (scno == NO_SYSCALL) | 
|---|
| 114 | 152 | goto trace_exit; | 
|---|
| .. | .. | 
|---|
| 124 | 162 | if (!has_syscall_work(flags) && !IS_ENABLED(CONFIG_DEBUG_RSEQ)) { | 
|---|
| 125 | 163 | local_daif_mask(); | 
|---|
| 126 | 164 | flags = current_thread_info()->flags; | 
|---|
| 127 |  | -		if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) { | 
|---|
| 128 |  | -			/* | 
|---|
| 129 |  | -			 * We're off to userspace, where interrupts are | 
|---|
| 130 |  | -			 * always enabled after we restore the flags from | 
|---|
| 131 |  | -			 * the SPSR. | 
|---|
| 132 |  | -			 */ | 
|---|
| 133 |  | -			trace_hardirqs_on(); | 
|---|
|  | 165 | +		if (!has_syscall_work(flags) && !(flags & _TIF_SINGLESTEP)) | 
|---|
| 134 | 166 | return; | 
|---|
| 135 |  | -		} | 
|---|
| 136 | 167 | local_daif_restore(DAIF_PROCCTX); | 
|---|
| 137 | 168 | } | 
|---|
| 138 | 169 |  | 
|---|
| .. | .. | 
|---|
| 157 | 188 | sve_user_disable(); | 
|---|
| 158 | 189 | } | 
|---|
| 159 | 190 |  | 
|---|
| 160 |  | -asmlinkage void el0_svc_handler(struct pt_regs *regs) | 
|---|
|  | 191 | +void do_el0_svc(struct pt_regs *regs) | 
|---|
| 161 | 192 | { | 
|---|
| 162 | 193 | sve_user_discard(); | 
|---|
| 163 | 194 | el0_svc_common(regs, regs->regs[8], __NR_syscalls, sys_call_table); | 
|---|
| 164 | 195 | } | 
|---|
| 165 | 196 |  | 
|---|
| 166 | 197 | #ifdef CONFIG_COMPAT | 
|---|
| 167 |  | -asmlinkage void el0_svc_compat_handler(struct pt_regs *regs) | 
|---|
|  | 198 | +void do_el0_svc_compat(struct pt_regs *regs) | 
|---|
| 168 | 199 | { | 
|---|
| 169 | 200 | el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls, | 
|---|
| 170 | 201 | compat_sys_call_table); | 
|---|