Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*    Signal support for 32-bit kernel builds
  3 *
  4 *    Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
  5 *    Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
  6 *
  7 *    Code was mostly borrowed from kernel/signal.c.
  8 *    See kernel/signal.c for additional Copyrights.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
  9 */
 10
 11#include <linux/compat.h>
 12#include <linux/module.h>
 13#include <linux/unistd.h>
 14#include <linux/init.h>
 15#include <linux/sched.h>
 16#include <linux/syscalls.h>
 17#include <linux/types.h>
 18#include <linux/errno.h>
 19
 20#include <linux/uaccess.h>
 21
 22#include "signal32.h"
 
 23
 24#define DEBUG_COMPAT_SIG 0 
 25#define DEBUG_COMPAT_SIG_LEVEL 2
 26
 27#if DEBUG_COMPAT_SIG
 28#define DBG(LEVEL, ...) \
 29	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
 30	? printk(__VA_ARGS__) : (void) 0)
 31#else
 32#define DBG(LEVEL, ...)
 33#endif
 34
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 35long
 36restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
 37		struct pt_regs *regs)
 38{
 39	long err = 0;
 40	compat_uint_t compat_reg;
 41	compat_uint_t compat_regt;
 42	int regn;
 43	
 44	/* When loading 32-bit values into 64-bit registers make
 45	   sure to clear the upper 32-bits */
 46	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
 47	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
 48	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
 49	for(regn=0; regn < 32; regn++){
 50		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
 51		regs->gr[regn] = compat_reg;
 52		/* Load upper half */
 53		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
 54		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
 55		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
 56				regn, regs->gr[regn], compat_regt, compat_reg);
 57	}
 58	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
 59	/* XXX: BE WARNED FR's are 64-BIT! */
 60	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
 61		
 62	/* Better safe than sorry, pass __get_user two things of
 63	   the same size and let gcc do the upward conversion to 
 64	   64-bits */		
 65	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
 66	/* Load upper half */
 67	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
 68	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
 69	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
 70	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
 71			&sc->sc_iaoq[0], compat_reg);
 72
 73	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
 74	/* Load upper half */
 75	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
 76	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
 77	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
 78	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
 79			&sc->sc_iaoq[1],compat_reg);	
 80	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
 81			regs->iaoq[0],regs->iaoq[1]);		
 82		
 83	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
 84	/* Load the upper half for iasq */
 85	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
 86	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
 87	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
 88	
 89	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
 90	/* Load the upper half for iasq */
 91	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
 92	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
 93	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
 94	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
 95		regs->iasq[0],regs->iasq[1]);		
 96
 97	err |= __get_user(compat_reg, &sc->sc_sar);
 98	/* Load the upper half for sar */
 99	err |= __get_user(compat_regt, &rf->rf_sar);
100	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;	
101	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);	
102	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);		
103	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
104	
105	return err;
106}
107
108/*
109 * Set up the sigcontext structure for this process.
110 * This is not an easy task if the kernel is 64-bit, it will require
111 * that we examine the process personality to determine if we need to
112 * truncate for a 32-bit userspace.
113 */
114long
115setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
116		struct pt_regs *regs, int in_syscall)		 
117{
118	compat_int_t flags = 0;
119	long err = 0;
120	compat_uint_t compat_reg;
121	compat_uint_t compat_regb;
122	int regn;
123	
124	if (on_sig_stack((unsigned long) sc))
125		flags |= PARISC_SC_FLAG_ONSTACK;
126	
127	if (in_syscall) {
128		
129		DBG(1,"setup_sigcontext32: in_syscall\n");
130		
131		flags |= PARISC_SC_FLAG_IN_SYSCALL;
132		/* Truncate gr31 */
133		compat_reg = (compat_uint_t)(regs->gr[31]);
134		/* regs->iaoq is undefined in the syscall return path */
135		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
136		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
137				&sc->sc_iaoq[0], compat_reg);
138		
139		/* Store upper half */
140		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
141		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
142		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
143		
144		
145		compat_reg = (compat_uint_t)(regs->gr[31]+4);
146		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
147		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
148				&sc->sc_iaoq[1], compat_reg);
149		/* Store upper half */
150		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
151		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
152		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
153		
154		/* Truncate sr3 */
155		compat_reg = (compat_uint_t)(regs->sr[3]);
156		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
157		err |= __put_user(compat_reg, &sc->sc_iasq[1]);		
158		
159		/* Store upper half */
160		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
161		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
162		err |= __put_user(compat_reg, &rf->rf_iasq[1]);		
163		
164		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
165		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);		
166		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",				
167			regs->gr[31], regs->gr[31]+4);
168		
169	} else {
170		
171		compat_reg = (compat_uint_t)(regs->iaoq[0]);
172		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
173		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
174				&sc->sc_iaoq[0], compat_reg);
175		/* Store upper half */
176		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
177		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);	
178		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
179		
180		compat_reg = (compat_uint_t)(regs->iaoq[1]);
181		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
182		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
183				&sc->sc_iaoq[1], compat_reg);
184		/* Store upper half */
185		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
186		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
187		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
188		
189		
190		compat_reg = (compat_uint_t)(regs->iasq[0]);
191		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
192		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
193				&sc->sc_iasq[0], compat_reg);
194		/* Store upper half */
195		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
196		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
197		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
198		
199		
200		compat_reg = (compat_uint_t)(regs->iasq[1]);
201		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
202		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
203				&sc->sc_iasq[1], compat_reg);
204		/* Store upper half */
205		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
206		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
207		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
208
209		/* Print out the IAOQ for debugging */		
210		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
211			regs->iaoq[0], regs->iaoq[1]);
212	}
213
214	err |= __put_user(flags, &sc->sc_flags);
215	
216	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
217	
218	for(regn=0; regn < 32; regn++){
219		/* Truncate a general register */
220		compat_reg = (compat_uint_t)(regs->gr[regn]);
221		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
222		/* Store upper half */
223		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
224		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
225
226		/* DEBUG: Write out the "upper / lower" register data */
227		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
228				compat_regb, compat_reg);
229	}
230	
231	/* Copy the floating point registers (same size)
232	   XXX: BE WARNED FR's are 64-BIT! */	
233	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
234	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
235		sizeof(regs->fr), sizeof(sc->sc_fr));
236	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
237
238	compat_reg = (compat_uint_t)(regs->sar);
239	err |= __put_user(compat_reg, &sc->sc_sar);
240	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
241	/* Store upper half */
242	compat_reg = (compat_uint_t)(regs->sar >> 32);
243	err |= __put_user(compat_reg, &rf->rf_sar);	
244	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
245	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
246
247	return err;
248}
v3.5.6
 
  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#include "sys32.h"
 38
 39#define DEBUG_COMPAT_SIG 0 
 40#define DEBUG_COMPAT_SIG_LEVEL 2
 41
 42#if DEBUG_COMPAT_SIG
 43#define DBG(LEVEL, ...) \
 44	((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
 45	? printk(__VA_ARGS__) : (void) 0)
 46#else
 47#define DBG(LEVEL, ...)
 48#endif
 49
 50inline void
 51sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
 52{
 53	s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
 54}
 55
 56inline void
 57sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
 58{
 59	s32->sig[0] = s64->sig[0] & 0xffffffffUL;
 60	s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
 61}
 62
 63static int
 64put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
 65{
 66	compat_sigset_t s;
 67
 68	if (sz != sizeof *set) panic("put_sigset32()");
 69	sigset_64to32(&s, set);
 70
 71	return copy_to_user(up, &s, sizeof s);
 72}
 73
 74static int
 75get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
 76{
 77	compat_sigset_t s;
 78	int r;
 79
 80	if (sz != sizeof *set) panic("put_sigset32()");
 81
 82	if ((r = copy_from_user(&s, up, sz)) == 0) {
 83		sigset_32to64(set, &s);
 84	}
 85
 86	return r;
 87}
 88
 89int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
 90				    unsigned int sigsetsize)
 91{
 92	sigset_t old_set, new_set;
 93	int ret;
 94
 95	if (set && get_sigset32(set, &new_set, sigsetsize))
 96		return -EFAULT;
 97	
 98	KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
 99				 oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
100
101	if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
102		return -EFAULT;
103
104	return ret;
105}
106
107
108int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
109{
110	int ret;
111	sigset_t set;
112
113	KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
114
115	if (!ret && put_sigset32(uset, &set, sigsetsize))
116		return -EFAULT;
117
118	return ret;
119}
120
121long
122sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
123                 size_t sigsetsize)
124{
125	struct k_sigaction32 new_sa32, old_sa32;
126	struct k_sigaction new_sa, old_sa;
127	int ret = -EINVAL;
128
129	if (act) {
130		if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
131			return -EFAULT;
132		new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
133		new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
134		sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
135	}
136
137	ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
138
139	if (!ret && oact) {
140		sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
141		old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
142		old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
143		if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
144			return -EFAULT;
145	}
146	return ret;
147}
148
149int 
150do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
151{
152	compat_stack_t ss32, oss32;
153	stack_t ss, oss;
154	stack_t *ssp = NULL, *ossp = NULL;
155	int ret;
156
157	if (uss32) {
158		if (copy_from_user(&ss32, uss32, sizeof ss32))
159			return -EFAULT;
160
161		ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
162		ss.ss_flags = ss32.ss_flags;
163		ss.ss_size = ss32.ss_size;
164
165		ssp = &ss;
166	}
167
168	if (uoss32)
169		ossp = &oss;
170
171	KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
172
173	if (!ret && uoss32) {
174		oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
175		oss32.ss_flags = oss.ss_flags;
176		oss32.ss_size = oss.ss_size;
177		if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
178			return -EFAULT;
179	}
180
181	return ret;
182}
183
184long
185restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
186		struct pt_regs *regs)
187{
188	long err = 0;
189	compat_uint_t compat_reg;
190	compat_uint_t compat_regt;
191	int regn;
192	
193	/* When loading 32-bit values into 64-bit registers make
194	   sure to clear the upper 32-bits */
195	DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
196	DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
197	DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
198	for(regn=0; regn < 32; regn++){
199		err |= __get_user(compat_reg,&sc->sc_gr[regn]);
200		regs->gr[regn] = compat_reg;
201		/* Load upper half */
202		err |= __get_user(compat_regt,&rf->rf_gr[regn]);
203		regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
204		DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
205				regn, regs->gr[regn], compat_regt, compat_reg);
206	}
207	DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
208	/* XXX: BE WARNED FR's are 64-BIT! */
209	err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
210		
211	/* Better safe than sorry, pass __get_user two things of
212	   the same size and let gcc do the upward conversion to 
213	   64-bits */		
214	err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
215	/* Load upper half */
216	err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
217	regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
218	DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
219	DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
220			&sc->sc_iaoq[0], compat_reg);
221
222	err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
223	/* Load upper half */
224	err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
225	regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
226	DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
227	DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
228			&sc->sc_iaoq[1],compat_reg);	
229	DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
230			regs->iaoq[0],regs->iaoq[1]);		
231		
232	err |= __get_user(compat_reg, &sc->sc_iasq[0]);
233	/* Load the upper half for iasq */
234	err |= __get_user(compat_regt, &rf->rf_iasq[0]);
235	regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
236	DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
237	
238	err |= __get_user(compat_reg, &sc->sc_iasq[1]);
239	/* Load the upper half for iasq */
240	err |= __get_user(compat_regt, &rf->rf_iasq[1]);
241	regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
242	DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
243	DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
244		regs->iasq[0],regs->iasq[1]);		
245
246	err |= __get_user(compat_reg, &sc->sc_sar);
247	/* Load the upper half for sar */
248	err |= __get_user(compat_regt, &rf->rf_sar);
249	regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;	
250	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);	
251	DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);		
252	DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
253	
254	return err;
255}
256
257/*
258 * Set up the sigcontext structure for this process.
259 * This is not an easy task if the kernel is 64-bit, it will require
260 * that we examine the process personality to determine if we need to
261 * truncate for a 32-bit userspace.
262 */
263long
264setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
265		struct pt_regs *regs, int in_syscall)		 
266{
267	compat_int_t flags = 0;
268	long err = 0;
269	compat_uint_t compat_reg;
270	compat_uint_t compat_regb;
271	int regn;
272	
273	if (on_sig_stack((unsigned long) sc))
274		flags |= PARISC_SC_FLAG_ONSTACK;
275	
276	if (in_syscall) {
277		
278		DBG(1,"setup_sigcontext32: in_syscall\n");
279		
280		flags |= PARISC_SC_FLAG_IN_SYSCALL;
281		/* Truncate gr31 */
282		compat_reg = (compat_uint_t)(regs->gr[31]);
283		/* regs->iaoq is undefined in the syscall return path */
284		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
285		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
286				&sc->sc_iaoq[0], compat_reg);
287		
288		/* Store upper half */
289		compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
290		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
291		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
292		
293		
294		compat_reg = (compat_uint_t)(regs->gr[31]+4);
295		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
296		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
297				&sc->sc_iaoq[1], compat_reg);
298		/* Store upper half */
299		compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
300		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
301		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
302		
303		/* Truncate sr3 */
304		compat_reg = (compat_uint_t)(regs->sr[3]);
305		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
306		err |= __put_user(compat_reg, &sc->sc_iasq[1]);		
307		
308		/* Store upper half */
309		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
310		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
311		err |= __put_user(compat_reg, &rf->rf_iasq[1]);		
312		
313		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
314		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);		
315		DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",				
316			regs->gr[31], regs->gr[31]+4);
317		
318	} else {
319		
320		compat_reg = (compat_uint_t)(regs->iaoq[0]);
321		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
322		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
323				&sc->sc_iaoq[0], compat_reg);
324		/* Store upper half */
325		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
326		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);	
327		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
328		
329		compat_reg = (compat_uint_t)(regs->iaoq[1]);
330		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
331		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
332				&sc->sc_iaoq[1], compat_reg);
333		/* Store upper half */
334		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
335		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
336		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
337		
338		
339		compat_reg = (compat_uint_t)(regs->iasq[0]);
340		err |= __put_user(compat_reg, &sc->sc_iasq[0]);
341		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
342				&sc->sc_iasq[0], compat_reg);
343		/* Store upper half */
344		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
345		err |= __put_user(compat_reg, &rf->rf_iasq[0]);
346		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
347		
348		
349		compat_reg = (compat_uint_t)(regs->iasq[1]);
350		err |= __put_user(compat_reg, &sc->sc_iasq[1]);
351		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
352				&sc->sc_iasq[1], compat_reg);
353		/* Store upper half */
354		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
355		err |= __put_user(compat_reg, &rf->rf_iasq[1]);
356		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
357
358		/* Print out the IAOQ for debugging */		
359		DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
360			regs->iaoq[0], regs->iaoq[1]);
361	}
362
363	err |= __put_user(flags, &sc->sc_flags);
364	
365	DBG(1,"setup_sigcontext32: Truncating general registers.\n");
366	
367	for(regn=0; regn < 32; regn++){
368		/* Truncate a general register */
369		compat_reg = (compat_uint_t)(regs->gr[regn]);
370		err |= __put_user(compat_reg, &sc->sc_gr[regn]);
371		/* Store upper half */
372		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
373		err |= __put_user(compat_regb, &rf->rf_gr[regn]);
374
375		/* DEBUG: Write out the "upper / lower" register data */
376		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
377				compat_regb, compat_reg);
378	}
379	
380	/* Copy the floating point registers (same size)
381	   XXX: BE WARNED FR's are 64-BIT! */	
382	DBG(1,"setup_sigcontext32: Copying from regs to sc, "
383	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
384		sizeof(regs->fr), sizeof(sc->sc_fr));
385	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
386
387	compat_reg = (compat_uint_t)(regs->sar);
388	err |= __put_user(compat_reg, &sc->sc_sar);
389	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
390	/* Store upper half */
391	compat_reg = (compat_uint_t)(regs->sar >> 32);
392	err |= __put_user(compat_reg, &rf->rf_sar);	
393	DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
394	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
395
396	return err;
397}
398
399int
400copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
401{
402	compat_uptr_t addr;
403	int err;
404
405	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
406		return -EFAULT;
407
408	err = __get_user(to->si_signo, &from->si_signo);
409	err |= __get_user(to->si_errno, &from->si_errno);
410	err |= __get_user(to->si_code, &from->si_code);
411
412	if (to->si_code < 0)
413		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
414	else {
415		switch (to->si_code >> 16) {
416		      case __SI_CHLD >> 16:
417			err |= __get_user(to->si_utime, &from->si_utime);
418			err |= __get_user(to->si_stime, &from->si_stime);
419			err |= __get_user(to->si_status, &from->si_status);
420		      default:
421			err |= __get_user(to->si_pid, &from->si_pid);
422			err |= __get_user(to->si_uid, &from->si_uid);
423			break;
424		      case __SI_FAULT >> 16:
425			err |= __get_user(addr, &from->si_addr);
426			to->si_addr = compat_ptr(addr);
427			break;
428		      case __SI_POLL >> 16:
429			err |= __get_user(to->si_band, &from->si_band);
430			err |= __get_user(to->si_fd, &from->si_fd);
431			break;
432		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
433		      case __SI_MESGQ >> 16:
434			err |= __get_user(to->si_pid, &from->si_pid);
435			err |= __get_user(to->si_uid, &from->si_uid);
436			err |= __get_user(to->si_int, &from->si_int);
437			break;
438		}
439	}
440	return err;
441}
442
443int
444copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
445{
446	compat_uptr_t addr;
447	compat_int_t val;
448	int err;
449
450	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
451		return -EFAULT;
452
453	/* If you change siginfo_t structure, please be sure
454	   this code is fixed accordingly.
455	   It should never copy any pad contained in the structure
456	   to avoid security leaks, but must copy the generic
457	   3 ints plus the relevant union member.
458	   This routine must convert siginfo from 64bit to 32bit as well
459	   at the same time.  */
460	err = __put_user(from->si_signo, &to->si_signo);
461	err |= __put_user(from->si_errno, &to->si_errno);
462	err |= __put_user((short)from->si_code, &to->si_code);
463	if (from->si_code < 0)
464		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
465	else {
466		switch (from->si_code >> 16) {
467		case __SI_CHLD >> 16:
468			err |= __put_user(from->si_utime, &to->si_utime);
469			err |= __put_user(from->si_stime, &to->si_stime);
470			err |= __put_user(from->si_status, &to->si_status);
471		default:
472			err |= __put_user(from->si_pid, &to->si_pid);
473			err |= __put_user(from->si_uid, &to->si_uid);
474			break;
475		case __SI_FAULT >> 16:
476			addr = ptr_to_compat(from->si_addr);
477			err |= __put_user(addr, &to->si_addr);
478			break;
479		case __SI_POLL >> 16:
480			err |= __put_user(from->si_band, &to->si_band);
481			err |= __put_user(from->si_fd, &to->si_fd);
482			break;
483		case __SI_TIMER >> 16:
484			err |= __put_user(from->si_tid, &to->si_tid);
485			err |= __put_user(from->si_overrun, &to->si_overrun);
486			val = (compat_int_t)from->si_int;
487			err |= __put_user(val, &to->si_int);
488			break;
489		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */
490		case __SI_MESGQ >> 16:
491			err |= __put_user(from->si_uid, &to->si_uid);
492			err |= __put_user(from->si_pid, &to->si_pid);
493			val = (compat_int_t)from->si_int;
494			err |= __put_user(val, &to->si_int);
495			break;
496		}
497	}
498	return err;
499}
500
501asmlinkage long compat_sys_rt_sigqueueinfo(int pid, int sig,
502	struct compat_siginfo __user *uinfo)
503{
504	siginfo_t info;
505
506	if (copy_siginfo_from_user32(&info, uinfo))
507		return -EFAULT;
508
509	/* Not even root can pretend to send signals from the kernel.
510	   Nor can they impersonate a kill(), which adds source info.  */
511	if (info.si_code >= 0)
512		return -EPERM;
513	info.si_signo = sig;
514
515	/* POSIX.1b doesn't mention process groups.  */
516	return kill_proc_info(sig, &info, pid);
517}
518