Merge tag 'scsi-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[sfrench/cifs-2.6.git] / arch / parisc / kernel / signal32.c
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 <linux/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
49 long
50 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
51                 struct pt_regs *regs)
52 {
53         long err = 0;
54         compat_uint_t compat_reg;
55         compat_uint_t compat_regt;
56         int regn;
57         
58         /* When loading 32-bit values into 64-bit registers make
59            sure to clear the upper 32-bits */
60         DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
61         DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
62         DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
63         for(regn=0; regn < 32; regn++){
64                 err |= __get_user(compat_reg,&sc->sc_gr[regn]);
65                 regs->gr[regn] = compat_reg;
66                 /* Load upper half */
67                 err |= __get_user(compat_regt,&rf->rf_gr[regn]);
68                 regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
69                 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
70                                 regn, regs->gr[regn], compat_regt, compat_reg);
71         }
72         DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
73         /* XXX: BE WARNED FR's are 64-BIT! */
74         err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
75                 
76         /* Better safe than sorry, pass __get_user two things of
77            the same size and let gcc do the upward conversion to 
78            64-bits */           
79         err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
80         /* Load upper half */
81         err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
82         regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
83         DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
84         DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
85                         &sc->sc_iaoq[0], compat_reg);
86
87         err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
88         /* Load upper half */
89         err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
90         regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
91         DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
92         DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
93                         &sc->sc_iaoq[1],compat_reg);    
94         DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
95                         regs->iaoq[0],regs->iaoq[1]);           
96                 
97         err |= __get_user(compat_reg, &sc->sc_iasq[0]);
98         /* Load the upper half for iasq */
99         err |= __get_user(compat_regt, &rf->rf_iasq[0]);
100         regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
101         DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
102         
103         err |= __get_user(compat_reg, &sc->sc_iasq[1]);
104         /* Load the upper half for iasq */
105         err |= __get_user(compat_regt, &rf->rf_iasq[1]);
106         regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
107         DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
108         DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
109                 regs->iasq[0],regs->iasq[1]);           
110
111         err |= __get_user(compat_reg, &sc->sc_sar);
112         /* Load the upper half for sar */
113         err |= __get_user(compat_regt, &rf->rf_sar);
114         regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg; 
115         DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);  
116         DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);                
117         DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
118         
119         return err;
120 }
121
122 /*
123  * Set up the sigcontext structure for this process.
124  * This is not an easy task if the kernel is 64-bit, it will require
125  * that we examine the process personality to determine if we need to
126  * truncate for a 32-bit userspace.
127  */
128 long
129 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
130                 struct pt_regs *regs, int in_syscall)            
131 {
132         compat_int_t flags = 0;
133         long err = 0;
134         compat_uint_t compat_reg;
135         compat_uint_t compat_regb;
136         int regn;
137         
138         if (on_sig_stack((unsigned long) sc))
139                 flags |= PARISC_SC_FLAG_ONSTACK;
140         
141         if (in_syscall) {
142                 
143                 DBG(1,"setup_sigcontext32: in_syscall\n");
144                 
145                 flags |= PARISC_SC_FLAG_IN_SYSCALL;
146                 /* Truncate gr31 */
147                 compat_reg = (compat_uint_t)(regs->gr[31]);
148                 /* regs->iaoq is undefined in the syscall return path */
149                 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
150                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
151                                 &sc->sc_iaoq[0], compat_reg);
152                 
153                 /* Store upper half */
154                 compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
155                 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
156                 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
157                 
158                 
159                 compat_reg = (compat_uint_t)(regs->gr[31]+4);
160                 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
161                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
162                                 &sc->sc_iaoq[1], compat_reg);
163                 /* Store upper half */
164                 compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
165                 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
166                 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
167                 
168                 /* Truncate sr3 */
169                 compat_reg = (compat_uint_t)(regs->sr[3]);
170                 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
171                 err |= __put_user(compat_reg, &sc->sc_iasq[1]);         
172                 
173                 /* Store upper half */
174                 compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
175                 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
176                 err |= __put_user(compat_reg, &rf->rf_iasq[1]);         
177                 
178                 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
179                 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);            
180                 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",                         
181                         regs->gr[31], regs->gr[31]+4);
182                 
183         } else {
184                 
185                 compat_reg = (compat_uint_t)(regs->iaoq[0]);
186                 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
187                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
188                                 &sc->sc_iaoq[0], compat_reg);
189                 /* Store upper half */
190                 compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
191                 err |= __put_user(compat_reg, &rf->rf_iaoq[0]); 
192                 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
193                 
194                 compat_reg = (compat_uint_t)(regs->iaoq[1]);
195                 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
196                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
197                                 &sc->sc_iaoq[1], compat_reg);
198                 /* Store upper half */
199                 compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
200                 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
201                 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
202                 
203                 
204                 compat_reg = (compat_uint_t)(regs->iasq[0]);
205                 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
206                 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
207                                 &sc->sc_iasq[0], compat_reg);
208                 /* Store upper half */
209                 compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
210                 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
211                 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
212                 
213                 
214                 compat_reg = (compat_uint_t)(regs->iasq[1]);
215                 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
216                 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
217                                 &sc->sc_iasq[1], compat_reg);
218                 /* Store upper half */
219                 compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
220                 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
221                 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
222
223                 /* Print out the IAOQ for debugging */          
224                 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
225                         regs->iaoq[0], regs->iaoq[1]);
226         }
227
228         err |= __put_user(flags, &sc->sc_flags);
229         
230         DBG(1,"setup_sigcontext32: Truncating general registers.\n");
231         
232         for(regn=0; regn < 32; regn++){
233                 /* Truncate a general register */
234                 compat_reg = (compat_uint_t)(regs->gr[regn]);
235                 err |= __put_user(compat_reg, &sc->sc_gr[regn]);
236                 /* Store upper half */
237                 compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
238                 err |= __put_user(compat_regb, &rf->rf_gr[regn]);
239
240                 /* DEBUG: Write out the "upper / lower" register data */
241                 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
242                                 compat_regb, compat_reg);
243         }
244         
245         /* Copy the floating point registers (same size)
246            XXX: BE WARNED FR's are 64-BIT! */   
247         DBG(1,"setup_sigcontext32: Copying from regs to sc, "
248               "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
249                 sizeof(regs->fr), sizeof(sc->sc_fr));
250         err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
251
252         compat_reg = (compat_uint_t)(regs->sar);
253         err |= __put_user(compat_reg, &sc->sc_sar);
254         DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
255         /* Store upper half */
256         compat_reg = (compat_uint_t)(regs->sar >> 32);
257         err |= __put_user(compat_reg, &rf->rf_sar);     
258         DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
259         DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
260
261         return err;
262 }
263
264 int
265 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
266 {
267         compat_uptr_t addr;
268         int err;
269
270         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
271                 return -EFAULT;
272
273         err = __get_user(to->si_signo, &from->si_signo);
274         err |= __get_user(to->si_errno, &from->si_errno);
275         err |= __get_user(to->si_code, &from->si_code);
276
277         if (to->si_code < 0)
278                 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
279         else {
280                 switch (siginfo_layout(to->si_signo, to->si_code)) {
281                       case SIL_CHLD:
282                         err |= __get_user(to->si_utime, &from->si_utime);
283                         err |= __get_user(to->si_stime, &from->si_stime);
284                         err |= __get_user(to->si_status, &from->si_status);
285                       default:
286                       case SIL_KILL:
287                         err |= __get_user(to->si_pid, &from->si_pid);
288                         err |= __get_user(to->si_uid, &from->si_uid);
289                         break;
290                       case SIL_FAULT:
291                         err |= __get_user(addr, &from->si_addr);
292                         to->si_addr = compat_ptr(addr);
293                         break;
294                       case SIL_POLL:
295                         err |= __get_user(to->si_band, &from->si_band);
296                         err |= __get_user(to->si_fd, &from->si_fd);
297                         break;
298                       case SIL_RT:
299                         err |= __get_user(to->si_pid, &from->si_pid);
300                         err |= __get_user(to->si_uid, &from->si_uid);
301                         err |= __get_user(to->si_int, &from->si_int);
302                         break;
303                 }
304         }
305         return err;
306 }
307
308 int
309 copy_siginfo_to_user32 (compat_siginfo_t __user *to, const siginfo_t *from)
310 {
311         compat_uptr_t addr;
312         compat_int_t val;
313         int err;
314
315         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
316                 return -EFAULT;
317
318         /* If you change siginfo_t structure, please be sure
319            this code is fixed accordingly.
320            It should never copy any pad contained in the structure
321            to avoid security leaks, but must copy the generic
322            3 ints plus the relevant union member.
323            This routine must convert siginfo from 64bit to 32bit as well
324            at the same time.  */
325         err = __put_user(from->si_signo, &to->si_signo);
326         err |= __put_user(from->si_errno, &to->si_errno);
327         err |= __put_user(from->si_code, &to->si_code);
328         if (from->si_code < 0)
329                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
330         else {
331                 switch (siginfo_layout(from->si_signo, from->si_code)) {
332                 case SIL_CHLD:
333                         err |= __put_user(from->si_utime, &to->si_utime);
334                         err |= __put_user(from->si_stime, &to->si_stime);
335                         err |= __put_user(from->si_status, &to->si_status);
336                 case SIL_KILL:
337                         err |= __put_user(from->si_pid, &to->si_pid);
338                         err |= __put_user(from->si_uid, &to->si_uid);
339                         break;
340                 case SIL_FAULT:
341                         addr = ptr_to_compat(from->si_addr);
342                         err |= __put_user(addr, &to->si_addr);
343                         break;
344                 case SIL_POLL:
345                         err |= __put_user(from->si_band, &to->si_band);
346                         err |= __put_user(from->si_fd, &to->si_fd);
347                         break;
348                 case SIL_TIMER:
349                         err |= __put_user(from->si_tid, &to->si_tid);
350                         err |= __put_user(from->si_overrun, &to->si_overrun);
351                         val = (compat_int_t)from->si_int;
352                         err |= __put_user(val, &to->si_int);
353                         break;
354                 case SIL_RT:
355                         err |= __put_user(from->si_uid, &to->si_uid);
356                         err |= __put_user(from->si_pid, &to->si_pid);
357                         val = (compat_int_t)from->si_int;
358                         err |= __put_user(val, &to->si_int);
359                         break;
360                 case SIL_SYS:
361                         err |= __put_user(ptr_to_compat(from->si_call_addr), &to->si_call_addr);
362                         err |= __put_user(from->si_syscall, &to->si_syscall);
363                         err |= __put_user(from->si_arch, &to->si_arch);
364                         break;
365                 }
366         }
367         return err;
368 }