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