• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  Copyright (C) 1991,1992  Linus Torvalds
4  *  Copyright (C) 2005-2012  Imagination Technologies Ltd.
5  *
6  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7  *
8  */
9 
10 #include <linux/sched.h>
11 #include <linux/sched/task_stack.h>
12 #include <linux/mm.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/uaccess.h>
23 #include <linux/tracehook.h>
24 
25 #include <asm/ucontext.h>
26 #include <asm/cacheflush.h>
27 #include <asm/switch.h>
28 #include <asm/syscall.h>
29 #include <asm/syscalls.h>
30 
31 #define REG_FLAGS	ctx.SaveMask
32 #define REG_RETVAL	ctx.DX[0].U0
33 #define REG_SYSCALL	ctx.DX[0].U1
34 #define REG_SP		ctx.AX[0].U0
35 #define REG_ARG1	ctx.DX[3].U1
36 #define REG_ARG2	ctx.DX[3].U0
37 #define REG_ARG3	ctx.DX[2].U1
38 #define REG_PC		ctx.CurrPC
39 #define REG_RTP		ctx.DX[4].U1
40 
41 struct rt_sigframe {
42 	struct siginfo info;
43 	struct ucontext uc;
44 	unsigned long retcode[2];
45 };
46 
restore_sigcontext(struct pt_regs * regs,struct sigcontext __user * sc)47 static int restore_sigcontext(struct pt_regs *regs,
48 			      struct sigcontext __user *sc)
49 {
50 	int err;
51 
52 	/* Always make any pending restarted system calls return -EINTR */
53 	current->restart_block.fn = do_no_restart_syscall;
54 
55 	err = metag_gp_regs_copyin(regs, 0, sizeof(struct user_gp_regs), NULL,
56 				   &sc->regs);
57 	if (!err)
58 		err = metag_cb_regs_copyin(regs, 0,
59 					   sizeof(struct user_cb_regs), NULL,
60 					   &sc->cb);
61 	if (!err)
62 		err = metag_rp_state_copyin(regs, 0,
63 					    sizeof(struct user_rp_state), NULL,
64 					    &sc->rp);
65 
66 	/* This is a user-mode context. */
67 	regs->REG_FLAGS |= TBICTX_PRIV_BIT;
68 
69 	return err;
70 }
71 
sys_rt_sigreturn(void)72 long sys_rt_sigreturn(void)
73 {
74 	/* NOTE - Meta stack goes UPWARDS - so we wind the stack back */
75 	struct pt_regs *regs = current_pt_regs();
76 	struct rt_sigframe __user *frame;
77 	sigset_t set;
78 
79 	frame = (__force struct rt_sigframe __user *)(regs->REG_SP -
80 						      sizeof(*frame));
81 
82 	if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
83 		goto badframe;
84 
85 	if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
86 		goto badframe;
87 
88 	set_current_blocked(&set);
89 
90 	if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
91 		goto badframe;
92 
93 	if (restore_altstack(&frame->uc.uc_stack))
94 		goto badframe;
95 
96 	return regs->REG_RETVAL;
97 
98 badframe:
99 	force_sig(SIGSEGV, current);
100 
101 	return 0;
102 }
103 
setup_sigcontext(struct sigcontext __user * sc,struct pt_regs * regs,unsigned long mask)104 static int setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
105 			    unsigned long mask)
106 {
107 	int err;
108 
109 	err = metag_gp_regs_copyout(regs, 0, sizeof(struct user_gp_regs), NULL,
110 				    &sc->regs);
111 
112 	if (!err)
113 		err = metag_cb_regs_copyout(regs, 0,
114 					    sizeof(struct user_cb_regs), NULL,
115 					    &sc->cb);
116 	if (!err)
117 		err = metag_rp_state_copyout(regs, 0,
118 					     sizeof(struct user_rp_state), NULL,
119 					     &sc->rp);
120 
121 	/* OK, clear that cbuf flag in the old context, or our stored
122 	 * catch buffer will be restored when we go to call the signal
123 	 * handler. Also clear out the CBRP RA/RD pipe bit incase
124 	 * that is pending as well!
125 	 * Note that as we have already stored this context, these
126 	 * flags will get restored on sigreturn to their original
127 	 * state.
128 	 */
129 	regs->REG_FLAGS &= ~(TBICTX_XCBF_BIT | TBICTX_CBUF_BIT |
130 			     TBICTX_CBRP_BIT);
131 
132 	/* Clear out the LSM_STEP bits in case we are in the middle of
133 	 * and MSET/MGET.
134 	 */
135 	regs->ctx.Flags &= ~TXSTATUS_LSM_STEP_BITS;
136 
137 	err |= __put_user(mask, &sc->oldmask);
138 
139 	return err;
140 }
141 
142 /*
143  * Determine which stack to use..
144  */
get_sigframe(struct ksignal * ksig,unsigned long sp)145 static void __user *get_sigframe(struct ksignal *ksig, unsigned long sp)
146 {
147 	sp = sigsp(sp, ksig);
148 	sp = (sp + 7) & ~7;			/* 8byte align stack */
149 
150 	return (void __user *)sp;
151 }
152 
setup_rt_frame(struct ksignal * ksig,sigset_t * set,struct pt_regs * regs)153 static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
154 			  struct pt_regs *regs)
155 {
156 	struct rt_sigframe __user *frame;
157 	int err;
158 	unsigned long code;
159 
160 	frame = get_sigframe(ksig, regs->REG_SP);
161 	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
162 		return -EFAULT;
163 
164 	err = copy_siginfo_to_user(&frame->info, &ksig->info);
165 
166 	/* Create the ucontext.  */
167 	err |= __put_user(0, &frame->uc.uc_flags);
168 	err |= __put_user(0, (unsigned long __user *)&frame->uc.uc_link);
169 	err |= __save_altstack(&frame->uc.uc_stack, regs->REG_SP);
170 	err |= setup_sigcontext(&frame->uc.uc_mcontext,
171 				regs, set->sig[0]);
172 	err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
173 
174 	if (err)
175 		return -EFAULT;
176 
177 	/* Set up to return from userspace.  */
178 
179 	/* MOV D1Re0 (D1.0), #__NR_rt_sigreturn */
180 	code = 0x03000004 | (__NR_rt_sigreturn << 3);
181 	err |= __put_user(code, (unsigned long __user *)(&frame->retcode[0]));
182 
183 	/* SWITCH #__METAG_SW_SYS */
184 	code = __METAG_SW_ENCODING(SYS);
185 	err |= __put_user(code, (unsigned long __user *)(&frame->retcode[1]));
186 
187 	if (err)
188 		return -EFAULT;
189 
190 	/* Set up registers for signal handler */
191 	regs->REG_RTP = (unsigned long) frame->retcode;
192 	regs->REG_SP = (unsigned long) frame + sizeof(*frame);
193 	regs->REG_ARG1 = ksig->sig;
194 	regs->REG_ARG2 = (unsigned long) &frame->info;
195 	regs->REG_ARG3 = (unsigned long) &frame->uc;
196 	regs->REG_PC = (unsigned long) ksig->ka.sa.sa_handler;
197 
198 	pr_debug("SIG deliver (%s:%d): sp=%p pc=%08x pr=%08x\n",
199 		 current->comm, current->pid, frame, regs->REG_PC,
200 		 regs->REG_RTP);
201 
202 	/* Now pass size of 'new code' into sigtramp so we can do a more
203 	 * effective cache flush - directed rather than 'full flush'.
204 	 */
205 	flush_cache_sigtramp(regs->REG_RTP, sizeof(frame->retcode));
206 
207 	return 0;
208 }
209 
handle_signal(struct ksignal * ksig,struct pt_regs * regs)210 static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
211 {
212 	sigset_t *oldset = sigmask_to_save();
213 	int ret;
214 
215 	/* Set up the stack frame */
216 	ret = setup_rt_frame(ksig, oldset, regs);
217 
218 	signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
219 }
220 
221  /*
222   * Notes for Meta.
223   * We have moved from the old 2.4.9 SH way of using syscall_nr (in the stored
224   * context) to passing in the syscall flag on the stack.
225   * This is because having syscall_nr in our context does not fit with TBX, and
226   * corrupted the stack.
227   */
do_signal(struct pt_regs * regs,int syscall)228 static int do_signal(struct pt_regs *regs, int syscall)
229 {
230 	unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
231 	int restart = 0;
232 	struct ksignal ksig;
233 
234 	/*
235 	 * By the end of rt_sigreturn the context describes the point that the
236 	 * signal was taken (which may happen to be just before a syscall if
237 	 * it's already been restarted). This should *never* be mistaken for a
238 	 * system call in need of restarting.
239 	 */
240 	if (syscall == __NR_rt_sigreturn)
241 		syscall = -1;
242 
243 	/* Did we come from a system call? */
244 	if (syscall >= 0) {
245 		continue_addr = regs->REG_PC;
246 		restart_addr = continue_addr - 4;
247 		retval = regs->REG_RETVAL;
248 
249 		/*
250 		 * Prepare for system call restart. We do this here so that a
251 		 * debugger will see the already changed PC.
252 		 */
253 		switch (retval) {
254 		case -ERESTART_RESTARTBLOCK:
255 			restart = -2;
256 		case -ERESTARTNOHAND:
257 		case -ERESTARTSYS:
258 		case -ERESTARTNOINTR:
259 			++restart;
260 			regs->REG_PC = restart_addr;
261 			break;
262 		}
263 	}
264 
265 	/*
266 	 * Get the signal to deliver. When running under ptrace, at this point
267 	 * the debugger may change all our registers ...
268 	 */
269 	get_signal(&ksig);
270 
271 	/*
272 	 * Depending on the signal settings we may need to revert the decision
273 	 * to restart the system call. But skip this if a debugger has chosen to
274 	 * restart at a different PC.
275 	 */
276 	if (regs->REG_PC != restart_addr)
277 		restart = 0;
278 	if (ksig.sig > 0) {
279 		if (unlikely(restart)) {
280 			if (retval == -ERESTARTNOHAND
281 			    || retval == -ERESTART_RESTARTBLOCK
282 			    || (retval == -ERESTARTSYS
283 				&& !(ksig.ka.sa.sa_flags & SA_RESTART))) {
284 				regs->REG_RETVAL = -EINTR;
285 				regs->REG_PC = continue_addr;
286 			}
287 		}
288 
289 		/* Whee! Actually deliver the signal.  */
290 		handle_signal(&ksig, regs);
291 		return 0;
292 	}
293 
294 	/* Handlerless -ERESTART_RESTARTBLOCK re-enters via restart_syscall */
295 	if (unlikely(restart < 0))
296 		regs->REG_SYSCALL = __NR_restart_syscall;
297 
298 	/*
299 	 * If there's no signal to deliver, we just put the saved sigmask back.
300 	 */
301 	restore_saved_sigmask();
302 
303 	return restart;
304 }
305 
do_work_pending(struct pt_regs * regs,unsigned int thread_flags,int syscall)306 int do_work_pending(struct pt_regs *regs, unsigned int thread_flags,
307 		    int syscall)
308 {
309 	do {
310 		if (likely(thread_flags & _TIF_NEED_RESCHED)) {
311 			schedule();
312 		} else {
313 			if (unlikely(!user_mode(regs)))
314 				return 0;
315 			local_irq_enable();
316 			if (thread_flags & _TIF_SIGPENDING) {
317 				int restart = do_signal(regs, syscall);
318 				if (unlikely(restart)) {
319 					/*
320 					 * Restart without handlers.
321 					 * Deal with it without leaving
322 					 * the kernel space.
323 					 */
324 					return restart;
325 				}
326 				syscall = -1;
327 			} else {
328 				clear_thread_flag(TIF_NOTIFY_RESUME);
329 				tracehook_notify_resume(regs);
330 			}
331 		}
332 		local_irq_disable();
333 		thread_flags = current_thread_info()->flags;
334 	} while (thread_flags & _TIF_WORK_MASK);
335 	return 0;
336 }
337