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>
39 #define DEBUG_COMPAT_SIG 0
40 #define DEBUG_COMPAT_SIG_LEVEL 2
43 #define DBG(LEVEL, ...) \
44 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45 ? printk(__VA_ARGS__) : (void) 0)
47 #define DBG(LEVEL, ...)
51 sigset_32to64(sigset_t
*s64
, compat_sigset_t
*s32
)
53 s64
->sig
[0] = s32
->sig
[0] | ((unsigned long)s32
->sig
[1] << 32);
57 sigset_64to32(compat_sigset_t
*s32
, sigset_t
*s64
)
59 s32
->sig
[0] = s64
->sig
[0] & 0xffffffffUL
;
60 s32
->sig
[1] = (s64
->sig
[0] >> 32) & 0xffffffffUL
;
64 restore_sigcontext32(struct compat_sigcontext __user
*sc
, struct compat_regfile __user
* rf
,
68 compat_uint_t compat_reg
;
69 compat_uint_t compat_regt
;
72 /* When loading 32-bit values into 64-bit registers make
73 sure to clear the upper 32-bits */
74 DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
75 DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc
, rf
, regs
);
76 DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc
));
77 for(regn
=0; regn
< 32; regn
++){
78 err
|= __get_user(compat_reg
,&sc
->sc_gr
[regn
]);
79 regs
->gr
[regn
] = compat_reg
;
81 err
|= __get_user(compat_regt
,&rf
->rf_gr
[regn
]);
82 regs
->gr
[regn
] = ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
83 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
84 regn
, regs
->gr
[regn
], compat_regt
, compat_reg
);
86 DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc
->sc_fr
, sizeof(sc
->sc_fr
));
87 /* XXX: BE WARNED FR's are 64-BIT! */
88 err
|= __copy_from_user(regs
->fr
, sc
->sc_fr
, sizeof(regs
->fr
));
90 /* Better safe than sorry, pass __get_user two things of
91 the same size and let gcc do the upward conversion to
93 err
|= __get_user(compat_reg
, &sc
->sc_iaoq
[0]);
95 err
|= __get_user(compat_regt
, &rf
->rf_iaoq
[0]);
96 regs
->iaoq
[0] = ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
97 DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt
);
98 DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
99 &sc
->sc_iaoq
[0], compat_reg
);
101 err
|= __get_user(compat_reg
, &sc
->sc_iaoq
[1]);
102 /* Load upper half */
103 err
|= __get_user(compat_regt
, &rf
->rf_iaoq
[1]);
104 regs
->iaoq
[1] = ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
105 DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt
);
106 DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
107 &sc
->sc_iaoq
[1],compat_reg
);
108 DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
109 regs
->iaoq
[0],regs
->iaoq
[1]);
111 err
|= __get_user(compat_reg
, &sc
->sc_iasq
[0]);
112 /* Load the upper half for iasq */
113 err
|= __get_user(compat_regt
, &rf
->rf_iasq
[0]);
114 regs
->iasq
[0] = ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
115 DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt
);
117 err
|= __get_user(compat_reg
, &sc
->sc_iasq
[1]);
118 /* Load the upper half for iasq */
119 err
|= __get_user(compat_regt
, &rf
->rf_iasq
[1]);
120 regs
->iasq
[1] = ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
121 DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt
);
122 DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
123 regs
->iasq
[0],regs
->iasq
[1]);
125 err
|= __get_user(compat_reg
, &sc
->sc_sar
);
126 /* Load the upper half for sar */
127 err
|= __get_user(compat_regt
, &rf
->rf_sar
);
128 regs
->sar
= ((u64
)compat_regt
<< 32) | (u64
)compat_reg
;
129 DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt
);
130 DBG(2,"restore_sigcontext32: sar is %#lx\n", regs
->sar
);
131 DBG(2,"restore_sigcontext32: r28 is %ld\n", regs
->gr
[28]);
137 * Set up the sigcontext structure for this process.
138 * This is not an easy task if the kernel is 64-bit, it will require
139 * that we examine the process personality to determine if we need to
140 * truncate for a 32-bit userspace.
143 setup_sigcontext32(struct compat_sigcontext __user
*sc
, struct compat_regfile __user
* rf
,
144 struct pt_regs
*regs
, int in_syscall
)
146 compat_int_t flags
= 0;
148 compat_uint_t compat_reg
;
149 compat_uint_t compat_regb
;
152 if (on_sig_stack((unsigned long) sc
))
153 flags
|= PARISC_SC_FLAG_ONSTACK
;
157 DBG(1,"setup_sigcontext32: in_syscall\n");
159 flags
|= PARISC_SC_FLAG_IN_SYSCALL
;
161 compat_reg
= (compat_uint_t
)(regs
->gr
[31]);
162 /* regs->iaoq is undefined in the syscall return path */
163 err
|= __put_user(compat_reg
, &sc
->sc_iaoq
[0]);
164 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
165 &sc
->sc_iaoq
[0], compat_reg
);
167 /* Store upper half */
168 compat_reg
= (compat_uint_t
)(regs
->gr
[31] >> 32);
169 err
|= __put_user(compat_reg
, &rf
->rf_iaoq
[0]);
170 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg
);
173 compat_reg
= (compat_uint_t
)(regs
->gr
[31]+4);
174 err
|= __put_user(compat_reg
, &sc
->sc_iaoq
[1]);
175 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
176 &sc
->sc_iaoq
[1], compat_reg
);
177 /* Store upper half */
178 compat_reg
= (compat_uint_t
)((regs
->gr
[31]+4) >> 32);
179 err
|= __put_user(compat_reg
, &rf
->rf_iaoq
[1]);
180 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg
);
183 compat_reg
= (compat_uint_t
)(regs
->sr
[3]);
184 err
|= __put_user(compat_reg
, &sc
->sc_iasq
[0]);
185 err
|= __put_user(compat_reg
, &sc
->sc_iasq
[1]);
187 /* Store upper half */
188 compat_reg
= (compat_uint_t
)(regs
->sr
[3] >> 32);
189 err
|= __put_user(compat_reg
, &rf
->rf_iasq
[0]);
190 err
|= __put_user(compat_reg
, &rf
->rf_iasq
[1]);
192 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg
);
193 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg
);
194 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
195 regs
->gr
[31], regs
->gr
[31]+4);
199 compat_reg
= (compat_uint_t
)(regs
->iaoq
[0]);
200 err
|= __put_user(compat_reg
, &sc
->sc_iaoq
[0]);
201 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
202 &sc
->sc_iaoq
[0], compat_reg
);
203 /* Store upper half */
204 compat_reg
= (compat_uint_t
)(regs
->iaoq
[0] >> 32);
205 err
|= __put_user(compat_reg
, &rf
->rf_iaoq
[0]);
206 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg
);
208 compat_reg
= (compat_uint_t
)(regs
->iaoq
[1]);
209 err
|= __put_user(compat_reg
, &sc
->sc_iaoq
[1]);
210 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
211 &sc
->sc_iaoq
[1], compat_reg
);
212 /* Store upper half */
213 compat_reg
= (compat_uint_t
)(regs
->iaoq
[1] >> 32);
214 err
|= __put_user(compat_reg
, &rf
->rf_iaoq
[1]);
215 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg
);
218 compat_reg
= (compat_uint_t
)(regs
->iasq
[0]);
219 err
|= __put_user(compat_reg
, &sc
->sc_iasq
[0]);
220 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
221 &sc
->sc_iasq
[0], compat_reg
);
222 /* Store upper half */
223 compat_reg
= (compat_uint_t
)(regs
->iasq
[0] >> 32);
224 err
|= __put_user(compat_reg
, &rf
->rf_iasq
[0]);
225 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg
);
228 compat_reg
= (compat_uint_t
)(regs
->iasq
[1]);
229 err
|= __put_user(compat_reg
, &sc
->sc_iasq
[1]);
230 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
231 &sc
->sc_iasq
[1], compat_reg
);
232 /* Store upper half */
233 compat_reg
= (compat_uint_t
)(regs
->iasq
[1] >> 32);
234 err
|= __put_user(compat_reg
, &rf
->rf_iasq
[1]);
235 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg
);
237 /* Print out the IAOQ for debugging */
238 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
239 regs
->iaoq
[0], regs
->iaoq
[1]);
242 err
|= __put_user(flags
, &sc
->sc_flags
);
244 DBG(1,"setup_sigcontext32: Truncating general registers.\n");
246 for(regn
=0; regn
< 32; regn
++){
247 /* Truncate a general register */
248 compat_reg
= (compat_uint_t
)(regs
->gr
[regn
]);
249 err
|= __put_user(compat_reg
, &sc
->sc_gr
[regn
]);
250 /* Store upper half */
251 compat_regb
= (compat_uint_t
)(regs
->gr
[regn
] >> 32);
252 err
|= __put_user(compat_regb
, &rf
->rf_gr
[regn
]);
254 /* DEBUG: Write out the "upper / lower" register data */
255 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn
,
256 compat_regb
, compat_reg
);
259 /* Copy the floating point registers (same size)
260 XXX: BE WARNED FR's are 64-BIT! */
261 DBG(1,"setup_sigcontext32: Copying from regs to sc, "
262 "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
263 sizeof(regs
->fr
), sizeof(sc
->sc_fr
));
264 err
|= __copy_to_user(sc
->sc_fr
, regs
->fr
, sizeof(regs
->fr
));
266 compat_reg
= (compat_uint_t
)(regs
->sar
);
267 err
|= __put_user(compat_reg
, &sc
->sc_sar
);
268 DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg
);
269 /* Store upper half */
270 compat_reg
= (compat_uint_t
)(regs
->sar
>> 32);
271 err
|= __put_user(compat_reg
, &rf
->rf_sar
);
272 DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg
);
273 DBG(1,"setup_sigcontext32: r28 is %ld\n", regs
->gr
[28]);
279 copy_siginfo_from_user32 (siginfo_t
*to
, compat_siginfo_t __user
*from
)
284 if (!access_ok(VERIFY_READ
, from
, sizeof(compat_siginfo_t
)))
287 err
= __get_user(to
->si_signo
, &from
->si_signo
);
288 err
|= __get_user(to
->si_errno
, &from
->si_errno
);
289 err
|= __get_user(to
->si_code
, &from
->si_code
);
292 err
|= __copy_from_user(&to
->_sifields
._pad
, &from
->_sifields
._pad
, SI_PAD_SIZE
);
294 switch (to
->si_code
>> 16) {
295 case __SI_CHLD
>> 16:
296 err
|= __get_user(to
->si_utime
, &from
->si_utime
);
297 err
|= __get_user(to
->si_stime
, &from
->si_stime
);
298 err
|= __get_user(to
->si_status
, &from
->si_status
);
300 err
|= __get_user(to
->si_pid
, &from
->si_pid
);
301 err
|= __get_user(to
->si_uid
, &from
->si_uid
);
303 case __SI_FAULT
>> 16:
304 err
|= __get_user(addr
, &from
->si_addr
);
305 to
->si_addr
= compat_ptr(addr
);
307 case __SI_POLL
>> 16:
308 err
|= __get_user(to
->si_band
, &from
->si_band
);
309 err
|= __get_user(to
->si_fd
, &from
->si_fd
);
311 case __SI_RT
>> 16: /* This is not generated by the kernel as of now. */
312 case __SI_MESGQ
>> 16:
313 err
|= __get_user(to
->si_pid
, &from
->si_pid
);
314 err
|= __get_user(to
->si_uid
, &from
->si_uid
);
315 err
|= __get_user(to
->si_int
, &from
->si_int
);
323 copy_siginfo_to_user32 (compat_siginfo_t __user
*to
, siginfo_t
*from
)
329 if (!access_ok(VERIFY_WRITE
, to
, sizeof(compat_siginfo_t
)))
332 /* If you change siginfo_t structure, please be sure
333 this code is fixed accordingly.
334 It should never copy any pad contained in the structure
335 to avoid security leaks, but must copy the generic
336 3 ints plus the relevant union member.
337 This routine must convert siginfo from 64bit to 32bit as well
339 err
= __put_user(from
->si_signo
, &to
->si_signo
);
340 err
|= __put_user(from
->si_errno
, &to
->si_errno
);
341 err
|= __put_user((short)from
->si_code
, &to
->si_code
);
342 if (from
->si_code
< 0)
343 err
|= __copy_to_user(&to
->_sifields
._pad
, &from
->_sifields
._pad
, SI_PAD_SIZE
);
345 switch (from
->si_code
>> 16) {
346 case __SI_CHLD
>> 16:
347 err
|= __put_user(from
->si_utime
, &to
->si_utime
);
348 err
|= __put_user(from
->si_stime
, &to
->si_stime
);
349 err
|= __put_user(from
->si_status
, &to
->si_status
);
351 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
352 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
354 case __SI_FAULT
>> 16:
355 addr
= ptr_to_compat(from
->si_addr
);
356 err
|= __put_user(addr
, &to
->si_addr
);
358 case __SI_POLL
>> 16:
359 err
|= __put_user(from
->si_band
, &to
->si_band
);
360 err
|= __put_user(from
->si_fd
, &to
->si_fd
);
362 case __SI_TIMER
>> 16:
363 err
|= __put_user(from
->si_tid
, &to
->si_tid
);
364 err
|= __put_user(from
->si_overrun
, &to
->si_overrun
);
365 val
= (compat_int_t
)from
->si_int
;
366 err
|= __put_user(val
, &to
->si_int
);
368 case __SI_RT
>> 16: /* Not generated by the kernel as of now. */
369 case __SI_MESGQ
>> 16:
370 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
371 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
372 val
= (compat_int_t
)from
->si_int
;
373 err
|= __put_user(val
, &to
->si_int
);