1/*    Signal support for 32-bit kernel builds
2 *
3 *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
5 *
6 *    Code was mostly borrowed from kernel/signal.c.
7 *    See kernel/signal.c for additional Copyrights.
8 *
9 *
10 *    This program is free software; you can redistribute it and/or modify
11 *    it under the terms of the GNU General Public License as published by
12 *    the Free Software Foundation; either version 2 of the License, or
13 *    (at your option) any later version.
14 *
15 *    This program is distributed in the hope that it will be useful,
16 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *    GNU General Public License for more details.
19 *
20 *    You should have received a copy of the GNU General Public License
21 *    along with this program; if not, write to the Free Software
22 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23 */
24
25#include <linux/compat.h>
26#include <linux/module.h>
27#include <linux/unistd.h>
28#include <linux/init.h>
29#include <linux/sched.h>
30#include <linux/syscalls.h>
31#include <linux/types.h>
32#include <linux/errno.h>
33
34#include <asm/uaccess.h>
35
36#include "signal32.h"
37
38#define DEBUG_COMPAT_SIG 0
39#define DEBUG_COMPAT_SIG_LEVEL 2
40
41#if DEBUG_COMPAT_SIG
42#define DBG(LEVEL, ...) \
43	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
44	? printk(__VA_ARGS__) : (void) 0)
45#else
46#define DBG(LEVEL, ...)
47#endif
48
49inline void
50sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
51{
52	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
53}
54
55inline void
56sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
57{
58	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
59	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
60}
61
62long
63restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
64		struct pt_regs *regs)
65{
66	long err = 0;
67	compat_uint_t compat_reg;
68	compat_uint_t compat_regt;
69	int regn;
70
71	/* When loading 32-bit values into 64-bit registers make
72	   sure to clear the upper 32-bits */
73	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
74	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
75	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
76	for(regn=0; regn < 32; regn++){
77		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
78		regs->gr[regn] = compat_reg;
79		/* Load upper half */
80		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
81		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
82		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
83				regn, regs->gr[regn], compat_regt, compat_reg);
84	}
85	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
86	/* XXX: BE WARNED FR's are 64-BIT! */
87	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
88
89	/* Better safe than sorry, pass __get_user two things of
90	   the same size and let gcc do the upward conversion to
91	   64-bits */
92	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
93	/* Load upper half */
94	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
95	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
96	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
97	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
98			&sc->sc_iaoq[0], compat_reg);
99
100	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
101	/* Load upper half */
102	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
103	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
104	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
105	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
106			&sc->sc_iaoq[1],compat_reg);
107	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
108			regs->iaoq[0],regs->iaoq[1]);
109
110	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
111	/* Load the upper half for iasq */
112	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
113	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
114	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
115
116	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
117	/* Load the upper half for iasq */
118	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
119	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
120	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
121	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
122		regs->iasq[0],regs->iasq[1]);
123
124	err |= __get_user(compat_reg, &sc->sc_sar);
125	/* Load the upper half for sar */
126	err |= __get_user(compat_regt, &rf->rf_sar);
127	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
128	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
129	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
130	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
131
132	return err;
133}
134
135/*
136 * Set up the sigcontext structure for this process.
137 * This is not an easy task if the kernel is 64-bit, it will require
138 * that we examine the process personality to determine if we need to
139 * truncate for a 32-bit userspace.
140 */
141long
142setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
143		struct pt_regs *regs, int in_syscall)
144{
145	compat_int_t flags = 0;
146	long err = 0;
147	compat_uint_t compat_reg;
148	compat_uint_t compat_regb;
149	int regn;
150
151	if (on_sig_stack((unsigned long) sc))
152		flags |= PARISC_SC_FLAG_ONSTACK;
153
154	if (in_syscall) {
155
156		DBG(1,"setup_sigcontext32: in_syscall\n");
157
158		flags |= PARISC_SC_FLAG_IN_SYSCALL;
159		/* Truncate gr31 */
160		compat_reg = (compat_uint_t)(regs->gr[31]);
161		/* regs->iaoq is undefined in the syscall return path */
162		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
163		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
164				&sc->sc_iaoq[0], compat_reg);
165
166		/* Store upper half */
167		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
168		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
169		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
170
171
172		compat_reg = (compat_uint_t)(regs->gr[31]+4);
173		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
174		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
175				&sc->sc_iaoq[1], compat_reg);
176		/* Store upper half */
177		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
178		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
179		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
180
181		/* Truncate sr3 */
182		compat_reg = (compat_uint_t)(regs->sr[3]);
183		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
184		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
185
186		/* Store upper half */
187		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
188		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
189		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
190
191		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
192		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
193		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
194			regs->gr[31], regs->gr[31]+4);
195
196	} else {
197
198		compat_reg = (compat_uint_t)(regs->iaoq[0]);
199		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
200		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
201				&sc->sc_iaoq[0], compat_reg);
202		/* Store upper half */
203		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
204		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
205		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
206
207		compat_reg = (compat_uint_t)(regs->iaoq[1]);
208		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
209		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
210				&sc->sc_iaoq[1], compat_reg);
211		/* Store upper half */
212		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
213		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
214		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
215
216
217		compat_reg = (compat_uint_t)(regs->iasq[0]);
218		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
219		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
220				&sc->sc_iasq[0], compat_reg);
221		/* Store upper half */
222		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
223		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
224		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
225
226
227		compat_reg = (compat_uint_t)(regs->iasq[1]);
228		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
229		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
230				&sc->sc_iasq[1], compat_reg);
231		/* Store upper half */
232		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
233		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
234		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
235
236		/* Print out the IAOQ for debugging */
237		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
238			regs->iaoq[0], regs->iaoq[1]);
239	}
240
241	err |= __put_user(flags, &sc->sc_flags);
242
243	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
244
245	for(regn=0; regn < 32; regn++){
246		/* Truncate a general register */
247		compat_reg = (compat_uint_t)(regs->gr[regn]);
248		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
249		/* Store upper half */
250		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
251		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
252
253		/* DEBUG: Write out the "upper / lower" register data */
254		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
255				compat_regb, compat_reg);
256	}
257
258	/* Copy the floating point registers (same size)
259	   XXX: BE WARNED FR's are 64-BIT! */
260	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
261	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
262		sizeof(regs->fr), sizeof(sc->sc_fr));
263	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
264
265	compat_reg = (compat_uint_t)(regs->sar);
266	err |= __put_user(compat_reg, &sc->sc_sar);
267	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
268	/* Store upper half */
269	compat_reg = (compat_uint_t)(regs->sar >> 32);
270	err |= __put_user(compat_reg, &rf->rf_sar);
271	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
272	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
273
274	return err;
275}
276
277int
278copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
279{
280	compat_uptr_t addr;
281	int err;
282
283	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
284		return -EFAULT;
285
286	err = __get_user(to->si_signo, &from->si_signo);
287	err |= __get_user(to->si_errno, &from->si_errno);
288	err |= __get_user(to->si_code, &from->si_code);
289
290	if (to->si_code < 0)
291		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
292	else {
293		switch (to->si_code >> 16) {
294		      case __SI_CHLD >> 16:
295			err |= __get_user(to->si_utime, &from->si_utime);
296			err |= __get_user(to->si_stime, &from->si_stime);
297			err |= __get_user(to->si_status, &from->si_status);
298		      default:
299			err |= __get_user(to->si_pid, &from->si_pid);
300			err |= __get_user(to->si_uid, &from->si_uid);
301			break;
302		      case __SI_FAULT >> 16:
303			err |= __get_user(addr, &from->si_addr);
304			to->si_addr = compat_ptr(addr);
305			break;
306		      case __SI_POLL >> 16:
307			err |= __get_user(to->si_band, &from->si_band);
308			err |= __get_user(to->si_fd, &from->si_fd);
309			break;
310		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
311		      case __SI_MESGQ >> 16:
312			err |= __get_user(to->si_pid, &from->si_pid);
313			err |= __get_user(to->si_uid, &from->si_uid);
314			err |= __get_user(to->si_int, &from->si_int);
315			break;
316		}
317	}
318	return err;
319}
320
321int
322copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from)
323{
324	compat_uptr_t addr;
325	compat_int_t val;
326	int err;
327
328	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
329		return -EFAULT;
330
331	/* If you change siginfo_t structure, please be sure
332	   this code is fixed accordingly.
333	   It should never copy any pad contained in the structure
334	   to avoid security leaks, but must copy the generic
335	   3 ints plus the relevant union member.
336	   This routine must convert siginfo from 64bit to 32bit as well
337	   at the same time.  */
338	err = __put_user(from->si_signo, &to->si_signo);
339	err |= __put_user(from->si_errno, &to->si_errno);
340	err |= __put_user((short)from->si_code, &to->si_code);
341	if (from->si_code < 0)
342		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
343	else {
344		switch (from->si_code >> 16) {
345		case __SI_CHLD >> 16:
346			err |= __put_user(from->si_utime, &to->si_utime);
347			err |= __put_user(from->si_stime, &to->si_stime);
348			err |= __put_user(from->si_status, &to->si_status);
349		default:
350			err |= __put_user(from->si_pid, &to->si_pid);
351			err |= __put_user(from->si_uid, &to->si_uid);
352			break;
353		case __SI_FAULT >> 16:
354			addr = ptr_to_compat(from->si_addr);
355			err |= __put_user(addr, &to->si_addr);
356			break;
357		case __SI_POLL >> 16:
358			err |= __put_user(from->si_band, &to->si_band);
359			err |= __put_user(from->si_fd, &to->si_fd);
360			break;
361		case __SI_TIMER >> 16:
362			err |= __put_user(from->si_tid, &to->si_tid);
363			err |= __put_user(from->si_overrun, &to->si_overrun);
364			val = (compat_int_t)from->si_int;
365			err |= __put_user(val, &to->si_int);
366			break;
367		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
368		case __SI_MESGQ >> 16:
369			err |= __put_user(from->si_uid, &to->si_uid);
370			err |= __put_user(from->si_pid, &to->si_pid);
371			val = (compat_int_t)from->si_int;
372			err |= __put_user(val, &to->si_int);
373			break;
374		}
375	}
376	return err;
377}
378