1 /* Signal support for 32-bit kernel builds
3 * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 * Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
6 * Code was mostly borrowed from kernel/signal.c.
7 * See kernel/signal.c for additional Copyrights.
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.
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.
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
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>
34 #include <asm/uaccess.h>
38 #define DEBUG_COMPAT_SIG 0
39 #define DEBUG_COMPAT_SIG_LEVEL 2
42 #define DBG(LEVEL, ...) \
43 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
44 ? printk(__VA_ARGS__) : (void) 0)
46 #define DBG(LEVEL, ...)
50 sigset_32to64(sigset_t
*s64
, compat_sigset_t
*s32
)
52 s64
->sig
[0] = s32
->sig
[0] | ((unsigned long)s32
->sig
[1] << 32);
56 sigset_64to32(compat_sigset_t
*s32
, sigset_t
*s64
)
58 s32
->sig
[0] = s64
->sig
[0] & 0xffffffffUL
;
59 s32
->sig
[1] = (s64
->sig
[0] >> 32) & 0xffffffffUL
;
63 restore_sigcontext32(struct compat_sigcontext __user
*sc
, struct compat_regfile __user
* rf
,
67 compat_uint_t compat_reg
;
68 compat_uint_t compat_regt
;
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
;
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
);
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
));
89 /* Better safe than sorry, pass __get_user two things of
90 the same size and let gcc do the upward conversion to
92 err
|= __get_user(compat_reg
, &sc
->sc_iaoq
[0]);
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
);
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]);
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
);
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]);
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]);
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.
142 setup_sigcontext32(struct compat_sigcontext __user
*sc
, struct compat_regfile __user
* rf
,
143 struct pt_regs
*regs
, int in_syscall
)
145 compat_int_t flags
= 0;
147 compat_uint_t compat_reg
;
148 compat_uint_t compat_regb
;
151 if (on_sig_stack((unsigned long) sc
))
152 flags
|= PARISC_SC_FLAG_ONSTACK
;
156 DBG(1,"setup_sigcontext32: in_syscall\n");
158 flags
|= PARISC_SC_FLAG_IN_SYSCALL
;
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
);
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
);
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
);
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]);
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]);
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);
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
);
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
);
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
);
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
);
236 /* Print out the IAOQ for debugging */
237 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
238 regs
->iaoq
[0], regs
->iaoq
[1]);
241 err
|= __put_user(flags
, &sc
->sc_flags
);
243 DBG(1,"setup_sigcontext32: Truncating general registers.\n");
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
]);
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
);
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
));
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]);
278 copy_siginfo_from_user32 (siginfo_t
*to
, compat_siginfo_t __user
*from
)
283 if (!access_ok(VERIFY_READ
, from
, sizeof(compat_siginfo_t
)))
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
);
291 err
|= __copy_from_user(&to
->_sifields
._pad
, &from
->_sifields
._pad
, SI_PAD_SIZE
);
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
);
299 err
|= __get_user(to
->si_pid
, &from
->si_pid
);
300 err
|= __get_user(to
->si_uid
, &from
->si_uid
);
302 case __SI_FAULT
>> 16:
303 err
|= __get_user(addr
, &from
->si_addr
);
304 to
->si_addr
= compat_ptr(addr
);
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
);
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
);
322 copy_siginfo_to_user32 (compat_siginfo_t __user
*to
, const siginfo_t
*from
)
328 if (!access_ok(VERIFY_WRITE
, to
, sizeof(compat_siginfo_t
)))
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
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
);
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
);
350 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
351 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
353 case __SI_FAULT
>> 16:
354 addr
= ptr_to_compat(from
->si_addr
);
355 err
|= __put_user(addr
, &to
->si_addr
);
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
);
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
);
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
);