diff options
author | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-10-17 21:17:58 -0400 |
---|---|---|
committer | Stephen Rothwell <sfr@canb.auug.org.au> | 2005-10-17 21:17:58 -0400 |
commit | 81e7009ea46c951860b8716ee427ff4f54dd26fc (patch) | |
tree | cd9724dac4d04a2e03f4042adbcc86fdc2d037b7 | |
parent | 55d363397f1bdfa4fe861f0e2fadb058c79dafea (diff) |
powerpc: merge ppc signal.c and ppc64 signal32.c
Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
-rw-r--r-- | arch/powerpc/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/signal_32.c (renamed from arch/ppc64/kernel/signal32.c) | 977 | ||||
-rw-r--r-- | arch/ppc/kernel/Makefile | 4 | ||||
-rw-r--r-- | arch/ppc/kernel/signal.c | 771 | ||||
-rw-r--r-- | arch/ppc64/kernel/Makefile | 2 | ||||
-rw-r--r-- | include/asm-ppc64/ppc32.h | 14 |
6 files changed, 635 insertions, 1135 deletions
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 1ca740bc5b47..043ddd09521d 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -10,7 +10,7 @@ CFLAGS_prom_init.o += -fPIC | |||
10 | CFLAGS_btext.o += -fPIC | 10 | CFLAGS_btext.o += -fPIC |
11 | endif | 11 | endif |
12 | 12 | ||
13 | obj-y := semaphore.o cputable.o ptrace.o | 13 | obj-y := semaphore.o cputable.o ptrace.o signal_32.o |
14 | obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o | 14 | obj-$(CONFIG_PPC64) += binfmt_elf32.o sys_ppc32.o |
15 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 15 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
16 | obj-$(CONFIG_POWER4) += idle_power4.o | 16 | obj-$(CONFIG_POWER4) += idle_power4.o |
diff --git a/arch/ppc64/kernel/signal32.c b/arch/powerpc/kernel/signal_32.c index a8b7a5a56bb4..e53127ec373d 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/powerpc/kernel/signal_32.c | |||
@@ -1,56 +1,352 @@ | |||
1 | /* | 1 | /* |
2 | * signal32.c: Support 32bit signal syscalls. | 2 | * Signal handling for 32bit PPC and 32bit tasks on 64bit PPC |
3 | * | 3 | * |
4 | * PowerPC version | ||
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
4 | * Copyright (C) 2001 IBM | 6 | * Copyright (C) 2001 IBM |
5 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | 7 | * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) |
6 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) | 8 | * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) |
7 | * | 9 | * |
8 | * These routines maintain argument size conversion between 32bit and 64bit | 10 | * Derived from "arch/i386/kernel/signal.c" |
9 | * environment. | 11 | * Copyright (C) 1991, 1992 Linus Torvalds |
12 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
10 | * | 13 | * |
11 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | 15 | * modify it under the terms of the GNU General Public License |
13 | * as published by the Free Software Foundation; either version | 16 | * as published by the Free Software Foundation; either version |
14 | * 2 of the License, or (at your option) any later version. | 17 | * 2 of the License, or (at your option) any later version. |
15 | */ | 18 | */ |
16 | 19 | ||
17 | #include <linux/config.h> | 20 | #include <linux/config.h> |
18 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
19 | #include <linux/mm.h> | 22 | #include <linux/mm.h> |
20 | #include <linux/smp.h> | 23 | #include <linux/smp.h> |
21 | #include <linux/smp_lock.h> | 24 | #include <linux/smp_lock.h> |
22 | #include <linux/kernel.h> | 25 | #include <linux/kernel.h> |
23 | #include <linux/signal.h> | 26 | #include <linux/signal.h> |
24 | #include <linux/syscalls.h> | ||
25 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
26 | #include <linux/elf.h> | 28 | #include <linux/elf.h> |
29 | #ifdef CONFIG_PPC64 | ||
30 | #include <linux/syscalls.h> | ||
27 | #include <linux/compat.h> | 31 | #include <linux/compat.h> |
28 | #include <linux/ptrace.h> | 32 | #include <linux/ptrace.h> |
29 | #include <asm/ppc32.h> | 33 | #else |
34 | #include <linux/wait.h> | ||
35 | #include <linux/ptrace.h> | ||
36 | #include <linux/unistd.h> | ||
37 | #include <linux/stddef.h> | ||
38 | #include <linux/tty.h> | ||
39 | #include <linux/binfmts.h> | ||
40 | #include <linux/suspend.h> | ||
41 | #endif | ||
42 | |||
30 | #include <asm/uaccess.h> | 43 | #include <asm/uaccess.h> |
44 | #include <asm/cacheflush.h> | ||
45 | #ifdef CONFIG_PPC64 | ||
46 | #include <asm/ppc32.h> | ||
31 | #include <asm/ppcdebug.h> | 47 | #include <asm/ppcdebug.h> |
32 | #include <asm/unistd.h> | 48 | #include <asm/unistd.h> |
33 | #include <asm/cacheflush.h> | ||
34 | #include <asm/vdso.h> | 49 | #include <asm/vdso.h> |
50 | #else | ||
51 | #include <asm/ucontext.h> | ||
52 | #include <asm/pgtable.h> | ||
53 | #endif | ||
35 | 54 | ||
36 | #define DEBUG_SIG 0 | 55 | #undef DEBUG_SIG |
37 | 56 | ||
38 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 57 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
39 | 58 | ||
40 | #define GP_REGS_SIZE32 min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) | 59 | #ifdef CONFIG_PPC64 |
60 | #define do_signal do_signal32 | ||
61 | #define sys_sigsuspend sys32_sigsuspend | ||
62 | #define sys_rt_sigsuspend sys32_rt_sigsuspend | ||
63 | #define sys_rt_sigreturn sys32_rt_sigreturn | ||
64 | #define sys_sigaction sys32_sigaction | ||
65 | #define sys_swapcontext sys32_swapcontext | ||
66 | #define sys_sigreturn sys32_sigreturn | ||
67 | |||
68 | #define old_sigaction old_sigaction32 | ||
69 | #define sigcontext sigcontext32 | ||
70 | #define mcontext mcontext32 | ||
71 | #define ucontext ucontext32 | ||
72 | |||
73 | /* | ||
74 | * Returning 0 means we return to userspace via | ||
75 | * ret_from_except and thus restore all user | ||
76 | * registers from *regs. This is what we need | ||
77 | * to do when a signal has been delivered. | ||
78 | */ | ||
79 | #define sigreturn_exit(regs) return 0 | ||
80 | |||
81 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32)) | ||
82 | #undef __SIGNAL_FRAMESIZE | ||
83 | #define __SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE32 | ||
84 | #undef ELF_NVRREG | ||
85 | #define ELF_NVRREG ELF_NVRREG32 | ||
86 | |||
87 | /* | ||
88 | * Functions for flipping sigsets (thanks to brain dead generic | ||
89 | * implementation that makes things simple for little endian only) | ||
90 | */ | ||
91 | static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) | ||
92 | { | ||
93 | compat_sigset_t cset; | ||
94 | |||
95 | switch (_NSIG_WORDS) { | ||
96 | case 4: cset.sig[5] = set->sig[3] & 0xffffffffull; | ||
97 | cset.sig[7] = set->sig[3] >> 32; | ||
98 | case 3: cset.sig[4] = set->sig[2] & 0xffffffffull; | ||
99 | cset.sig[5] = set->sig[2] >> 32; | ||
100 | case 2: cset.sig[2] = set->sig[1] & 0xffffffffull; | ||
101 | cset.sig[3] = set->sig[1] >> 32; | ||
102 | case 1: cset.sig[0] = set->sig[0] & 0xffffffffull; | ||
103 | cset.sig[1] = set->sig[0] >> 32; | ||
104 | } | ||
105 | return copy_to_user(uset, &cset, sizeof(*uset)); | ||
106 | } | ||
107 | |||
108 | static inline int get_sigset_t(sigset_t *set, compat_sigset_t __user *uset) | ||
109 | { | ||
110 | compat_sigset_t s32; | ||
111 | |||
112 | if (copy_from_user(&s32, uset, sizeof(*uset))) | ||
113 | return -EFAULT; | ||
114 | |||
115 | /* | ||
116 | * Swap the 2 words of the 64-bit sigset_t (they are stored | ||
117 | * in the "wrong" endian in 32-bit user storage). | ||
118 | */ | ||
119 | switch (_NSIG_WORDS) { | ||
120 | case 4: set->sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); | ||
121 | case 3: set->sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); | ||
122 | case 2: set->sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); | ||
123 | case 1: set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); | ||
124 | } | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static inline int get_old_sigaction(struct k_sigaction *new_ka, | ||
129 | struct old_sigaction __user *act) | ||
130 | { | ||
131 | compat_old_sigset_t mask; | ||
132 | compat_uptr_t handler, restorer; | ||
133 | |||
134 | if (get_user(handler, &act->sa_handler) || | ||
135 | __get_user(restorer, &act->sa_restorer) || | ||
136 | __get_user(new_ka->sa.sa_flags, &act->sa_flags) || | ||
137 | __get_user(mask, &act->sa_mask)) | ||
138 | return -EFAULT; | ||
139 | new_ka->sa.sa_handler = compat_ptr(handler); | ||
140 | new_ka->sa.sa_restorer = compat_ptr(restorer); | ||
141 | siginitset(&new_ka->sa.sa_mask, mask); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | static inline compat_uptr_t to_user_ptr(void *kp) | ||
146 | { | ||
147 | return (compat_uptr_t)(u64)kp; | ||
148 | } | ||
149 | |||
150 | #define from_user_ptr(p) compat_ptr(p) | ||
151 | |||
152 | static inline int save_general_regs(struct pt_regs *regs, | ||
153 | struct mcontext __user *frame) | ||
154 | { | ||
155 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; | ||
156 | int i; | ||
157 | |||
158 | for (i = 0; i <= PT_RESULT; i ++) | ||
159 | if (__put_user((unsigned int)gregs[i], &frame->mc_gregs[i])) | ||
160 | return -EFAULT; | ||
161 | return 0; | ||
162 | } | ||
163 | |||
164 | static inline int restore_general_regs(struct pt_regs *regs, | ||
165 | struct mcontext __user *sr) | ||
166 | { | ||
167 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; | ||
168 | int i; | ||
169 | |||
170 | for (i = 0; i <= PT_RESULT; i++) { | ||
171 | if ((i == PT_MSR) || (i == PT_SOFTE)) | ||
172 | continue; | ||
173 | if (__get_user(gregs[i], &sr->mc_gregs[i])) | ||
174 | return -EFAULT; | ||
175 | } | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | #else /* CONFIG_PPC64 */ | ||
180 | |||
181 | extern void sigreturn_exit(struct pt_regs *); | ||
182 | |||
183 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | ||
184 | |||
185 | static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set) | ||
186 | { | ||
187 | return copy_to_user(uset, set, sizeof(*uset)); | ||
188 | } | ||
189 | |||
190 | static inline int get_sigset_t(sigset_t *set, sigset_t __user *uset) | ||
191 | { | ||
192 | return copy_from_user(set, uset, sizeof(*uset)); | ||
193 | } | ||
194 | |||
195 | static inline int get_old_sigaction(struct k_sigaction *new_ka, | ||
196 | struct old_sigaction __user *act) | ||
197 | { | ||
198 | old_sigset_t mask; | ||
199 | |||
200 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
201 | __get_user(new_ka->sa.sa_handler, &act->sa_handler) || | ||
202 | __get_user(new_ka->sa.sa_restorer, &act->sa_restorer)) | ||
203 | return -EFAULT; | ||
204 | __get_user(new_ka->sa.sa_flags, &act->sa_flags); | ||
205 | __get_user(mask, &act->sa_mask); | ||
206 | siginitset(&new_ka->sa.sa_mask, mask); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | #define to_user_ptr(p) (p) | ||
211 | #define from_user_ptr(p) (p) | ||
212 | |||
213 | static inline int save_general_regs(struct pt_regs *regs, | ||
214 | struct mcontext __user *frame) | ||
215 | { | ||
216 | return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE); | ||
217 | } | ||
218 | |||
219 | static inline int restore_general_regs(struct pt_regs *regs, | ||
220 | struct mcontext __user *sr) | ||
221 | { | ||
222 | /* copy up to but not including MSR */ | ||
223 | if (__copy_from_user(regs, &sr->mc_gregs, | ||
224 | PT_MSR * sizeof(elf_greg_t))) | ||
225 | return -EFAULT; | ||
226 | /* copy from orig_r3 (the word after the MSR) up to the end */ | ||
227 | if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3], | ||
228 | GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t))) | ||
229 | return -EFAULT; | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | #endif /* CONFIG_PPC64 */ | ||
234 | |||
235 | int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
236 | |||
237 | /* | ||
238 | * Atomically swap in the new signal mask, and wait for a signal. | ||
239 | */ | ||
240 | long sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, | ||
241 | struct pt_regs *regs) | ||
242 | { | ||
243 | sigset_t saveset; | ||
244 | |||
245 | mask &= _BLOCKABLE; | ||
246 | spin_lock_irq(¤t->sighand->siglock); | ||
247 | saveset = current->blocked; | ||
248 | siginitset(¤t->blocked, mask); | ||
249 | recalc_sigpending(); | ||
250 | spin_unlock_irq(¤t->sighand->siglock); | ||
251 | |||
252 | regs->result = -EINTR; | ||
253 | regs->gpr[3] = EINTR; | ||
254 | regs->ccr |= 0x10000000; | ||
255 | while (1) { | ||
256 | current->state = TASK_INTERRUPTIBLE; | ||
257 | schedule(); | ||
258 | if (do_signal(&saveset, regs)) | ||
259 | sigreturn_exit(regs); | ||
260 | } | ||
261 | } | ||
262 | |||
263 | long sys_rt_sigsuspend( | ||
264 | #ifdef CONFIG_PPC64 | ||
265 | compat_sigset_t __user *unewset, | ||
266 | #else | ||
267 | sigset_t __user *unewset, | ||
268 | #endif | ||
269 | size_t sigsetsize, int p3, int p4, | ||
270 | int p6, int p7, struct pt_regs *regs) | ||
271 | { | ||
272 | sigset_t saveset, newset; | ||
273 | |||
274 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
275 | if (sigsetsize != sizeof(sigset_t)) | ||
276 | return -EINVAL; | ||
277 | |||
278 | if (get_sigset_t(&newset, unewset)) | ||
279 | return -EFAULT; | ||
280 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
281 | |||
282 | spin_lock_irq(¤t->sighand->siglock); | ||
283 | saveset = current->blocked; | ||
284 | current->blocked = newset; | ||
285 | recalc_sigpending(); | ||
286 | spin_unlock_irq(¤t->sighand->siglock); | ||
287 | |||
288 | regs->result = -EINTR; | ||
289 | regs->gpr[3] = EINTR; | ||
290 | regs->ccr |= 0x10000000; | ||
291 | while (1) { | ||
292 | current->state = TASK_INTERRUPTIBLE; | ||
293 | schedule(); | ||
294 | if (do_signal(&saveset, regs)) | ||
295 | sigreturn_exit(regs); | ||
296 | } | ||
297 | } | ||
298 | |||
299 | #ifdef CONFIG_PPC32 | ||
300 | long sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5, | ||
301 | int r6, int r7, int r8, struct pt_regs *regs) | ||
302 | { | ||
303 | return do_sigaltstack(uss, uoss, regs->gpr[1]); | ||
304 | } | ||
305 | #endif | ||
306 | |||
307 | long sys_sigaction(int sig, struct old_sigaction __user *act, | ||
308 | struct old_sigaction __user *oact) | ||
309 | { | ||
310 | struct k_sigaction new_ka, old_ka; | ||
311 | int ret; | ||
312 | |||
313 | #ifdef CONFIG_PPC64 | ||
314 | if (sig < 0) | ||
315 | sig = -sig; | ||
316 | #endif | ||
317 | |||
318 | if (act) { | ||
319 | if (get_old_sigaction(&new_ka, act)) | ||
320 | return -EFAULT; | ||
321 | } | ||
322 | |||
323 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
324 | if (!ret && oact) { | ||
325 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
326 | __put_user(to_user_ptr(old_ka.sa.sa_handler), | ||
327 | &oact->sa_handler) || | ||
328 | __put_user(to_user_ptr(old_ka.sa.sa_restorer), | ||
329 | &oact->sa_restorer) || | ||
330 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
331 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
332 | return -EFAULT; | ||
333 | } | ||
334 | |||
335 | return ret; | ||
336 | } | ||
41 | 337 | ||
42 | /* | 338 | /* |
43 | * When we have signals to deliver, we set up on the | 339 | * When we have signals to deliver, we set up on the |
44 | * user stack, going down from the original stack pointer: | 340 | * user stack, going down from the original stack pointer: |
45 | * a sigregs32 struct | 341 | * a sigregs struct |
46 | * a sigcontext32 struct | 342 | * a sigcontext struct |
47 | * a gap of __SIGNAL_FRAMESIZE32 bytes | 343 | * a gap of __SIGNAL_FRAMESIZE bytes |
48 | * | 344 | * |
49 | * Each of these things must be a multiple of 16 bytes in size. | 345 | * Each of these things must be a multiple of 16 bytes in size. |
50 | * | 346 | * |
51 | */ | 347 | */ |
52 | struct sigregs32 { | 348 | struct sigregs { |
53 | struct mcontext32 mctx; /* all the register values */ | 349 | struct mcontext mctx; /* all the register values */ |
54 | /* | 350 | /* |
55 | * Programs using the rs6000/xcoff abi can save up to 19 gp | 351 | * Programs using the rs6000/xcoff abi can save up to 19 gp |
56 | * regs and 18 fp regs below sp before decrementing it. | 352 | * regs and 18 fp regs below sp before decrementing it. |
@@ -64,17 +360,21 @@ struct sigregs32 { | |||
64 | /* | 360 | /* |
65 | * When we have rt signals to deliver, we set up on the | 361 | * When we have rt signals to deliver, we set up on the |
66 | * user stack, going down from the original stack pointer: | 362 | * user stack, going down from the original stack pointer: |
67 | * one rt_sigframe32 struct (siginfo + ucontext + ABI gap) | 363 | * one rt_sigframe struct (siginfo + ucontext + ABI gap) |
68 | * a gap of __SIGNAL_FRAMESIZE32+16 bytes | 364 | * a gap of __SIGNAL_FRAMESIZE+16 bytes |
69 | * (the +16 is to get the siginfo and ucontext32 in the same | 365 | * (the +16 is to get the siginfo and ucontext in the same |
70 | * positions as in older kernels). | 366 | * positions as in older kernels). |
71 | * | 367 | * |
72 | * Each of these things must be a multiple of 16 bytes in size. | 368 | * Each of these things must be a multiple of 16 bytes in size. |
73 | * | 369 | * |
74 | */ | 370 | */ |
75 | struct rt_sigframe32 { | 371 | struct rt_sigframe { |
76 | compat_siginfo_t info; | 372 | #ifdef CONFIG_PPC64 |
77 | struct ucontext32 uc; | 373 | compat_siginfo_t info; |
374 | #else | ||
375 | struct siginfo info; | ||
376 | #endif | ||
377 | struct ucontext uc; | ||
78 | /* | 378 | /* |
79 | * Programs using the rs6000/xcoff abi can save up to 19 gp | 379 | * Programs using the rs6000/xcoff abi can save up to 19 gp |
80 | * regs and 18 fp regs below sp before decrementing it. | 380 | * regs and 18 fp regs below sp before decrementing it. |
@@ -82,66 +382,24 @@ struct rt_sigframe32 { | |||
82 | int abigap[56]; | 382 | int abigap[56]; |
83 | }; | 383 | }; |
84 | 384 | ||
85 | |||
86 | /* | ||
87 | * Common utility functions used by signal and context support | ||
88 | * | ||
89 | */ | ||
90 | |||
91 | /* | ||
92 | * Restore the user process's signal mask | ||
93 | * (implemented in signal.c) | ||
94 | */ | ||
95 | extern void restore_sigmask(sigset_t *set); | ||
96 | |||
97 | /* | ||
98 | * Functions for flipping sigsets (thanks to brain dead generic | ||
99 | * implementation that makes things simple for little endian only | ||
100 | */ | ||
101 | static inline void compat_from_sigset(compat_sigset_t *compat, sigset_t *set) | ||
102 | { | ||
103 | switch (_NSIG_WORDS) { | ||
104 | case 4: compat->sig[5] = set->sig[3] & 0xffffffffull ; | ||
105 | compat->sig[7] = set->sig[3] >> 32; | ||
106 | case 3: compat->sig[4] = set->sig[2] & 0xffffffffull ; | ||
107 | compat->sig[5] = set->sig[2] >> 32; | ||
108 | case 2: compat->sig[2] = set->sig[1] & 0xffffffffull ; | ||
109 | compat->sig[3] = set->sig[1] >> 32; | ||
110 | case 1: compat->sig[0] = set->sig[0] & 0xffffffffull ; | ||
111 | compat->sig[1] = set->sig[0] >> 32; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | static inline void sigset_from_compat(sigset_t *set, compat_sigset_t *compat) | ||
116 | { | ||
117 | switch (_NSIG_WORDS) { | ||
118 | case 4: set->sig[3] = compat->sig[6] | (((long)compat->sig[7]) << 32); | ||
119 | case 3: set->sig[2] = compat->sig[4] | (((long)compat->sig[5]) << 32); | ||
120 | case 2: set->sig[1] = compat->sig[2] | (((long)compat->sig[3]) << 32); | ||
121 | case 1: set->sig[0] = compat->sig[0] | (((long)compat->sig[1]) << 32); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | |||
126 | /* | 385 | /* |
127 | * Save the current user registers on the user stack. | 386 | * Save the current user registers on the user stack. |
128 | * We only save the altivec registers if the process has used | 387 | * We only save the altivec/spe registers if the process has used |
129 | * altivec instructions at some point. | 388 | * altivec/spe instructions at some point. |
130 | */ | 389 | */ |
131 | static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, int sigret) | 390 | static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, |
391 | int sigret) | ||
132 | { | 392 | { |
133 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; | 393 | #ifdef CONFIG_PPC32 |
134 | int i, err = 0; | 394 | CHECK_FULL_REGS(regs); |
135 | 395 | #endif | |
136 | /* Make sure floating point registers are stored in regs */ | 396 | /* Make sure floating point registers are stored in regs */ |
137 | flush_fp_to_thread(current); | 397 | flush_fp_to_thread(current); |
138 | 398 | ||
139 | /* save general and floating-point registers */ | 399 | /* save general and floating-point registers */ |
140 | for (i = 0; i <= PT_RESULT; i ++) | 400 | if (save_general_regs(regs, frame) || |
141 | err |= __put_user((unsigned int)gregs[i], &frame->mc_gregs[i]); | 401 | __copy_to_user(&frame->mc_fregs, current->thread.fpr, |
142 | err |= __copy_to_user(&frame->mc_fregs, current->thread.fpr, | 402 | ELF_NFPREG * sizeof(double))) |
143 | ELF_NFPREG * sizeof(double)); | ||
144 | if (err) | ||
145 | return 1; | 403 | return 1; |
146 | 404 | ||
147 | current->thread.fpscr = 0; /* turn off all fp exceptions */ | 405 | current->thread.fpscr = 0; /* turn off all fp exceptions */ |
@@ -151,7 +409,7 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, | |||
151 | if (current->thread.used_vr) { | 409 | if (current->thread.used_vr) { |
152 | flush_altivec_to_thread(current); | 410 | flush_altivec_to_thread(current); |
153 | if (__copy_to_user(&frame->mc_vregs, current->thread.vr, | 411 | if (__copy_to_user(&frame->mc_vregs, current->thread.vr, |
154 | ELF_NVRREG32 * sizeof(vector128))) | 412 | ELF_NVRREG * sizeof(vector128))) |
155 | return 1; | 413 | return 1; |
156 | /* set MSR_VEC in the saved MSR value to indicate that | 414 | /* set MSR_VEC in the saved MSR value to indicate that |
157 | frame->mc_vregs contains valid data */ | 415 | frame->mc_vregs contains valid data */ |
@@ -169,6 +427,25 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, | |||
169 | return 1; | 427 | return 1; |
170 | #endif /* CONFIG_ALTIVEC */ | 428 | #endif /* CONFIG_ALTIVEC */ |
171 | 429 | ||
430 | #ifdef CONFIG_SPE | ||
431 | /* save spe registers */ | ||
432 | if (current->thread.used_spe) { | ||
433 | flush_spe_to_thread(current); | ||
434 | if (__copy_to_user(&frame->mc_vregs, current->thread.evr, | ||
435 | ELF_NEVRREG * sizeof(u32))) | ||
436 | return 1; | ||
437 | /* set MSR_SPE in the saved MSR value to indicate that | ||
438 | frame->mc_vregs contains valid data */ | ||
439 | if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR])) | ||
440 | return 1; | ||
441 | } | ||
442 | /* else assert((regs->msr & MSR_SPE) == 0) */ | ||
443 | |||
444 | /* We always copy to/from spefscr */ | ||
445 | if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG)) | ||
446 | return 1; | ||
447 | #endif /* CONFIG_SPE */ | ||
448 | |||
172 | if (sigret) { | 449 | if (sigret) { |
173 | /* Set up the sigreturn trampoline: li r0,sigret; sc */ | 450 | /* Set up the sigreturn trampoline: li r0,sigret; sc */ |
174 | if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) | 451 | if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) |
@@ -186,13 +463,11 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext32 __user *frame, | |||
186 | * (except for MSR). | 463 | * (except for MSR). |
187 | */ | 464 | */ |
188 | static long restore_user_regs(struct pt_regs *regs, | 465 | static long restore_user_regs(struct pt_regs *regs, |
189 | struct mcontext32 __user *sr, int sig) | 466 | struct mcontext __user *sr, int sig) |
190 | { | 467 | { |
191 | elf_greg_t64 *gregs = (elf_greg_t64 *)regs; | 468 | long err; |
192 | int i; | ||
193 | long err = 0; | ||
194 | unsigned int save_r2 = 0; | 469 | unsigned int save_r2 = 0; |
195 | #ifdef CONFIG_ALTIVEC | 470 | #if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) |
196 | unsigned long msr; | 471 | unsigned long msr; |
197 | #endif | 472 | #endif |
198 | 473 | ||
@@ -202,11 +477,7 @@ static long restore_user_regs(struct pt_regs *regs, | |||
202 | */ | 477 | */ |
203 | if (!sig) | 478 | if (!sig) |
204 | save_r2 = (unsigned int)regs->gpr[2]; | 479 | save_r2 = (unsigned int)regs->gpr[2]; |
205 | for (i = 0; i <= PT_RESULT; i++) { | 480 | err = restore_general_regs(regs, sr); |
206 | if ((i == PT_MSR) || (i == PT_SOFTE)) | ||
207 | continue; | ||
208 | err |= __get_user(gregs[i], &sr->mc_gregs[i]); | ||
209 | } | ||
210 | if (!sig) | 481 | if (!sig) |
211 | regs->gpr[2] = (unsigned long) save_r2; | 482 | regs->gpr[2] = (unsigned long) save_r2; |
212 | if (err) | 483 | if (err) |
@@ -229,135 +500,51 @@ static long restore_user_regs(struct pt_regs *regs, | |||
229 | sizeof(sr->mc_vregs))) | 500 | sizeof(sr->mc_vregs))) |
230 | return 1; | 501 | return 1; |
231 | } else if (current->thread.used_vr) | 502 | } else if (current->thread.used_vr) |
232 | memset(current->thread.vr, 0, ELF_NVRREG32 * sizeof(vector128)); | 503 | memset(current->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); |
233 | 504 | ||
234 | /* Always get VRSAVE back */ | 505 | /* Always get VRSAVE back */ |
235 | if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) | 506 | if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) |
236 | return 1; | 507 | return 1; |
237 | #endif /* CONFIG_ALTIVEC */ | 508 | #endif /* CONFIG_ALTIVEC */ |
238 | 509 | ||
510 | #ifdef CONFIG_SPE | ||
511 | /* force the process to reload the spe registers from | ||
512 | current->thread when it next does spe instructions */ | ||
513 | regs->msr &= ~MSR_SPE; | ||
514 | if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { | ||
515 | /* restore spe registers from the stack */ | ||
516 | if (__copy_from_user(current->thread.evr, &sr->mc_vregs, | ||
517 | ELF_NEVRREG * sizeof(u32))) | ||
518 | return 1; | ||
519 | } else if (current->thread.used_spe) | ||
520 | memset(current->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); | ||
521 | |||
522 | /* Always get SPEFSCR back */ | ||
523 | if (__get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG)) | ||
524 | return 1; | ||
525 | #endif /* CONFIG_SPE */ | ||
526 | |||
239 | #ifndef CONFIG_SMP | 527 | #ifndef CONFIG_SMP |
240 | preempt_disable(); | 528 | preempt_disable(); |
241 | if (last_task_used_math == current) | 529 | if (last_task_used_math == current) |
242 | last_task_used_math = NULL; | 530 | last_task_used_math = NULL; |
243 | if (last_task_used_altivec == current) | 531 | if (last_task_used_altivec == current) |
244 | last_task_used_altivec = NULL; | 532 | last_task_used_altivec = NULL; |
533 | #ifdef CONFIG_SPE | ||
534 | if (last_task_used_spe == current) | ||
535 | last_task_used_spe = NULL; | ||
536 | #endif | ||
245 | preempt_enable(); | 537 | preempt_enable(); |
246 | #endif | 538 | #endif |
247 | return 0; | 539 | return 0; |
248 | } | 540 | } |
249 | 541 | ||
250 | 542 | #ifdef CONFIG_PPC64 | |
251 | /* | ||
252 | * Start of nonRT signal support | ||
253 | * | ||
254 | * sigset_t is 32 bits for non-rt signals | ||
255 | * | ||
256 | * System Calls | ||
257 | * sigaction sys32_sigaction | ||
258 | * sigreturn sys32_sigreturn | ||
259 | * | ||
260 | * Note sigsuspend has no special 32 bit routine - uses the 64 bit routine | ||
261 | * | ||
262 | * Other routines | ||
263 | * setup_frame32 | ||
264 | */ | ||
265 | |||
266 | /* | ||
267 | * Atomically swap in the new signal mask, and wait for a signal. | ||
268 | */ | ||
269 | long sys32_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, | ||
270 | struct pt_regs *regs) | ||
271 | { | ||
272 | sigset_t saveset; | ||
273 | |||
274 | mask &= _BLOCKABLE; | ||
275 | spin_lock_irq(¤t->sighand->siglock); | ||
276 | saveset = current->blocked; | ||
277 | siginitset(¤t->blocked, mask); | ||
278 | recalc_sigpending(); | ||
279 | spin_unlock_irq(¤t->sighand->siglock); | ||
280 | |||
281 | regs->result = -EINTR; | ||
282 | regs->gpr[3] = EINTR; | ||
283 | regs->ccr |= 0x10000000; | ||
284 | while (1) { | ||
285 | current->state = TASK_INTERRUPTIBLE; | ||
286 | schedule(); | ||
287 | if (do_signal32(&saveset, regs)) | ||
288 | /* | ||
289 | * Returning 0 means we return to userspace via | ||
290 | * ret_from_except and thus restore all user | ||
291 | * registers from *regs. This is what we need | ||
292 | * to do when a signal has been delivered. | ||
293 | */ | ||
294 | return 0; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | long sys32_sigaction(int sig, struct old_sigaction32 __user *act, | ||
299 | struct old_sigaction32 __user *oact) | ||
300 | { | ||
301 | struct k_sigaction new_ka, old_ka; | ||
302 | int ret; | ||
303 | |||
304 | if (sig < 0) | ||
305 | sig = -sig; | ||
306 | |||
307 | if (act) { | ||
308 | compat_old_sigset_t mask; | ||
309 | compat_uptr_t handler, restorer; | ||
310 | |||
311 | if (get_user(handler, &act->sa_handler) || | ||
312 | __get_user(restorer, &act->sa_restorer) || | ||
313 | __get_user(new_ka.sa.sa_flags, &act->sa_flags) || | ||
314 | __get_user(mask, &act->sa_mask)) | ||
315 | return -EFAULT; | ||
316 | new_ka.sa.sa_handler = compat_ptr(handler); | ||
317 | new_ka.sa.sa_restorer = compat_ptr(restorer); | ||
318 | siginitset(&new_ka.sa.sa_mask, mask); | ||
319 | } | ||
320 | |||
321 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | ||
322 | if (!ret && oact) { | ||
323 | if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || | ||
324 | __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || | ||
325 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || | ||
326 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) | ||
327 | return -EFAULT; | ||
328 | } | ||
329 | |||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | |||
334 | |||
335 | /* | ||
336 | * Start of RT signal support | ||
337 | * | ||
338 | * sigset_t is 64 bits for rt signals | ||
339 | * | ||
340 | * System Calls | ||
341 | * sigaction sys32_rt_sigaction | ||
342 | * sigpending sys32_rt_sigpending | ||
343 | * sigprocmask sys32_rt_sigprocmask | ||
344 | * sigreturn sys32_rt_sigreturn | ||
345 | * sigqueueinfo sys32_rt_sigqueueinfo | ||
346 | * sigsuspend sys32_rt_sigsuspend | ||
347 | * | ||
348 | * Other routines | ||
349 | * setup_rt_frame32 | ||
350 | * copy_siginfo_to_user32 | ||
351 | * siginfo32to64 | ||
352 | */ | ||
353 | |||
354 | |||
355 | long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, | 543 | long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, |
356 | struct sigaction32 __user *oact, size_t sigsetsize) | 544 | struct sigaction32 __user *oact, size_t sigsetsize) |
357 | { | 545 | { |
358 | struct k_sigaction new_ka, old_ka; | 546 | struct k_sigaction new_ka, old_ka; |
359 | int ret; | 547 | int ret; |
360 | compat_sigset_t set32; | ||
361 | 548 | ||
362 | /* XXX: Don't preclude handling different sized sigset_t's. */ | 549 | /* XXX: Don't preclude handling different sized sigset_t's. */ |
363 | if (sigsetsize != sizeof(compat_sigset_t)) | 550 | if (sigsetsize != sizeof(compat_sigset_t)) |
@@ -368,9 +555,7 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, | |||
368 | 555 | ||
369 | ret = get_user(handler, &act->sa_handler); | 556 | ret = get_user(handler, &act->sa_handler); |
370 | new_ka.sa.sa_handler = compat_ptr(handler); | 557 | new_ka.sa.sa_handler = compat_ptr(handler); |
371 | ret |= __copy_from_user(&set32, &act->sa_mask, | 558 | ret |= get_sigset_t(&new_ka.sa.sa_mask, &act->sa_mask); |
372 | sizeof(compat_sigset_t)); | ||
373 | sigset_from_compat(&new_ka.sa.sa_mask, &set32); | ||
374 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); | 559 | ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags); |
375 | if (ret) | 560 | if (ret) |
376 | return -EFAULT; | 561 | return -EFAULT; |
@@ -378,10 +563,8 @@ long sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, | |||
378 | 563 | ||
379 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); | 564 | ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); |
380 | if (!ret && oact) { | 565 | if (!ret && oact) { |
381 | compat_from_sigset(&set32, &old_ka.sa.sa_mask); | ||
382 | ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); | 566 | ret = put_user((long)old_ka.sa.sa_handler, &oact->sa_handler); |
383 | ret |= __copy_to_user(&oact->sa_mask, &set32, | 567 | ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask); |
384 | sizeof(compat_sigset_t)); | ||
385 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | 568 | ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags); |
386 | } | 569 | } |
387 | return ret; | 570 | return ret; |
@@ -399,27 +582,24 @@ long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, | |||
399 | { | 582 | { |
400 | sigset_t s; | 583 | sigset_t s; |
401 | sigset_t __user *up; | 584 | sigset_t __user *up; |
402 | compat_sigset_t s32; | ||
403 | int ret; | 585 | int ret; |
404 | mm_segment_t old_fs = get_fs(); | 586 | mm_segment_t old_fs = get_fs(); |
405 | 587 | ||
406 | if (set) { | 588 | if (set) { |
407 | if (copy_from_user (&s32, set, sizeof(compat_sigset_t))) | 589 | if (get_sigset_t(&s, set)) |
408 | return -EFAULT; | 590 | return -EFAULT; |
409 | sigset_from_compat(&s, &s32); | ||
410 | } | 591 | } |
411 | 592 | ||
412 | set_fs(KERNEL_DS); | 593 | set_fs(KERNEL_DS); |
413 | /* This is valid because of the set_fs() */ | 594 | /* This is valid because of the set_fs() */ |
414 | up = (sigset_t __user *) &s; | 595 | up = (sigset_t __user *) &s; |
415 | ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL, | 596 | ret = sys_rt_sigprocmask((int)how, set ? up : NULL, oset ? up : NULL, |
416 | sigsetsize); | 597 | sigsetsize); |
417 | set_fs(old_fs); | 598 | set_fs(old_fs); |
418 | if (ret) | 599 | if (ret) |
419 | return ret; | 600 | return ret; |
420 | if (oset) { | 601 | if (oset) { |
421 | compat_from_sigset(&s32, &s); | 602 | if (put_sigset_t(oset, &s)) |
422 | if (copy_to_user (oset, &s32, sizeof(compat_sigset_t))) | ||
423 | return -EFAULT; | 603 | return -EFAULT; |
424 | } | 604 | } |
425 | return 0; | 605 | return 0; |
@@ -428,7 +608,6 @@ long sys32_rt_sigprocmask(u32 how, compat_sigset_t __user *set, | |||
428 | long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) | 608 | long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) |
429 | { | 609 | { |
430 | sigset_t s; | 610 | sigset_t s; |
431 | compat_sigset_t s32; | ||
432 | int ret; | 611 | int ret; |
433 | mm_segment_t old_fs = get_fs(); | 612 | mm_segment_t old_fs = get_fs(); |
434 | 613 | ||
@@ -437,8 +616,7 @@ long sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) | |||
437 | ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); | 616 | ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); |
438 | set_fs(old_fs); | 617 | set_fs(old_fs); |
439 | if (!ret) { | 618 | if (!ret) { |
440 | compat_from_sigset(&s32, &s); | 619 | if (put_sigset_t(set, &s)) |
441 | if (copy_to_user (set, &s32, sizeof(compat_sigset_t))) | ||
442 | return -EFAULT; | 620 | return -EFAULT; |
443 | } | 621 | } |
444 | return ret; | 622 | return ret; |
@@ -500,6 +678,8 @@ int copy_siginfo_to_user32(struct compat_siginfo __user *d, siginfo_t *s) | |||
500 | return err; | 678 | return err; |
501 | } | 679 | } |
502 | 680 | ||
681 | #define copy_siginfo_to_user copy_siginfo_to_user32 | ||
682 | |||
503 | /* | 683 | /* |
504 | * Note: it is necessary to treat pid and sig as unsigned ints, with the | 684 | * Note: it is necessary to treat pid and sig as unsigned ints, with the |
505 | * corresponding cast to a signed int to insure that the proper conversion | 685 | * corresponding cast to a signed int to insure that the proper conversion |
@@ -512,7 +692,7 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) | |||
512 | siginfo_t info; | 692 | siginfo_t info; |
513 | int ret; | 693 | int ret; |
514 | mm_segment_t old_fs = get_fs(); | 694 | mm_segment_t old_fs = get_fs(); |
515 | 695 | ||
516 | if (copy_from_user (&info, uinfo, 3*sizeof(int)) || | 696 | if (copy_from_user (&info, uinfo, 3*sizeof(int)) || |
517 | copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32)) | 697 | copy_from_user (info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE32)) |
518 | return -EFAULT; | 698 | return -EFAULT; |
@@ -522,50 +702,6 @@ long sys32_rt_sigqueueinfo(u32 pid, u32 sig, compat_siginfo_t __user *uinfo) | |||
522 | set_fs (old_fs); | 702 | set_fs (old_fs); |
523 | return ret; | 703 | return ret; |
524 | } | 704 | } |
525 | |||
526 | int sys32_rt_sigsuspend(compat_sigset_t __user * unewset, size_t sigsetsize, int p3, | ||
527 | int p4, int p6, int p7, struct pt_regs *regs) | ||
528 | { | ||
529 | sigset_t saveset, newset; | ||
530 | compat_sigset_t s32; | ||
531 | |||
532 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
533 | if (sigsetsize != sizeof(sigset_t)) | ||
534 | return -EINVAL; | ||
535 | |||
536 | if (copy_from_user(&s32, unewset, sizeof(s32))) | ||
537 | return -EFAULT; | ||
538 | |||
539 | /* | ||
540 | * Swap the 2 words of the 64-bit sigset_t (they are stored | ||
541 | * in the "wrong" endian in 32-bit user storage). | ||
542 | */ | ||
543 | sigset_from_compat(&newset, &s32); | ||
544 | |||
545 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
546 | spin_lock_irq(¤t->sighand->siglock); | ||
547 | saveset = current->blocked; | ||
548 | current->blocked = newset; | ||
549 | recalc_sigpending(); | ||
550 | spin_unlock_irq(¤t->sighand->siglock); | ||
551 | |||
552 | regs->result = -EINTR; | ||
553 | regs->gpr[3] = EINTR; | ||
554 | regs->ccr |= 0x10000000; | ||
555 | while (1) { | ||
556 | current->state = TASK_INTERRUPTIBLE; | ||
557 | schedule(); | ||
558 | if (do_signal32(&saveset, regs)) | ||
559 | /* | ||
560 | * Returning 0 means we return to userspace via | ||
561 | * ret_from_except and thus restore all user | ||
562 | * registers from *regs. This is what we need | ||
563 | * to do when a signal has been delivered. | ||
564 | */ | ||
565 | return 0; | ||
566 | } | ||
567 | } | ||
568 | |||
569 | /* | 705 | /* |
570 | * Start Alternate signal stack support | 706 | * Start Alternate signal stack support |
571 | * | 707 | * |
@@ -615,76 +751,95 @@ int sys32_sigaltstack(u32 __new, u32 __old, int r5, | |||
615 | return -EFAULT; | 751 | return -EFAULT; |
616 | return ret; | 752 | return ret; |
617 | } | 753 | } |
754 | #endif /* CONFIG_PPC64 */ | ||
618 | 755 | ||
619 | 756 | ||
620 | /* | 757 | /* |
758 | * Restore the user process's signal mask | ||
759 | */ | ||
760 | #ifdef CONFIG_PPC64 | ||
761 | extern void restore_sigmask(sigset_t *set); | ||
762 | #else /* CONFIG_PPC64 */ | ||
763 | static void restore_sigmask(sigset_t *set) | ||
764 | { | ||
765 | sigdelsetmask(set, ~_BLOCKABLE); | ||
766 | spin_lock_irq(¤t->sighand->siglock); | ||
767 | current->blocked = *set; | ||
768 | recalc_sigpending(); | ||
769 | spin_unlock_irq(¤t->sighand->siglock); | ||
770 | } | ||
771 | #endif | ||
772 | |||
773 | /* | ||
621 | * Set up a signal frame for a "real-time" signal handler | 774 | * Set up a signal frame for a "real-time" signal handler |
622 | * (one which gets siginfo). | 775 | * (one which gets siginfo). |
623 | */ | 776 | */ |
624 | static int handle_rt_signal32(unsigned long sig, struct k_sigaction *ka, | 777 | static int handle_rt_signal(unsigned long sig, struct k_sigaction *ka, |
625 | siginfo_t *info, sigset_t *oldset, | 778 | siginfo_t *info, sigset_t *oldset, |
626 | struct pt_regs * regs, unsigned long newsp) | 779 | struct pt_regs *regs, unsigned long newsp) |
627 | { | 780 | { |
628 | struct rt_sigframe32 __user *rt_sf; | 781 | struct rt_sigframe __user *rt_sf; |
629 | struct mcontext32 __user *frame; | 782 | struct mcontext __user *frame; |
630 | unsigned long origsp = newsp; | 783 | unsigned long origsp = newsp; |
631 | compat_sigset_t c_oldset; | ||
632 | 784 | ||
633 | /* Set up Signal Frame */ | 785 | /* Set up Signal Frame */ |
634 | /* Put a Real Time Context onto stack */ | 786 | /* Put a Real Time Context onto stack */ |
635 | newsp -= sizeof(*rt_sf); | 787 | newsp -= sizeof(*rt_sf); |
636 | rt_sf = (struct rt_sigframe32 __user *)newsp; | 788 | rt_sf = (struct rt_sigframe __user *)newsp; |
637 | 789 | ||
638 | /* create a stack frame for the caller of the handler */ | 790 | /* create a stack frame for the caller of the handler */ |
639 | newsp -= __SIGNAL_FRAMESIZE32 + 16; | 791 | newsp -= __SIGNAL_FRAMESIZE + 16; |
640 | 792 | ||
641 | if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp)) | 793 | if (!access_ok(VERIFY_WRITE, (void __user *)newsp, origsp - newsp)) |
642 | goto badframe; | 794 | goto badframe; |
643 | 795 | ||
644 | compat_from_sigset(&c_oldset, oldset); | ||
645 | |||
646 | /* Put the siginfo & fill in most of the ucontext */ | 796 | /* Put the siginfo & fill in most of the ucontext */ |
647 | if (copy_siginfo_to_user32(&rt_sf->info, info) | 797 | if (copy_siginfo_to_user(&rt_sf->info, info) |
648 | || __put_user(0, &rt_sf->uc.uc_flags) | 798 | || __put_user(0, &rt_sf->uc.uc_flags) |
649 | || __put_user(0, &rt_sf->uc.uc_link) | 799 | || __put_user(0, &rt_sf->uc.uc_link) |
650 | || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) | 800 | || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) |
651 | || __put_user(sas_ss_flags(regs->gpr[1]), | 801 | || __put_user(sas_ss_flags(regs->gpr[1]), |
652 | &rt_sf->uc.uc_stack.ss_flags) | 802 | &rt_sf->uc.uc_stack.ss_flags) |
653 | || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) | 803 | || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) |
654 | || __put_user((u32)(u64)&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) | 804 | || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), |
655 | || __copy_to_user(&rt_sf->uc.uc_sigmask, &c_oldset, sizeof(c_oldset))) | 805 | &rt_sf->uc.uc_regs) |
806 | || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset)) | ||
656 | goto badframe; | 807 | goto badframe; |
657 | 808 | ||
658 | /* Save user registers on the stack */ | 809 | /* Save user registers on the stack */ |
659 | frame = &rt_sf->uc.uc_mcontext; | 810 | frame = &rt_sf->uc.uc_mcontext; |
660 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 811 | #ifdef CONFIG_PPC64 |
661 | goto badframe; | ||
662 | |||
663 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { | 812 | if (vdso32_rt_sigtramp && current->thread.vdso_base) { |
664 | if (save_user_regs(regs, frame, 0)) | 813 | if (save_user_regs(regs, frame, 0)) |
665 | goto badframe; | 814 | goto badframe; |
666 | regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; | 815 | regs->link = current->thread.vdso_base + vdso32_rt_sigtramp; |
667 | } else { | 816 | } else |
817 | #endif | ||
818 | { | ||
668 | if (save_user_regs(regs, frame, __NR_rt_sigreturn)) | 819 | if (save_user_regs(regs, frame, __NR_rt_sigreturn)) |
669 | goto badframe; | 820 | goto badframe; |
670 | regs->link = (unsigned long) frame->tramp; | 821 | regs->link = (unsigned long) frame->tramp; |
671 | } | 822 | } |
672 | regs->gpr[1] = (unsigned long) newsp; | 823 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) |
824 | goto badframe; | ||
825 | regs->gpr[1] = newsp; | ||
673 | regs->gpr[3] = sig; | 826 | regs->gpr[3] = sig; |
674 | regs->gpr[4] = (unsigned long) &rt_sf->info; | 827 | regs->gpr[4] = (unsigned long) &rt_sf->info; |
675 | regs->gpr[5] = (unsigned long) &rt_sf->uc; | 828 | regs->gpr[5] = (unsigned long) &rt_sf->uc; |
676 | regs->gpr[6] = (unsigned long) rt_sf; | 829 | regs->gpr[6] = (unsigned long) rt_sf; |
677 | regs->nip = (unsigned long) ka->sa.sa_handler; | 830 | regs->nip = (unsigned long) ka->sa.sa_handler; |
831 | regs->link = (unsigned long) frame->tramp; | ||
678 | regs->trap = 0; | 832 | regs->trap = 0; |
833 | #ifdef CONFIG_PPC64 | ||
679 | regs->result = 0; | 834 | regs->result = 0; |
680 | 835 | ||
681 | if (test_thread_flag(TIF_SINGLESTEP)) | 836 | if (test_thread_flag(TIF_SINGLESTEP)) |
682 | ptrace_notify(SIGTRAP); | 837 | ptrace_notify(SIGTRAP); |
683 | 838 | #endif | |
684 | return 1; | 839 | return 1; |
685 | 840 | ||
686 | badframe: | 841 | badframe: |
687 | #if DEBUG_SIG | 842 | #ifdef DEBUG_SIG |
688 | printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", | 843 | printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", |
689 | regs, frame, newsp); | 844 | regs, frame, newsp); |
690 | #endif | 845 | #endif |
@@ -692,46 +847,50 @@ badframe: | |||
692 | return 0; | 847 | return 0; |
693 | } | 848 | } |
694 | 849 | ||
695 | static long do_setcontext32(struct ucontext32 __user *ucp, struct pt_regs *regs, int sig) | 850 | static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig) |
696 | { | 851 | { |
697 | compat_sigset_t c_set; | ||
698 | sigset_t set; | 852 | sigset_t set; |
699 | u32 mcp; | 853 | struct mcontext __user *mcp; |
854 | |||
855 | if (get_sigset_t(&set, &ucp->uc_sigmask)) | ||
856 | return -EFAULT; | ||
857 | #ifdef CONFIG_PPC64 | ||
858 | { | ||
859 | u32 cmcp; | ||
700 | 860 | ||
701 | if (__copy_from_user(&c_set, &ucp->uc_sigmask, sizeof(c_set)) | 861 | if (__get_user(cmcp, &ucp->uc_regs)) |
702 | || __get_user(mcp, &ucp->uc_regs)) | 862 | return -EFAULT; |
863 | mcp = (struct mcontext __user *)(u64)cmcp; | ||
864 | } | ||
865 | #else | ||
866 | if (__get_user(mcp, &ucp->uc_regs)) | ||
703 | return -EFAULT; | 867 | return -EFAULT; |
704 | sigset_from_compat(&set, &c_set); | 868 | #endif |
705 | restore_sigmask(&set); | 869 | restore_sigmask(&set); |
706 | if (restore_user_regs(regs, (struct mcontext32 __user *)(u64)mcp, sig)) | 870 | if (restore_user_regs(regs, mcp, sig)) |
707 | return -EFAULT; | 871 | return -EFAULT; |
708 | 872 | ||
709 | return 0; | 873 | return 0; |
710 | } | 874 | } |
711 | 875 | ||
712 | /* | 876 | long sys_swapcontext(struct ucontext __user *old_ctx, |
713 | * Handle {get,set,swap}_context operations for 32 bits processes | 877 | struct ucontext __user *new_ctx, |
714 | */ | ||
715 | |||
716 | long sys32_swapcontext(struct ucontext32 __user *old_ctx, | ||
717 | struct ucontext32 __user *new_ctx, | ||
718 | int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) | 878 | int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) |
719 | { | 879 | { |
720 | unsigned char tmp; | 880 | unsigned char tmp; |
721 | compat_sigset_t c_set; | ||
722 | 881 | ||
723 | /* Context size is for future use. Right now, we only make sure | 882 | /* Context size is for future use. Right now, we only make sure |
724 | * we are passed something we understand | 883 | * we are passed something we understand |
725 | */ | 884 | */ |
726 | if (ctx_size < sizeof(struct ucontext32)) | 885 | if (ctx_size < sizeof(struct ucontext)) |
727 | return -EINVAL; | 886 | return -EINVAL; |
728 | 887 | ||
729 | if (old_ctx != NULL) { | 888 | if (old_ctx != NULL) { |
730 | compat_from_sigset(&c_set, ¤t->blocked); | ||
731 | if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) | 889 | if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) |
732 | || save_user_regs(regs, &old_ctx->uc_mcontext, 0) | 890 | || save_user_regs(regs, &old_ctx->uc_mcontext, 0) |
733 | || __copy_to_user(&old_ctx->uc_sigmask, &c_set, sizeof(c_set)) | 891 | || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked) |
734 | || __put_user((u32)(u64)&old_ctx->uc_mcontext, &old_ctx->uc_regs)) | 892 | || __put_user(to_user_ptr(&old_ctx->uc_mcontext), |
893 | &old_ctx->uc_regs)) | ||
735 | return -EFAULT; | 894 | return -EFAULT; |
736 | } | 895 | } |
737 | if (new_ctx == NULL) | 896 | if (new_ctx == NULL) |
@@ -752,27 +911,26 @@ long sys32_swapcontext(struct ucontext32 __user *old_ctx, | |||
752 | * or if another thread unmaps the region containing the context. | 911 | * or if another thread unmaps the region containing the context. |
753 | * We kill the task with a SIGSEGV in this situation. | 912 | * We kill the task with a SIGSEGV in this situation. |
754 | */ | 913 | */ |
755 | if (do_setcontext32(new_ctx, regs, 0)) | 914 | if (do_setcontext(new_ctx, regs, 0)) |
756 | do_exit(SIGSEGV); | 915 | do_exit(SIGSEGV); |
757 | 916 | sigreturn_exit(regs); | |
917 | /* doesn't actually return back to here */ | ||
758 | return 0; | 918 | return 0; |
759 | } | 919 | } |
760 | 920 | ||
761 | long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | 921 | long sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, |
762 | struct pt_regs *regs) | 922 | struct pt_regs *regs) |
763 | { | 923 | { |
764 | struct rt_sigframe32 __user *rt_sf; | 924 | struct rt_sigframe __user *rt_sf; |
765 | int ret; | ||
766 | |||
767 | 925 | ||
768 | /* Always make any pending restarted system calls return -EINTR */ | 926 | /* Always make any pending restarted system calls return -EINTR */ |
769 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 927 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
770 | 928 | ||
771 | rt_sf = (struct rt_sigframe32 __user *) | 929 | rt_sf = (struct rt_sigframe __user *) |
772 | (regs->gpr[1] + __SIGNAL_FRAMESIZE32 + 16); | 930 | (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); |
773 | if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) | 931 | if (!access_ok(VERIFY_READ, rt_sf, sizeof(*rt_sf))) |
774 | goto bad; | 932 | goto bad; |
775 | if (do_setcontext32(&rt_sf->uc, regs, 1)) | 933 | if (do_setcontext(&rt_sf->uc, regs, 1)) |
776 | goto bad; | 934 | goto bad; |
777 | 935 | ||
778 | /* | 936 | /* |
@@ -781,62 +939,165 @@ long sys32_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | |||
781 | * signal return. But other architectures do this and we have | 939 | * signal return. But other architectures do this and we have |
782 | * always done it up until now so it is probably better not to | 940 | * always done it up until now so it is probably better not to |
783 | * change it. -- paulus | 941 | * change it. -- paulus |
942 | */ | ||
943 | #ifdef CONFIG_PPC64 | ||
944 | /* | ||
784 | * We use the sys32_ version that does the 32/64 bits conversion | 945 | * We use the sys32_ version that does the 32/64 bits conversion |
785 | * and takes userland pointer directly. What about error checking ? | 946 | * and takes userland pointer directly. What about error checking ? |
786 | * nobody does any... | 947 | * nobody does any... |
787 | */ | 948 | */ |
788 | sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); | 949 | sys32_sigaltstack((u32)(u64)&rt_sf->uc.uc_stack, 0, 0, 0, 0, 0, regs); |
789 | 950 | return (int)regs->result; | |
790 | ret = regs->result; | 951 | #else |
791 | 952 | do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); | |
792 | return ret; | 953 | sigreturn_exit(regs); /* doesn't return here */ |
954 | return 0; | ||
955 | #endif | ||
793 | 956 | ||
794 | bad: | 957 | bad: |
795 | force_sig(SIGSEGV, current); | 958 | force_sig(SIGSEGV, current); |
796 | return 0; | 959 | return 0; |
797 | } | 960 | } |
798 | 961 | ||
962 | #ifdef CONFIG_PPC32 | ||
963 | int sys_debug_setcontext(struct ucontext __user *ctx, | ||
964 | int ndbg, struct sig_dbg_op __user *dbg, | ||
965 | int r6, int r7, int r8, | ||
966 | struct pt_regs *regs) | ||
967 | { | ||
968 | struct sig_dbg_op op; | ||
969 | int i; | ||
970 | unsigned long new_msr = regs->msr; | ||
971 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
972 | unsigned long new_dbcr0 = current->thread.dbcr0; | ||
973 | #endif | ||
974 | |||
975 | for (i=0; i<ndbg; i++) { | ||
976 | if (__copy_from_user(&op, dbg, sizeof(op))) | ||
977 | return -EFAULT; | ||
978 | switch (op.dbg_type) { | ||
979 | case SIG_DBG_SINGLE_STEPPING: | ||
980 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
981 | if (op.dbg_value) { | ||
982 | new_msr |= MSR_DE; | ||
983 | new_dbcr0 |= (DBCR0_IDM | DBCR0_IC); | ||
984 | } else { | ||
985 | new_msr &= ~MSR_DE; | ||
986 | new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC); | ||
987 | } | ||
988 | #else | ||
989 | if (op.dbg_value) | ||
990 | new_msr |= MSR_SE; | ||
991 | else | ||
992 | new_msr &= ~MSR_SE; | ||
993 | #endif | ||
994 | break; | ||
995 | case SIG_DBG_BRANCH_TRACING: | ||
996 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
997 | return -EINVAL; | ||
998 | #else | ||
999 | if (op.dbg_value) | ||
1000 | new_msr |= MSR_BE; | ||
1001 | else | ||
1002 | new_msr &= ~MSR_BE; | ||
1003 | #endif | ||
1004 | break; | ||
1005 | |||
1006 | default: | ||
1007 | return -EINVAL; | ||
1008 | } | ||
1009 | } | ||
1010 | |||
1011 | /* We wait until here to actually install the values in the | ||
1012 | registers so if we fail in the above loop, it will not | ||
1013 | affect the contents of these registers. After this point, | ||
1014 | failure is a problem, anyway, and it's very unlikely unless | ||
1015 | the user is really doing something wrong. */ | ||
1016 | regs->msr = new_msr; | ||
1017 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
1018 | current->thread.dbcr0 = new_dbcr0; | ||
1019 | #endif | ||
1020 | |||
1021 | /* | ||
1022 | * If we get a fault copying the context into the kernel's | ||
1023 | * image of the user's registers, we can't just return -EFAULT | ||
1024 | * because the user's registers will be corrupted. For instance | ||
1025 | * the NIP value may have been updated but not some of the | ||
1026 | * other registers. Given that we have done the access_ok | ||
1027 | * and successfully read the first and last bytes of the region | ||
1028 | * above, this should only happen in an out-of-memory situation | ||
1029 | * or if another thread unmaps the region containing the context. | ||
1030 | * We kill the task with a SIGSEGV in this situation. | ||
1031 | */ | ||
1032 | if (do_setcontext(ctx, regs, 1)) { | ||
1033 | force_sig(SIGSEGV, current); | ||
1034 | goto out; | ||
1035 | } | ||
1036 | |||
1037 | /* | ||
1038 | * It's not clear whether or why it is desirable to save the | ||
1039 | * sigaltstack setting on signal delivery and restore it on | ||
1040 | * signal return. But other architectures do this and we have | ||
1041 | * always done it up until now so it is probably better not to | ||
1042 | * change it. -- paulus | ||
1043 | */ | ||
1044 | do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); | ||
1045 | |||
1046 | sigreturn_exit(regs); | ||
1047 | /* doesn't actually return back to here */ | ||
1048 | |||
1049 | out: | ||
1050 | return 0; | ||
1051 | } | ||
1052 | #endif | ||
799 | 1053 | ||
800 | /* | 1054 | /* |
801 | * OK, we're invoking a handler | 1055 | * OK, we're invoking a handler |
802 | */ | 1056 | */ |
803 | static int handle_signal32(unsigned long sig, struct k_sigaction *ka, | 1057 | static int handle_signal(unsigned long sig, struct k_sigaction *ka, |
804 | siginfo_t *info, sigset_t *oldset, | 1058 | siginfo_t *info, sigset_t *oldset, struct pt_regs *regs, |
805 | struct pt_regs * regs, unsigned long newsp) | 1059 | unsigned long newsp) |
806 | { | 1060 | { |
807 | struct sigcontext32 __user *sc; | 1061 | struct sigcontext __user *sc; |
808 | struct sigregs32 __user *frame; | 1062 | struct sigregs __user *frame; |
809 | unsigned long origsp = newsp; | 1063 | unsigned long origsp = newsp; |
810 | 1064 | ||
811 | /* Set up Signal Frame */ | 1065 | /* Set up Signal Frame */ |
812 | newsp -= sizeof(struct sigregs32); | 1066 | newsp -= sizeof(struct sigregs); |
813 | frame = (struct sigregs32 __user *) newsp; | 1067 | frame = (struct sigregs __user *) newsp; |
814 | 1068 | ||
815 | /* Put a sigcontext on the stack */ | 1069 | /* Put a sigcontext on the stack */ |
816 | newsp -= sizeof(*sc); | 1070 | newsp -= sizeof(*sc); |
817 | sc = (struct sigcontext32 __user *) newsp; | 1071 | sc = (struct sigcontext __user *) newsp; |
818 | 1072 | ||
819 | /* create a stack frame for the caller of the handler */ | 1073 | /* create a stack frame for the caller of the handler */ |
820 | newsp -= __SIGNAL_FRAMESIZE32; | 1074 | newsp -= __SIGNAL_FRAMESIZE; |
821 | 1075 | ||
822 | if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) | 1076 | if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) |
823 | goto badframe; | 1077 | goto badframe; |
824 | 1078 | ||
825 | #if _NSIG != 64 | 1079 | #if _NSIG != 64 |
826 | #error "Please adjust handle_signal32()" | 1080 | #error "Please adjust handle_signal()" |
827 | #endif | 1081 | #endif |
828 | if (__put_user((u32)(u64)ka->sa.sa_handler, &sc->handler) | 1082 | if (__put_user(to_user_ptr(ka->sa.sa_handler), &sc->handler) |
829 | || __put_user(oldset->sig[0], &sc->oldmask) | 1083 | || __put_user(oldset->sig[0], &sc->oldmask) |
1084 | #ifdef CONFIG_PPC64 | ||
830 | || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) | 1085 | || __put_user((oldset->sig[0] >> 32), &sc->_unused[3]) |
831 | || __put_user((u32)(u64)frame, &sc->regs) | 1086 | #else |
1087 | || __put_user(oldset->sig[1], &sc->_unused[3]) | ||
1088 | #endif | ||
1089 | || __put_user(to_user_ptr(frame), &sc->regs) | ||
832 | || __put_user(sig, &sc->signal)) | 1090 | || __put_user(sig, &sc->signal)) |
833 | goto badframe; | 1091 | goto badframe; |
834 | 1092 | ||
1093 | #ifdef CONFIG_PPC64 | ||
835 | if (vdso32_sigtramp && current->thread.vdso_base) { | 1094 | if (vdso32_sigtramp && current->thread.vdso_base) { |
836 | if (save_user_regs(regs, &frame->mctx, 0)) | 1095 | if (save_user_regs(regs, &frame->mctx, 0)) |
837 | goto badframe; | 1096 | goto badframe; |
838 | regs->link = current->thread.vdso_base + vdso32_sigtramp; | 1097 | regs->link = current->thread.vdso_base + vdso32_sigtramp; |
839 | } else { | 1098 | } else |
1099 | #endif | ||
1100 | { | ||
840 | if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) | 1101 | if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) |
841 | goto badframe; | 1102 | goto badframe; |
842 | regs->link = (unsigned long) frame->mctx.tramp; | 1103 | regs->link = (unsigned long) frame->mctx.tramp; |
@@ -844,22 +1105,24 @@ static int handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
844 | 1105 | ||
845 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) | 1106 | if (put_user(regs->gpr[1], (u32 __user *)newsp)) |
846 | goto badframe; | 1107 | goto badframe; |
847 | regs->gpr[1] = (unsigned long) newsp; | 1108 | regs->gpr[1] = newsp; |
848 | regs->gpr[3] = sig; | 1109 | regs->gpr[3] = sig; |
849 | regs->gpr[4] = (unsigned long) sc; | 1110 | regs->gpr[4] = (unsigned long) sc; |
850 | regs->nip = (unsigned long) ka->sa.sa_handler; | 1111 | regs->nip = (unsigned long) ka->sa.sa_handler; |
851 | regs->trap = 0; | 1112 | regs->trap = 0; |
1113 | #ifdef CONFIG_PPC64 | ||
852 | regs->result = 0; | 1114 | regs->result = 0; |
853 | 1115 | ||
854 | if (test_thread_flag(TIF_SINGLESTEP)) | 1116 | if (test_thread_flag(TIF_SINGLESTEP)) |
855 | ptrace_notify(SIGTRAP); | 1117 | ptrace_notify(SIGTRAP); |
1118 | #endif | ||
856 | 1119 | ||
857 | return 1; | 1120 | return 1; |
858 | 1121 | ||
859 | badframe: | 1122 | badframe: |
860 | #if DEBUG_SIG | 1123 | #ifdef DEBUG_SIG |
861 | printk("badframe in handle_signal, regs=%p frame=%x newsp=%x\n", | 1124 | printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n", |
862 | regs, frame, *newspp); | 1125 | regs, frame, newsp); |
863 | #endif | 1126 | #endif |
864 | force_sigsegv(sig, current); | 1127 | force_sigsegv(sig, current); |
865 | return 0; | 1128 | return 0; |
@@ -868,65 +1131,69 @@ badframe: | |||
868 | /* | 1131 | /* |
869 | * Do a signal return; undo the signal stack. | 1132 | * Do a signal return; undo the signal stack. |
870 | */ | 1133 | */ |
871 | long sys32_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | 1134 | long sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, |
872 | struct pt_regs *regs) | 1135 | struct pt_regs *regs) |
873 | { | 1136 | { |
874 | struct sigcontext32 __user *sc; | 1137 | struct sigcontext __user *sc; |
875 | struct sigcontext32 sigctx; | 1138 | struct sigcontext sigctx; |
876 | struct mcontext32 __user *sr; | 1139 | struct mcontext __user *sr; |
877 | sigset_t set; | 1140 | sigset_t set; |
878 | int ret; | ||
879 | 1141 | ||
880 | /* Always make any pending restarted system calls return -EINTR */ | 1142 | /* Always make any pending restarted system calls return -EINTR */ |
881 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 1143 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
882 | 1144 | ||
883 | sc = (struct sigcontext32 __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE32); | 1145 | sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); |
884 | if (copy_from_user(&sigctx, sc, sizeof(sigctx))) | 1146 | if (copy_from_user(&sigctx, sc, sizeof(sigctx))) |
885 | goto badframe; | 1147 | goto badframe; |
886 | 1148 | ||
1149 | #ifdef CONFIG_PPC64 | ||
887 | /* | 1150 | /* |
888 | * Note that PPC32 puts the upper 32 bits of the sigmask in the | 1151 | * Note that PPC32 puts the upper 32 bits of the sigmask in the |
889 | * unused part of the signal stackframe | 1152 | * unused part of the signal stackframe |
890 | */ | 1153 | */ |
891 | set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32); | 1154 | set.sig[0] = sigctx.oldmask + ((long)(sigctx._unused[3]) << 32); |
1155 | #else | ||
1156 | set.sig[0] = sigctx.oldmask; | ||
1157 | set.sig[1] = sigctx._unused[3]; | ||
1158 | #endif | ||
892 | restore_sigmask(&set); | 1159 | restore_sigmask(&set); |
893 | 1160 | ||
894 | sr = (struct mcontext32 __user *)(u64)sigctx.regs; | 1161 | sr = (struct mcontext __user *)from_user_ptr(sigctx.regs); |
895 | if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) | 1162 | if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) |
896 | || restore_user_regs(regs, sr, 1)) | 1163 | || restore_user_regs(regs, sr, 1)) |
897 | goto badframe; | 1164 | goto badframe; |
898 | 1165 | ||
899 | ret = regs->result; | 1166 | #ifdef CONFIG_PPC64 |
900 | return ret; | 1167 | return (int)regs->result; |
1168 | #else | ||
1169 | sigreturn_exit(regs); /* doesn't return */ | ||
1170 | return 0; | ||
1171 | #endif | ||
901 | 1172 | ||
902 | badframe: | 1173 | badframe: |
903 | force_sig(SIGSEGV, current); | 1174 | force_sig(SIGSEGV, current); |
904 | return 0; | 1175 | return 0; |
905 | } | 1176 | } |
906 | 1177 | ||
907 | |||
908 | |||
909 | /* | ||
910 | * Start of do_signal32 routine | ||
911 | * | ||
912 | * This routine gets control when a pending signal needs to be processed | ||
913 | * in the 32 bit target thread - | ||
914 | * | ||
915 | * It handles both rt and non-rt signals | ||
916 | */ | ||
917 | |||
918 | /* | 1178 | /* |
919 | * Note that 'init' is a special process: it doesn't get signals it doesn't | 1179 | * Note that 'init' is a special process: it doesn't get signals it doesn't |
920 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 1180 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
921 | * mistake. | 1181 | * mistake. |
922 | */ | 1182 | */ |
923 | 1183 | int do_signal(sigset_t *oldset, struct pt_regs *regs) | |
924 | int do_signal32(sigset_t *oldset, struct pt_regs *regs) | ||
925 | { | 1184 | { |
926 | siginfo_t info; | 1185 | siginfo_t info; |
1186 | struct k_sigaction ka; | ||
927 | unsigned int frame, newsp; | 1187 | unsigned int frame, newsp; |
928 | int signr, ret; | 1188 | int signr, ret; |
929 | struct k_sigaction ka; | 1189 | |
1190 | #ifdef CONFIG_PPC32 | ||
1191 | if (try_to_freeze()) { | ||
1192 | signr = 0; | ||
1193 | if (!signal_pending(current)) | ||
1194 | goto no_signal; | ||
1195 | } | ||
1196 | #endif | ||
930 | 1197 | ||
931 | if (!oldset) | 1198 | if (!oldset) |
932 | oldset = ¤t->blocked; | 1199 | oldset = ¤t->blocked; |
@@ -934,7 +1201,9 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
934 | newsp = frame = 0; | 1201 | newsp = frame = 0; |
935 | 1202 | ||
936 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 1203 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
937 | 1204 | #ifdef CONFIG_PPC32 | |
1205 | no_signal: | ||
1206 | #endif | ||
938 | if (TRAP(regs) == 0x0C00 /* System Call! */ | 1207 | if (TRAP(regs) == 0x0C00 /* System Call! */ |
939 | && regs->ccr & 0x10000000 /* error signalled */ | 1208 | && regs->ccr & 0x10000000 /* error signalled */ |
940 | && ((ret = regs->gpr[3]) == ERESTARTSYS | 1209 | && ((ret = regs->gpr[3]) == ERESTARTSYS |
@@ -964,12 +1233,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
964 | return 0; /* no signals delivered */ | 1233 | return 0; /* no signals delivered */ |
965 | 1234 | ||
966 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size | 1235 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size |
967 | && (!on_sig_stack(regs->gpr[1]))) | 1236 | && !on_sig_stack(regs->gpr[1])) |
968 | newsp = (current->sas_ss_sp + current->sas_ss_size); | 1237 | newsp = current->sas_ss_sp + current->sas_ss_size; |
969 | else | 1238 | else |
970 | newsp = regs->gpr[1]; | 1239 | newsp = regs->gpr[1]; |
971 | newsp &= ~0xfUL; | 1240 | newsp &= ~0xfUL; |
972 | 1241 | ||
1242 | #ifdef CONFIG_PPC64 | ||
973 | /* | 1243 | /* |
974 | * Reenable the DABR before delivering the signal to | 1244 | * Reenable the DABR before delivering the signal to |
975 | * user space. The DABR will have been cleared if it | 1245 | * user space. The DABR will have been cleared if it |
@@ -977,12 +1247,13 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
977 | */ | 1247 | */ |
978 | if (current->thread.dabr) | 1248 | if (current->thread.dabr) |
979 | set_dabr(current->thread.dabr); | 1249 | set_dabr(current->thread.dabr); |
1250 | #endif | ||
980 | 1251 | ||
981 | /* Whee! Actually deliver the signal. */ | 1252 | /* Whee! Actually deliver the signal. */ |
982 | if (ka.sa.sa_flags & SA_SIGINFO) | 1253 | if (ka.sa.sa_flags & SA_SIGINFO) |
983 | ret = handle_rt_signal32(signr, &ka, &info, oldset, regs, newsp); | 1254 | ret = handle_rt_signal(signr, &ka, &info, oldset, regs, newsp); |
984 | else | 1255 | else |
985 | ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); | 1256 | ret = handle_signal(signr, &ka, &info, oldset, regs, newsp); |
986 | 1257 | ||
987 | if (ret) { | 1258 | if (ret) { |
988 | spin_lock_irq(¤t->sighand->siglock); | 1259 | spin_lock_irq(¤t->sighand->siglock); |
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 87d3be4af820..c178397c50af 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile | |||
@@ -13,7 +13,7 @@ extra-$(CONFIG_POWER4) += idle_power4.o | |||
13 | extra-y += vmlinux.lds | 13 | extra-y += vmlinux.lds |
14 | 14 | ||
15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ | 15 | obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ |
16 | process.o signal.o align.o \ | 16 | process.o align.o \ |
17 | syscalls.o setup.o \ | 17 | syscalls.o setup.o \ |
18 | ppc_htab.o perfmon.o | 18 | ppc_htab.o perfmon.o |
19 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 19 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
@@ -38,7 +38,7 @@ endif | |||
38 | 38 | ||
39 | else | 39 | else |
40 | obj-y := irq.o idle.o time.o \ | 40 | obj-y := irq.o idle.o time.o \ |
41 | signal.o align.o perfmon.o | 41 | align.o perfmon.o |
42 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o | 42 | obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o |
43 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o | 43 | obj-$(CONFIG_SOFTWARE_SUSPEND) += swsusp.o |
44 | obj-$(CONFIG_MODULES) += module.o | 44 | obj-$(CONFIG_MODULES) += module.o |
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c deleted file mode 100644 index 2244bf91e593..000000000000 --- a/arch/ppc/kernel/signal.c +++ /dev/null | |||
@@ -1,771 +0,0 @@ | |||
1 | /* | ||
2 | * arch/ppc/kernel/signal.c | ||
3 | * | ||
4 | * PowerPC version | ||
5 | * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) | ||
6 | * | ||
7 | * Derived from "arch/i386/kernel/signal.c" | ||
8 | * Copyright (C) 1991, 1992 Linus Torvalds | ||
9 | * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License | ||
13 | * as published by the Free Software Foundation; either version | ||
14 | * 2 of the License, or (at your option) any later version. | ||
15 | */ | ||
16 | |||
17 | #include <linux/sched.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/smp.h> | ||
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/signal.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include <linux/ptrace.h> | ||
26 | #include <linux/unistd.h> | ||
27 | #include <linux/stddef.h> | ||
28 | #include <linux/elf.h> | ||
29 | #include <linux/tty.h> | ||
30 | #include <linux/binfmts.h> | ||
31 | #include <linux/suspend.h> | ||
32 | #include <asm/ucontext.h> | ||
33 | #include <asm/uaccess.h> | ||
34 | #include <asm/pgtable.h> | ||
35 | #include <asm/cacheflush.h> | ||
36 | |||
37 | #undef DEBUG_SIG | ||
38 | |||
39 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
40 | |||
41 | extern void sigreturn_exit(struct pt_regs *); | ||
42 | |||
43 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | ||
44 | |||
45 | int do_signal(sigset_t *oldset, struct pt_regs *regs); | ||
46 | |||
47 | /* | ||
48 | * Atomically swap in the new signal mask, and wait for a signal. | ||
49 | */ | ||
50 | int | ||
51 | sys_sigsuspend(old_sigset_t mask, int p2, int p3, int p4, int p6, int p7, | ||
52 | struct pt_regs *regs) | ||
53 | { | ||
54 | sigset_t saveset; | ||
55 | |||
56 | mask &= _BLOCKABLE; | ||
57 | spin_lock_irq(¤t->sighand->siglock); | ||
58 | saveset = current->blocked; | ||
59 | siginitset(¤t->blocked, mask); | ||
60 | recalc_sigpending(); | ||
61 | spin_unlock_irq(¤t->sighand->siglock); | ||
62 | |||
63 | regs->result = -EINTR; | ||
64 | regs->gpr[3] = EINTR; | ||
65 | regs->ccr |= 0x10000000; | ||
66 | while (1) { | ||
67 | current->state = TASK_INTERRUPTIBLE; | ||
68 | schedule(); | ||
69 | if (do_signal(&saveset, regs)) | ||
70 | sigreturn_exit(regs); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | int | ||
75 | sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, int p3, int p4, | ||
76 | int p6, int p7, struct pt_regs *regs) | ||
77 | { | ||
78 | sigset_t saveset, newset; | ||
79 | |||
80 | /* XXX: Don't preclude handling different sized sigset_t's. */ | ||
81 | if (sigsetsize != sizeof(sigset_t)) | ||
82 | return -EINVAL; | ||
83 | |||
84 | if (copy_from_user(&newset, unewset, sizeof(newset))) | ||
85 | return -EFAULT; | ||
86 | sigdelsetmask(&newset, ~_BLOCKABLE); | ||
87 | |||
88 | spin_lock_irq(¤t->sighand->siglock); | ||
89 | saveset = current->blocked; | ||
90 | current->blocked = newset; | ||
91 | recalc_sigpending(); | ||
92 | spin_unlock_irq(¤t->sighand->siglock); | ||
93 | |||
94 | regs->result = -EINTR; | ||
95 | regs->gpr[3] = EINTR; | ||
96 | regs->ccr |= 0x10000000; | ||
97 | while (1) { | ||
98 | current->state = TASK_INTERRUPTIBLE; | ||
99 | schedule(); | ||
100 | if (do_signal(&saveset, regs)) | ||
101 | sigreturn_exit(regs); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | |||
106 | int | ||
107 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, int r5, | ||
108 | int r6, int r7, int r8, struct pt_regs *regs) | ||
109 | { | ||
110 | return do_sigaltstack(uss, uoss, regs->gpr[1]); | ||
111 | } | ||
112 | |||
113 | int | ||
114 | sys_sigaction(int sig, const struct old_sigaction __user *act, | ||
115 | struct old_sigaction __user *oact) | ||
116 | { | ||
117 | struct k_sigaction new_ka, old_ka; | ||
118 | int ret; | ||
119 | |||
120 | if (act) { | ||
121 | old_sigset_t mask; | ||
122 | if (!access_ok(VERIFY_READ, act, sizeof(*act)) || | ||
123 | __get_user(new_ka.sa.sa_handler, &act->sa_handler) || | ||
124 | __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) | ||
125 | return -EFAULT; | ||
126 | __get_user(new_ka.sa.sa_flags, &act->sa_flags); | ||
127 | __get_user(mask, &act->sa_mask); | ||
128 | siginitset(&new_ka.sa.sa_mask, mask); | ||
129 | } | ||
130 | |||
131 | ret = do_sigaction(sig, (act? &new_ka: NULL), (oact? &old_ka: NULL)); | ||
132 | |||
133 | if (!ret && oact) { | ||
134 | if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || | ||
135 | __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || | ||
136 | __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) | ||
137 | return -EFAULT; | ||
138 | __put_user(old_ka.sa.sa_flags, &oact->sa_flags); | ||
139 | __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); | ||
140 | } | ||
141 | |||
142 | return ret; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * When we have signals to deliver, we set up on the | ||
147 | * user stack, going down from the original stack pointer: | ||
148 | * a sigregs struct | ||
149 | * a sigcontext struct | ||
150 | * a gap of __SIGNAL_FRAMESIZE bytes | ||
151 | * | ||
152 | * Each of these things must be a multiple of 16 bytes in size. | ||
153 | * | ||
154 | */ | ||
155 | struct sigregs { | ||
156 | struct mcontext mctx; /* all the register values */ | ||
157 | /* Programs using the rs6000/xcoff abi can save up to 19 gp regs | ||
158 | and 18 fp regs below sp before decrementing it. */ | ||
159 | int abigap[56]; | ||
160 | }; | ||
161 | |||
162 | /* We use the mc_pad field for the signal return trampoline. */ | ||
163 | #define tramp mc_pad | ||
164 | |||
165 | /* | ||
166 | * When we have rt signals to deliver, we set up on the | ||
167 | * user stack, going down from the original stack pointer: | ||
168 | * one rt_sigframe struct (siginfo + ucontext + ABI gap) | ||
169 | * a gap of __SIGNAL_FRAMESIZE+16 bytes | ||
170 | * (the +16 is to get the siginfo and ucontext in the same | ||
171 | * positions as in older kernels). | ||
172 | * | ||
173 | * Each of these things must be a multiple of 16 bytes in size. | ||
174 | * | ||
175 | */ | ||
176 | struct rt_sigframe | ||
177 | { | ||
178 | struct siginfo info; | ||
179 | struct ucontext uc; | ||
180 | /* Programs using the rs6000/xcoff abi can save up to 19 gp regs | ||
181 | and 18 fp regs below sp before decrementing it. */ | ||
182 | int abigap[56]; | ||
183 | }; | ||
184 | |||
185 | /* | ||
186 | * Save the current user registers on the user stack. | ||
187 | * We only save the altivec/spe registers if the process has used | ||
188 | * altivec/spe instructions at some point. | ||
189 | */ | ||
190 | static int | ||
191 | save_user_regs(struct pt_regs *regs, struct mcontext __user *frame, int sigret) | ||
192 | { | ||
193 | /* save general and floating-point registers */ | ||
194 | CHECK_FULL_REGS(regs); | ||
195 | preempt_disable(); | ||
196 | if (regs->msr & MSR_FP) | ||
197 | giveup_fpu(current); | ||
198 | #ifdef CONFIG_ALTIVEC | ||
199 | if (current->thread.used_vr && (regs->msr & MSR_VEC)) | ||
200 | giveup_altivec(current); | ||
201 | #endif /* CONFIG_ALTIVEC */ | ||
202 | #ifdef CONFIG_SPE | ||
203 | if (current->thread.used_spe && (regs->msr & MSR_SPE)) | ||
204 | giveup_spe(current); | ||
205 | #endif /* CONFIG_ALTIVEC */ | ||
206 | preempt_enable(); | ||
207 | |||
208 | if (__copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE) | ||
209 | || __copy_to_user(&frame->mc_fregs, current->thread.fpr, | ||
210 | ELF_NFPREG * sizeof(double))) | ||
211 | return 1; | ||
212 | |||
213 | current->thread.fpscr = 0; /* turn off all fp exceptions */ | ||
214 | |||
215 | #ifdef CONFIG_ALTIVEC | ||
216 | /* save altivec registers */ | ||
217 | if (current->thread.used_vr) { | ||
218 | if (__copy_to_user(&frame->mc_vregs, current->thread.vr, | ||
219 | ELF_NVRREG * sizeof(vector128))) | ||
220 | return 1; | ||
221 | /* set MSR_VEC in the saved MSR value to indicate that | ||
222 | frame->mc_vregs contains valid data */ | ||
223 | if (__put_user(regs->msr | MSR_VEC, &frame->mc_gregs[PT_MSR])) | ||
224 | return 1; | ||
225 | } | ||
226 | /* else assert((regs->msr & MSR_VEC) == 0) */ | ||
227 | |||
228 | /* We always copy to/from vrsave, it's 0 if we don't have or don't | ||
229 | * use altivec. Since VSCR only contains 32 bits saved in the least | ||
230 | * significant bits of a vector, we "cheat" and stuff VRSAVE in the | ||
231 | * most significant bits of that same vector. --BenH | ||
232 | */ | ||
233 | if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32])) | ||
234 | return 1; | ||
235 | #endif /* CONFIG_ALTIVEC */ | ||
236 | |||
237 | #ifdef CONFIG_SPE | ||
238 | /* save spe registers */ | ||
239 | if (current->thread.used_spe) { | ||
240 | if (__copy_to_user(&frame->mc_vregs, current->thread.evr, | ||
241 | ELF_NEVRREG * sizeof(u32))) | ||
242 | return 1; | ||
243 | /* set MSR_SPE in the saved MSR value to indicate that | ||
244 | frame->mc_vregs contains valid data */ | ||
245 | if (__put_user(regs->msr | MSR_SPE, &frame->mc_gregs[PT_MSR])) | ||
246 | return 1; | ||
247 | } | ||
248 | /* else assert((regs->msr & MSR_SPE) == 0) */ | ||
249 | |||
250 | /* We always copy to/from spefscr */ | ||
251 | if (__put_user(current->thread.spefscr, (u32 *)&frame->mc_vregs + ELF_NEVRREG)) | ||
252 | return 1; | ||
253 | #endif /* CONFIG_SPE */ | ||
254 | |||
255 | if (sigret) { | ||
256 | /* Set up the sigreturn trampoline: li r0,sigret; sc */ | ||
257 | if (__put_user(0x38000000UL + sigret, &frame->tramp[0]) | ||
258 | || __put_user(0x44000002UL, &frame->tramp[1])) | ||
259 | return 1; | ||
260 | flush_icache_range((unsigned long) &frame->tramp[0], | ||
261 | (unsigned long) &frame->tramp[2]); | ||
262 | } | ||
263 | |||
264 | return 0; | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * Restore the current user register values from the user stack, | ||
269 | * (except for MSR). | ||
270 | */ | ||
271 | static int | ||
272 | restore_user_regs(struct pt_regs *regs, struct mcontext __user *sr, int sig) | ||
273 | { | ||
274 | unsigned long save_r2 = 0; | ||
275 | #if defined(CONFIG_ALTIVEC) || defined(CONFIG_SPE) | ||
276 | unsigned long msr; | ||
277 | #endif | ||
278 | |||
279 | /* backup/restore the TLS as we don't want it to be modified */ | ||
280 | if (!sig) | ||
281 | save_r2 = regs->gpr[2]; | ||
282 | /* copy up to but not including MSR */ | ||
283 | if (__copy_from_user(regs, &sr->mc_gregs, PT_MSR * sizeof(elf_greg_t))) | ||
284 | return 1; | ||
285 | /* copy from orig_r3 (the word after the MSR) up to the end */ | ||
286 | if (__copy_from_user(®s->orig_gpr3, &sr->mc_gregs[PT_ORIG_R3], | ||
287 | GP_REGS_SIZE - PT_ORIG_R3 * sizeof(elf_greg_t))) | ||
288 | return 1; | ||
289 | if (!sig) | ||
290 | regs->gpr[2] = save_r2; | ||
291 | |||
292 | /* force the process to reload the FP registers from | ||
293 | current->thread when it next does FP instructions */ | ||
294 | regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1); | ||
295 | if (__copy_from_user(current->thread.fpr, &sr->mc_fregs, | ||
296 | sizeof(sr->mc_fregs))) | ||
297 | return 1; | ||
298 | |||
299 | #ifdef CONFIG_ALTIVEC | ||
300 | /* force the process to reload the altivec registers from | ||
301 | current->thread when it next does altivec instructions */ | ||
302 | regs->msr &= ~MSR_VEC; | ||
303 | if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_VEC) != 0) { | ||
304 | /* restore altivec registers from the stack */ | ||
305 | if (__copy_from_user(current->thread.vr, &sr->mc_vregs, | ||
306 | sizeof(sr->mc_vregs))) | ||
307 | return 1; | ||
308 | } else if (current->thread.used_vr) | ||
309 | memset(¤t->thread.vr, 0, ELF_NVRREG * sizeof(vector128)); | ||
310 | |||
311 | /* Always get VRSAVE back */ | ||
312 | if (__get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32])) | ||
313 | return 1; | ||
314 | #endif /* CONFIG_ALTIVEC */ | ||
315 | |||
316 | #ifdef CONFIG_SPE | ||
317 | /* force the process to reload the spe registers from | ||
318 | current->thread when it next does spe instructions */ | ||
319 | regs->msr &= ~MSR_SPE; | ||
320 | if (!__get_user(msr, &sr->mc_gregs[PT_MSR]) && (msr & MSR_SPE) != 0) { | ||
321 | /* restore spe registers from the stack */ | ||
322 | if (__copy_from_user(current->thread.evr, &sr->mc_vregs, | ||
323 | ELF_NEVRREG * sizeof(u32))) | ||
324 | return 1; | ||
325 | } else if (current->thread.used_spe) | ||
326 | memset(¤t->thread.evr, 0, ELF_NEVRREG * sizeof(u32)); | ||
327 | |||
328 | /* Always get SPEFSCR back */ | ||
329 | if (__get_user(current->thread.spefscr, (u32 *)&sr->mc_vregs + ELF_NEVRREG)) | ||
330 | return 1; | ||
331 | #endif /* CONFIG_SPE */ | ||
332 | |||
333 | #ifndef CONFIG_SMP | ||
334 | preempt_disable(); | ||
335 | if (last_task_used_math == current) | ||
336 | last_task_used_math = NULL; | ||
337 | if (last_task_used_altivec == current) | ||
338 | last_task_used_altivec = NULL; | ||
339 | if (last_task_used_spe == current) | ||
340 | last_task_used_spe = NULL; | ||
341 | preempt_enable(); | ||
342 | #endif | ||
343 | return 0; | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * Restore the user process's signal mask | ||
348 | */ | ||
349 | static void | ||
350 | restore_sigmask(sigset_t *set) | ||
351 | { | ||
352 | sigdelsetmask(set, ~_BLOCKABLE); | ||
353 | spin_lock_irq(¤t->sighand->siglock); | ||
354 | current->blocked = *set; | ||
355 | recalc_sigpending(); | ||
356 | spin_unlock_irq(¤t->sighand->siglock); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Set up a signal frame for a "real-time" signal handler | ||
361 | * (one which gets siginfo). | ||
362 | */ | ||
363 | static void | ||
364 | handle_rt_signal(unsigned long sig, struct k_sigaction *ka, | ||
365 | siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, | ||
366 | unsigned long newsp) | ||
367 | { | ||
368 | struct rt_sigframe __user *rt_sf; | ||
369 | struct mcontext __user *frame; | ||
370 | unsigned long origsp = newsp; | ||
371 | |||
372 | /* Set up Signal Frame */ | ||
373 | /* Put a Real Time Context onto stack */ | ||
374 | newsp -= sizeof(*rt_sf); | ||
375 | rt_sf = (struct rt_sigframe __user *) newsp; | ||
376 | |||
377 | /* create a stack frame for the caller of the handler */ | ||
378 | newsp -= __SIGNAL_FRAMESIZE + 16; | ||
379 | |||
380 | if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) | ||
381 | goto badframe; | ||
382 | |||
383 | /* Put the siginfo & fill in most of the ucontext */ | ||
384 | if (copy_siginfo_to_user(&rt_sf->info, info) | ||
385 | || __put_user(0, &rt_sf->uc.uc_flags) | ||
386 | || __put_user(0, &rt_sf->uc.uc_link) | ||
387 | || __put_user(current->sas_ss_sp, &rt_sf->uc.uc_stack.ss_sp) | ||
388 | || __put_user(sas_ss_flags(regs->gpr[1]), | ||
389 | &rt_sf->uc.uc_stack.ss_flags) | ||
390 | || __put_user(current->sas_ss_size, &rt_sf->uc.uc_stack.ss_size) | ||
391 | || __put_user(&rt_sf->uc.uc_mcontext, &rt_sf->uc.uc_regs) | ||
392 | || __copy_to_user(&rt_sf->uc.uc_sigmask, oldset, sizeof(*oldset))) | ||
393 | goto badframe; | ||
394 | |||
395 | /* Save user registers on the stack */ | ||
396 | frame = &rt_sf->uc.uc_mcontext; | ||
397 | if (save_user_regs(regs, frame, __NR_rt_sigreturn)) | ||
398 | goto badframe; | ||
399 | |||
400 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | ||
401 | goto badframe; | ||
402 | regs->gpr[1] = newsp; | ||
403 | regs->gpr[3] = sig; | ||
404 | regs->gpr[4] = (unsigned long) &rt_sf->info; | ||
405 | regs->gpr[5] = (unsigned long) &rt_sf->uc; | ||
406 | regs->gpr[6] = (unsigned long) rt_sf; | ||
407 | regs->nip = (unsigned long) ka->sa.sa_handler; | ||
408 | regs->link = (unsigned long) frame->tramp; | ||
409 | regs->trap = 0; | ||
410 | |||
411 | return; | ||
412 | |||
413 | badframe: | ||
414 | #ifdef DEBUG_SIG | ||
415 | printk("badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n", | ||
416 | regs, frame, newsp); | ||
417 | #endif | ||
418 | force_sigsegv(sig, current); | ||
419 | } | ||
420 | |||
421 | static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sig) | ||
422 | { | ||
423 | sigset_t set; | ||
424 | struct mcontext __user *mcp; | ||
425 | |||
426 | if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(set)) | ||
427 | || __get_user(mcp, &ucp->uc_regs)) | ||
428 | return -EFAULT; | ||
429 | restore_sigmask(&set); | ||
430 | if (restore_user_regs(regs, mcp, sig)) | ||
431 | return -EFAULT; | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | int sys_swapcontext(struct ucontext __user *old_ctx, | ||
437 | struct ucontext __user *new_ctx, | ||
438 | int ctx_size, int r6, int r7, int r8, struct pt_regs *regs) | ||
439 | { | ||
440 | unsigned char tmp; | ||
441 | |||
442 | /* Context size is for future use. Right now, we only make sure | ||
443 | * we are passed something we understand | ||
444 | */ | ||
445 | if (ctx_size < sizeof(struct ucontext)) | ||
446 | return -EINVAL; | ||
447 | |||
448 | if (old_ctx != NULL) { | ||
449 | if (!access_ok(VERIFY_WRITE, old_ctx, sizeof(*old_ctx)) | ||
450 | || save_user_regs(regs, &old_ctx->uc_mcontext, 0) | ||
451 | || __copy_to_user(&old_ctx->uc_sigmask, | ||
452 | ¤t->blocked, sizeof(sigset_t)) | ||
453 | || __put_user(&old_ctx->uc_mcontext, &old_ctx->uc_regs)) | ||
454 | return -EFAULT; | ||
455 | } | ||
456 | if (new_ctx == NULL) | ||
457 | return 0; | ||
458 | if (!access_ok(VERIFY_READ, new_ctx, sizeof(*new_ctx)) | ||
459 | || __get_user(tmp, (u8 __user *) new_ctx) | ||
460 | || __get_user(tmp, (u8 __user *) (new_ctx + 1) - 1)) | ||
461 | return -EFAULT; | ||
462 | |||
463 | /* | ||
464 | * If we get a fault copying the context into the kernel's | ||
465 | * image of the user's registers, we can't just return -EFAULT | ||
466 | * because the user's registers will be corrupted. For instance | ||
467 | * the NIP value may have been updated but not some of the | ||
468 | * other registers. Given that we have done the access_ok | ||
469 | * and successfully read the first and last bytes of the region | ||
470 | * above, this should only happen in an out-of-memory situation | ||
471 | * or if another thread unmaps the region containing the context. | ||
472 | * We kill the task with a SIGSEGV in this situation. | ||
473 | */ | ||
474 | if (do_setcontext(new_ctx, regs, 0)) | ||
475 | do_exit(SIGSEGV); | ||
476 | sigreturn_exit(regs); | ||
477 | /* doesn't actually return back to here */ | ||
478 | return 0; | ||
479 | } | ||
480 | |||
481 | int sys_rt_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | ||
482 | struct pt_regs *regs) | ||
483 | { | ||
484 | struct rt_sigframe __user *rt_sf; | ||
485 | |||
486 | /* Always make any pending restarted system calls return -EINTR */ | ||
487 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
488 | |||
489 | rt_sf = (struct rt_sigframe __user *) | ||
490 | (regs->gpr[1] + __SIGNAL_FRAMESIZE + 16); | ||
491 | if (!access_ok(VERIFY_READ, rt_sf, sizeof(struct rt_sigframe))) | ||
492 | goto bad; | ||
493 | if (do_setcontext(&rt_sf->uc, regs, 1)) | ||
494 | goto bad; | ||
495 | |||
496 | /* | ||
497 | * It's not clear whether or why it is desirable to save the | ||
498 | * sigaltstack setting on signal delivery and restore it on | ||
499 | * signal return. But other architectures do this and we have | ||
500 | * always done it up until now so it is probably better not to | ||
501 | * change it. -- paulus | ||
502 | */ | ||
503 | do_sigaltstack(&rt_sf->uc.uc_stack, NULL, regs->gpr[1]); | ||
504 | |||
505 | sigreturn_exit(regs); /* doesn't return here */ | ||
506 | return 0; | ||
507 | |||
508 | bad: | ||
509 | force_sig(SIGSEGV, current); | ||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | int sys_debug_setcontext(struct ucontext __user *ctx, | ||
514 | int ndbg, struct sig_dbg_op __user *dbg, | ||
515 | int r6, int r7, int r8, | ||
516 | struct pt_regs *regs) | ||
517 | { | ||
518 | struct sig_dbg_op op; | ||
519 | int i; | ||
520 | unsigned long new_msr = regs->msr; | ||
521 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
522 | unsigned long new_dbcr0 = current->thread.dbcr0; | ||
523 | #endif | ||
524 | |||
525 | for (i=0; i<ndbg; i++) { | ||
526 | if (__copy_from_user(&op, dbg, sizeof(op))) | ||
527 | return -EFAULT; | ||
528 | switch (op.dbg_type) { | ||
529 | case SIG_DBG_SINGLE_STEPPING: | ||
530 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
531 | if (op.dbg_value) { | ||
532 | new_msr |= MSR_DE; | ||
533 | new_dbcr0 |= (DBCR0_IDM | DBCR0_IC); | ||
534 | } else { | ||
535 | new_msr &= ~MSR_DE; | ||
536 | new_dbcr0 &= ~(DBCR0_IDM | DBCR0_IC); | ||
537 | } | ||
538 | #else | ||
539 | if (op.dbg_value) | ||
540 | new_msr |= MSR_SE; | ||
541 | else | ||
542 | new_msr &= ~MSR_SE; | ||
543 | #endif | ||
544 | break; | ||
545 | case SIG_DBG_BRANCH_TRACING: | ||
546 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
547 | return -EINVAL; | ||
548 | #else | ||
549 | if (op.dbg_value) | ||
550 | new_msr |= MSR_BE; | ||
551 | else | ||
552 | new_msr &= ~MSR_BE; | ||
553 | #endif | ||
554 | break; | ||
555 | |||
556 | default: | ||
557 | return -EINVAL; | ||
558 | } | ||
559 | } | ||
560 | |||
561 | /* We wait until here to actually install the values in the | ||
562 | registers so if we fail in the above loop, it will not | ||
563 | affect the contents of these registers. After this point, | ||
564 | failure is a problem, anyway, and it's very unlikely unless | ||
565 | the user is really doing something wrong. */ | ||
566 | regs->msr = new_msr; | ||
567 | #if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) | ||
568 | current->thread.dbcr0 = new_dbcr0; | ||
569 | #endif | ||
570 | |||
571 | /* | ||
572 | * If we get a fault copying the context into the kernel's | ||
573 | * image of the user's registers, we can't just return -EFAULT | ||
574 | * because the user's registers will be corrupted. For instance | ||
575 | * the NIP value may have been updated but not some of the | ||
576 | * other registers. Given that we have done the access_ok | ||
577 | * and successfully read the first and last bytes of the region | ||
578 | * above, this should only happen in an out-of-memory situation | ||
579 | * or if another thread unmaps the region containing the context. | ||
580 | * We kill the task with a SIGSEGV in this situation. | ||
581 | */ | ||
582 | if (do_setcontext(ctx, regs, 1)) { | ||
583 | force_sig(SIGSEGV, current); | ||
584 | goto out; | ||
585 | } | ||
586 | |||
587 | /* | ||
588 | * It's not clear whether or why it is desirable to save the | ||
589 | * sigaltstack setting on signal delivery and restore it on | ||
590 | * signal return. But other architectures do this and we have | ||
591 | * always done it up until now so it is probably better not to | ||
592 | * change it. -- paulus | ||
593 | */ | ||
594 | do_sigaltstack(&ctx->uc_stack, NULL, regs->gpr[1]); | ||
595 | |||
596 | sigreturn_exit(regs); | ||
597 | /* doesn't actually return back to here */ | ||
598 | |||
599 | out: | ||
600 | return 0; | ||
601 | } | ||
602 | |||
603 | /* | ||
604 | * OK, we're invoking a handler | ||
605 | */ | ||
606 | static void | ||
607 | handle_signal(unsigned long sig, struct k_sigaction *ka, | ||
608 | siginfo_t *info, sigset_t *oldset, struct pt_regs * regs, | ||
609 | unsigned long newsp) | ||
610 | { | ||
611 | struct sigcontext __user *sc; | ||
612 | struct sigregs __user *frame; | ||
613 | unsigned long origsp = newsp; | ||
614 | |||
615 | /* Set up Signal Frame */ | ||
616 | newsp -= sizeof(struct sigregs); | ||
617 | frame = (struct sigregs __user *) newsp; | ||
618 | |||
619 | /* Put a sigcontext on the stack */ | ||
620 | newsp -= sizeof(*sc); | ||
621 | sc = (struct sigcontext __user *) newsp; | ||
622 | |||
623 | /* create a stack frame for the caller of the handler */ | ||
624 | newsp -= __SIGNAL_FRAMESIZE; | ||
625 | |||
626 | if (!access_ok(VERIFY_WRITE, (void __user *) newsp, origsp - newsp)) | ||
627 | goto badframe; | ||
628 | |||
629 | #if _NSIG != 64 | ||
630 | #error "Please adjust handle_signal()" | ||
631 | #endif | ||
632 | if (__put_user((unsigned long) ka->sa.sa_handler, &sc->handler) | ||
633 | || __put_user(oldset->sig[0], &sc->oldmask) | ||
634 | || __put_user(oldset->sig[1], &sc->_unused[3]) | ||
635 | || __put_user((struct pt_regs __user *)frame, &sc->regs) | ||
636 | || __put_user(sig, &sc->signal)) | ||
637 | goto badframe; | ||
638 | |||
639 | if (save_user_regs(regs, &frame->mctx, __NR_sigreturn)) | ||
640 | goto badframe; | ||
641 | |||
642 | if (put_user(regs->gpr[1], (unsigned long __user *)newsp)) | ||
643 | goto badframe; | ||
644 | regs->gpr[1] = newsp; | ||
645 | regs->gpr[3] = sig; | ||
646 | regs->gpr[4] = (unsigned long) sc; | ||
647 | regs->nip = (unsigned long) ka->sa.sa_handler; | ||
648 | regs->link = (unsigned long) frame->mctx.tramp; | ||
649 | regs->trap = 0; | ||
650 | |||
651 | return; | ||
652 | |||
653 | badframe: | ||
654 | #ifdef DEBUG_SIG | ||
655 | printk("badframe in handle_signal, regs=%p frame=%p newsp=%lx\n", | ||
656 | regs, frame, newsp); | ||
657 | #endif | ||
658 | force_sigsegv(sig, current); | ||
659 | } | ||
660 | |||
661 | /* | ||
662 | * Do a signal return; undo the signal stack. | ||
663 | */ | ||
664 | int sys_sigreturn(int r3, int r4, int r5, int r6, int r7, int r8, | ||
665 | struct pt_regs *regs) | ||
666 | { | ||
667 | struct sigcontext __user *sc; | ||
668 | struct sigcontext sigctx; | ||
669 | struct mcontext __user *sr; | ||
670 | sigset_t set; | ||
671 | |||
672 | /* Always make any pending restarted system calls return -EINTR */ | ||
673 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | ||
674 | |||
675 | sc = (struct sigcontext __user *)(regs->gpr[1] + __SIGNAL_FRAMESIZE); | ||
676 | if (copy_from_user(&sigctx, sc, sizeof(sigctx))) | ||
677 | goto badframe; | ||
678 | |||
679 | set.sig[0] = sigctx.oldmask; | ||
680 | set.sig[1] = sigctx._unused[3]; | ||
681 | restore_sigmask(&set); | ||
682 | |||
683 | sr = (struct mcontext __user *) sigctx.regs; | ||
684 | if (!access_ok(VERIFY_READ, sr, sizeof(*sr)) | ||
685 | || restore_user_regs(regs, sr, 1)) | ||
686 | goto badframe; | ||
687 | |||
688 | sigreturn_exit(regs); /* doesn't return */ | ||
689 | return 0; | ||
690 | |||
691 | badframe: | ||
692 | force_sig(SIGSEGV, current); | ||
693 | return 0; | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * Note that 'init' is a special process: it doesn't get signals it doesn't | ||
698 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | ||
699 | * mistake. | ||
700 | */ | ||
701 | int do_signal(sigset_t *oldset, struct pt_regs *regs) | ||
702 | { | ||
703 | siginfo_t info; | ||
704 | struct k_sigaction ka; | ||
705 | unsigned long frame, newsp; | ||
706 | int signr, ret; | ||
707 | |||
708 | if (try_to_freeze()) { | ||
709 | signr = 0; | ||
710 | if (!signal_pending(current)) | ||
711 | goto no_signal; | ||
712 | } | ||
713 | |||
714 | if (!oldset) | ||
715 | oldset = ¤t->blocked; | ||
716 | |||
717 | newsp = frame = 0; | ||
718 | |||
719 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | ||
720 | no_signal: | ||
721 | if (TRAP(regs) == 0x0C00 /* System Call! */ | ||
722 | && regs->ccr & 0x10000000 /* error signalled */ | ||
723 | && ((ret = regs->gpr[3]) == ERESTARTSYS | ||
724 | || ret == ERESTARTNOHAND || ret == ERESTARTNOINTR | ||
725 | || ret == ERESTART_RESTARTBLOCK)) { | ||
726 | |||
727 | if (signr > 0 | ||
728 | && (ret == ERESTARTNOHAND || ret == ERESTART_RESTARTBLOCK | ||
729 | || (ret == ERESTARTSYS | ||
730 | && !(ka.sa.sa_flags & SA_RESTART)))) { | ||
731 | /* make the system call return an EINTR error */ | ||
732 | regs->result = -EINTR; | ||
733 | regs->gpr[3] = EINTR; | ||
734 | /* note that the cr0.SO bit is already set */ | ||
735 | } else { | ||
736 | regs->nip -= 4; /* Back up & retry system call */ | ||
737 | regs->result = 0; | ||
738 | regs->trap = 0; | ||
739 | if (ret == ERESTART_RESTARTBLOCK) | ||
740 | regs->gpr[0] = __NR_restart_syscall; | ||
741 | else | ||
742 | regs->gpr[3] = regs->orig_gpr3; | ||
743 | } | ||
744 | } | ||
745 | |||
746 | if (signr == 0) | ||
747 | return 0; /* no signals delivered */ | ||
748 | |||
749 | if ((ka.sa.sa_flags & SA_ONSTACK) && current->sas_ss_size | ||
750 | && !on_sig_stack(regs->gpr[1])) | ||
751 | newsp = current->sas_ss_sp + current->sas_ss_size; | ||
752 | else | ||
753 | newsp = regs->gpr[1]; | ||
754 | newsp &= ~0xfUL; | ||
755 | |||
756 | /* Whee! Actually deliver the signal. */ | ||
757 | if (ka.sa.sa_flags & SA_SIGINFO) | ||
758 | handle_rt_signal(signr, &ka, &info, oldset, regs, newsp); | ||
759 | else | ||
760 | handle_signal(signr, &ka, &info, oldset, regs, newsp); | ||
761 | |||
762 | spin_lock_irq(¤t->sighand->siglock); | ||
763 | sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); | ||
764 | if (!(ka.sa.sa_flags & SA_NODEFER)) | ||
765 | sigaddset(¤t->blocked, signr); | ||
766 | recalc_sigpending(); | ||
767 | spin_unlock_irq(¤t->sighand->siglock); | ||
768 | |||
769 | return 1; | ||
770 | } | ||
771 | |||
diff --git a/arch/ppc64/kernel/Makefile b/arch/ppc64/kernel/Makefile index 0be7c7ecefdf..19846d78b329 100644 --- a/arch/ppc64/kernel/Makefile +++ b/arch/ppc64/kernel/Makefile | |||
@@ -15,7 +15,7 @@ obj-y += irq.o idle.o dma.o \ | |||
15 | time.o signal.o \ | 15 | time.o signal.o \ |
16 | align.o bitops.o pacaData.o \ | 16 | align.o bitops.o pacaData.o \ |
17 | udbg.o ioctl32.o \ | 17 | udbg.o ioctl32.o \ |
18 | ptrace32.o signal32.o rtc.o \ | 18 | ptrace32.o rtc.o \ |
19 | cpu_setup_power4.o \ | 19 | cpu_setup_power4.o \ |
20 | iommu.o sysfs.o vdso.o pmc.o firmware.o | 20 | iommu.o sysfs.o vdso.o pmc.o firmware.o |
21 | obj-y += vdso32/ vdso64/ | 21 | obj-y += vdso32/ vdso64/ |
diff --git a/include/asm-ppc64/ppc32.h b/include/asm-ppc64/ppc32.h index 6b44a8caf395..3945a55d112a 100644 --- a/include/asm-ppc64/ppc32.h +++ b/include/asm-ppc64/ppc32.h | |||
@@ -70,18 +70,18 @@ typedef struct compat_siginfo { | |||
70 | #define __old_sigaction32 old_sigaction32 | 70 | #define __old_sigaction32 old_sigaction32 |
71 | 71 | ||
72 | struct __old_sigaction32 { | 72 | struct __old_sigaction32 { |
73 | unsigned sa_handler; | 73 | compat_uptr_t sa_handler; |
74 | compat_old_sigset_t sa_mask; | 74 | compat_old_sigset_t sa_mask; |
75 | unsigned int sa_flags; | 75 | unsigned int sa_flags; |
76 | unsigned sa_restorer; /* not used by Linux/SPARC yet */ | 76 | compat_uptr_t sa_restorer; /* not used by Linux/SPARC yet */ |
77 | }; | 77 | }; |
78 | 78 | ||
79 | 79 | ||
80 | 80 | ||
81 | struct sigaction32 { | 81 | struct sigaction32 { |
82 | unsigned int sa_handler; /* Really a pointer, but need to deal with 32 bits */ | 82 | compat_uptr_t sa_handler; /* Really a pointer, but need to deal with 32 bits */ |
83 | unsigned int sa_flags; | 83 | unsigned int sa_flags; |
84 | unsigned int sa_restorer; /* Another 32 bit pointer */ | 84 | compat_uptr_t sa_restorer; /* Another 32 bit pointer */ |
85 | compat_sigset_t sa_mask; /* A 32 bit mask */ | 85 | compat_sigset_t sa_mask; /* A 32 bit mask */ |
86 | }; | 86 | }; |
87 | 87 | ||
@@ -94,9 +94,9 @@ typedef struct sigaltstack_32 { | |||
94 | struct sigcontext32 { | 94 | struct sigcontext32 { |
95 | unsigned int _unused[4]; | 95 | unsigned int _unused[4]; |
96 | int signal; | 96 | int signal; |
97 | unsigned int handler; | 97 | compat_uptr_t handler; |
98 | unsigned int oldmask; | 98 | unsigned int oldmask; |
99 | u32 regs; /* 4 byte pointer to the pt_regs32 structure. */ | 99 | compat_uptr_t regs; /* 4 byte pointer to the pt_regs32 structure. */ |
100 | }; | 100 | }; |
101 | 101 | ||
102 | struct mcontext32 { | 102 | struct mcontext32 { |
@@ -111,7 +111,7 @@ struct ucontext32 { | |||
111 | unsigned int uc_link; | 111 | unsigned int uc_link; |
112 | stack_32_t uc_stack; | 112 | stack_32_t uc_stack; |
113 | int uc_pad[7]; | 113 | int uc_pad[7]; |
114 | u32 uc_regs; /* points to uc_mcontext field */ | 114 | compat_uptr_t uc_regs; /* points to uc_mcontext field */ |
115 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ | 115 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
116 | /* glibc has 1024-bit signal masks, ours are 64-bit */ | 116 | /* glibc has 1024-bit signal masks, ours are 64-bit */ |
117 | int uc_maskext[30]; | 117 | int uc_maskext[30]; |