diff options
Diffstat (limited to 'arch/x86/kernel/signal_64.c')
-rw-r--r-- | arch/x86/kernel/signal_64.c | 362 |
1 files changed, 152 insertions, 210 deletions
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index ca316b5b742c..a5c9627f4db9 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c | |||
@@ -15,17 +15,21 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/wait.h> | 16 | #include <linux/wait.h> |
17 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
18 | #include <linux/tracehook.h> | ||
18 | #include <linux/unistd.h> | 19 | #include <linux/unistd.h> |
19 | #include <linux/stddef.h> | 20 | #include <linux/stddef.h> |
20 | #include <linux/personality.h> | 21 | #include <linux/personality.h> |
21 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | #include <linux/uaccess.h> | ||
24 | |||
22 | #include <asm/processor.h> | 25 | #include <asm/processor.h> |
23 | #include <asm/ucontext.h> | 26 | #include <asm/ucontext.h> |
24 | #include <asm/uaccess.h> | ||
25 | #include <asm/i387.h> | 27 | #include <asm/i387.h> |
26 | #include <asm/proto.h> | 28 | #include <asm/proto.h> |
27 | #include <asm/ia32_unistd.h> | 29 | #include <asm/ia32_unistd.h> |
28 | #include <asm/mce.h> | 30 | #include <asm/mce.h> |
31 | #include <asm/syscall.h> | ||
32 | #include <asm/syscalls.h> | ||
29 | #include "sigframe.h" | 33 | #include "sigframe.h" |
30 | 34 | ||
31 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 35 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
@@ -41,11 +45,6 @@ | |||
41 | # define FIX_EFLAGS __FIX_EFLAGS | 45 | # define FIX_EFLAGS __FIX_EFLAGS |
42 | #endif | 46 | #endif |
43 | 47 | ||
44 | int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | ||
45 | sigset_t *set, struct pt_regs * regs); | ||
46 | int ia32_setup_frame(int sig, struct k_sigaction *ka, | ||
47 | sigset_t *set, struct pt_regs * regs); | ||
48 | |||
49 | asmlinkage long | 48 | asmlinkage long |
50 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 49 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
51 | struct pt_regs *regs) | 50 | struct pt_regs *regs) |
@@ -53,67 +52,14 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | |||
53 | return do_sigaltstack(uss, uoss, regs->sp); | 52 | return do_sigaltstack(uss, uoss, regs->sp); |
54 | } | 53 | } |
55 | 54 | ||
56 | /* | 55 | #define COPY(x) { \ |
57 | * Signal frame handlers. | 56 | err |= __get_user(regs->x, &sc->x); \ |
58 | */ | ||
59 | |||
60 | static inline int save_i387(struct _fpstate __user *buf) | ||
61 | { | ||
62 | struct task_struct *tsk = current; | ||
63 | int err = 0; | ||
64 | |||
65 | BUILD_BUG_ON(sizeof(struct user_i387_struct) != | ||
66 | sizeof(tsk->thread.xstate->fxsave)); | ||
67 | |||
68 | if ((unsigned long)buf % 16) | ||
69 | printk("save_i387: bad fpstate %p\n", buf); | ||
70 | |||
71 | if (!used_math()) | ||
72 | return 0; | ||
73 | clear_used_math(); /* trigger finit */ | ||
74 | if (task_thread_info(tsk)->status & TS_USEDFPU) { | ||
75 | err = save_i387_checking((struct i387_fxsave_struct __user *) | ||
76 | buf); | ||
77 | if (err) | ||
78 | return err; | ||
79 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | ||
80 | stts(); | ||
81 | } else { | ||
82 | if (__copy_to_user(buf, &tsk->thread.xstate->fxsave, | ||
83 | sizeof(struct i387_fxsave_struct))) | ||
84 | return -1; | ||
85 | } | ||
86 | return 1; | ||
87 | } | 57 | } |
88 | 58 | ||
89 | /* | 59 | #define COPY_SEG_STRICT(seg) { \ |
90 | * This restores directly out of user space. Exceptions are handled. | 60 | unsigned short tmp; \ |
91 | */ | 61 | err |= __get_user(tmp, &sc->seg); \ |
92 | static inline int restore_i387(struct _fpstate __user *buf) | 62 | regs->seg = tmp | 3; \ |
93 | { | ||
94 | struct task_struct *tsk = current; | ||
95 | int err; | ||
96 | |||
97 | if (!used_math()) { | ||
98 | err = init_fpu(tsk); | ||
99 | if (err) | ||
100 | return err; | ||
101 | } | ||
102 | |||
103 | if (!(task_thread_info(current)->status & TS_USEDFPU)) { | ||
104 | clts(); | ||
105 | task_thread_info(current)->status |= TS_USEDFPU; | ||
106 | } | ||
107 | err = restore_fpu_checking((__force struct i387_fxsave_struct *)buf); | ||
108 | if (unlikely(err)) { | ||
109 | /* | ||
110 | * Encountered an error while doing the restore from the | ||
111 | * user buffer, clear the fpu state. | ||
112 | */ | ||
113 | clear_fpu(tsk); | ||
114 | clear_used_math(); | ||
115 | } | ||
116 | return err; | ||
117 | } | 63 | } |
118 | 64 | ||
119 | /* | 65 | /* |
@@ -123,13 +69,13 @@ static int | |||
123 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | 69 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, |
124 | unsigned long *pax) | 70 | unsigned long *pax) |
125 | { | 71 | { |
72 | void __user *buf; | ||
73 | unsigned int tmpflags; | ||
126 | unsigned int err = 0; | 74 | unsigned int err = 0; |
127 | 75 | ||
128 | /* Always make any pending restarted system calls return -EINTR */ | 76 | /* Always make any pending restarted system calls return -EINTR */ |
129 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 77 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
130 | 78 | ||
131 | #define COPY(x) err |= __get_user(regs->x, &sc->x) | ||
132 | |||
133 | COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); | 79 | COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); |
134 | COPY(dx); COPY(cx); COPY(ip); | 80 | COPY(dx); COPY(cx); COPY(ip); |
135 | COPY(r8); | 81 | COPY(r8); |
@@ -144,48 +90,24 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | |||
144 | /* Kernel saves and restores only the CS segment register on signals, | 90 | /* Kernel saves and restores only the CS segment register on signals, |
145 | * which is the bare minimum needed to allow mixed 32/64-bit code. | 91 | * which is the bare minimum needed to allow mixed 32/64-bit code. |
146 | * App's signal handler can save/restore other segments if needed. */ | 92 | * App's signal handler can save/restore other segments if needed. */ |
147 | { | 93 | COPY_SEG_STRICT(cs); |
148 | unsigned cs; | ||
149 | err |= __get_user(cs, &sc->cs); | ||
150 | regs->cs = cs | 3; /* Force into user mode */ | ||
151 | } | ||
152 | 94 | ||
153 | { | 95 | err |= __get_user(tmpflags, &sc->flags); |
154 | unsigned int tmpflags; | 96 | regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); |
155 | err |= __get_user(tmpflags, &sc->flags); | 97 | regs->orig_ax = -1; /* disable syscall checks */ |
156 | regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS); | ||
157 | regs->orig_ax = -1; /* disable syscall checks */ | ||
158 | } | ||
159 | 98 | ||
160 | { | 99 | err |= __get_user(buf, &sc->fpstate); |
161 | struct _fpstate __user * buf; | 100 | err |= restore_i387_xstate(buf); |
162 | err |= __get_user(buf, &sc->fpstate); | ||
163 | |||
164 | if (buf) { | ||
165 | if (!access_ok(VERIFY_READ, buf, sizeof(*buf))) | ||
166 | goto badframe; | ||
167 | err |= restore_i387(buf); | ||
168 | } else { | ||
169 | struct task_struct *me = current; | ||
170 | if (used_math()) { | ||
171 | clear_fpu(me); | ||
172 | clear_used_math(); | ||
173 | } | ||
174 | } | ||
175 | } | ||
176 | 101 | ||
177 | err |= __get_user(*pax, &sc->ax); | 102 | err |= __get_user(*pax, &sc->ax); |
178 | return err; | 103 | return err; |
179 | |||
180 | badframe: | ||
181 | return 1; | ||
182 | } | 104 | } |
183 | 105 | ||
184 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | 106 | static long do_rt_sigreturn(struct pt_regs *regs) |
185 | { | 107 | { |
186 | struct rt_sigframe __user *frame; | 108 | struct rt_sigframe __user *frame; |
187 | sigset_t set; | ||
188 | unsigned long ax; | 109 | unsigned long ax; |
110 | sigset_t set; | ||
189 | 111 | ||
190 | frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); | 112 | frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long)); |
191 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 113 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
@@ -198,7 +120,7 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | |||
198 | current->blocked = set; | 120 | current->blocked = set; |
199 | recalc_sigpending(); | 121 | recalc_sigpending(); |
200 | spin_unlock_irq(¤t->sighand->siglock); | 122 | spin_unlock_irq(¤t->sighand->siglock); |
201 | 123 | ||
202 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) | 124 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax)) |
203 | goto badframe; | 125 | goto badframe; |
204 | 126 | ||
@@ -208,16 +130,22 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | |||
208 | return ax; | 130 | return ax; |
209 | 131 | ||
210 | badframe: | 132 | badframe: |
211 | signal_fault(regs,frame,"sigreturn"); | 133 | signal_fault(regs, frame, "rt_sigreturn"); |
212 | return 0; | 134 | return 0; |
213 | } | 135 | } |
136 | |||
137 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | ||
138 | { | ||
139 | return do_rt_sigreturn(regs); | ||
140 | } | ||
214 | 141 | ||
215 | /* | 142 | /* |
216 | * Set up a signal frame. | 143 | * Set up a signal frame. |
217 | */ | 144 | */ |
218 | 145 | ||
219 | static inline int | 146 | static inline int |
220 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, unsigned long mask, struct task_struct *me) | 147 | setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, |
148 | unsigned long mask, struct task_struct *me) | ||
221 | { | 149 | { |
222 | int err = 0; | 150 | int err = 0; |
223 | 151 | ||
@@ -269,41 +197,40 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) | |||
269 | sp = current->sas_ss_sp + current->sas_ss_size; | 197 | sp = current->sas_ss_sp + current->sas_ss_size; |
270 | } | 198 | } |
271 | 199 | ||
272 | return (void __user *)round_down(sp - size, 16); | 200 | return (void __user *)round_down(sp - size, 64); |
273 | } | 201 | } |
274 | 202 | ||
275 | static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | 203 | static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
276 | sigset_t *set, struct pt_regs * regs) | 204 | sigset_t *set, struct pt_regs *regs) |
277 | { | 205 | { |
278 | struct rt_sigframe __user *frame; | 206 | struct rt_sigframe __user *frame; |
279 | struct _fpstate __user *fp = NULL; | 207 | void __user *fp = NULL; |
280 | int err = 0; | 208 | int err = 0; |
281 | struct task_struct *me = current; | 209 | struct task_struct *me = current; |
282 | 210 | ||
283 | if (used_math()) { | 211 | if (used_math()) { |
284 | fp = get_stack(ka, regs, sizeof(struct _fpstate)); | 212 | fp = get_stack(ka, regs, sig_xstate_size); |
285 | frame = (void __user *)round_down( | 213 | frame = (void __user *)round_down( |
286 | (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; | 214 | (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8; |
287 | 215 | ||
288 | if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) | 216 | if (save_i387_xstate(fp) < 0) |
289 | goto give_sigsegv; | 217 | return -EFAULT; |
290 | |||
291 | if (save_i387(fp) < 0) | ||
292 | err |= -1; | ||
293 | } else | 218 | } else |
294 | frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; | 219 | frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8; |
295 | 220 | ||
296 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) | 221 | if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) |
297 | goto give_sigsegv; | 222 | return -EFAULT; |
298 | 223 | ||
299 | if (ka->sa.sa_flags & SA_SIGINFO) { | 224 | if (ka->sa.sa_flags & SA_SIGINFO) { |
300 | err |= copy_siginfo_to_user(&frame->info, info); | 225 | if (copy_siginfo_to_user(&frame->info, info)) |
301 | if (err) | 226 | return -EFAULT; |
302 | goto give_sigsegv; | ||
303 | } | 227 | } |
304 | 228 | ||
305 | /* Create the ucontext. */ | 229 | /* Create the ucontext. */ |
306 | err |= __put_user(0, &frame->uc.uc_flags); | 230 | if (cpu_has_xsave) |
231 | err |= __put_user(UC_FP_XSTATE, &frame->uc.uc_flags); | ||
232 | else | ||
233 | err |= __put_user(0, &frame->uc.uc_flags); | ||
307 | err |= __put_user(0, &frame->uc.uc_link); | 234 | err |= __put_user(0, &frame->uc.uc_link); |
308 | err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 235 | err |= __put_user(me->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
309 | err |= __put_user(sas_ss_flags(regs->sp), | 236 | err |= __put_user(sas_ss_flags(regs->sp), |
@@ -311,9 +238,9 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
311 | err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); | 238 | err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); |
312 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); | 239 | err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0], me); |
313 | err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); | 240 | err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); |
314 | if (sizeof(*set) == 16) { | 241 | if (sizeof(*set) == 16) { |
315 | __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); | 242 | __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); |
316 | __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); | 243 | __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); |
317 | } else | 244 | } else |
318 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | 245 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); |
319 | 246 | ||
@@ -324,15 +251,15 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
324 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); | 251 | err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); |
325 | } else { | 252 | } else { |
326 | /* could use a vstub here */ | 253 | /* could use a vstub here */ |
327 | goto give_sigsegv; | 254 | return -EFAULT; |
328 | } | 255 | } |
329 | 256 | ||
330 | if (err) | 257 | if (err) |
331 | goto give_sigsegv; | 258 | return -EFAULT; |
332 | 259 | ||
333 | /* Set up registers for signal handler */ | 260 | /* Set up registers for signal handler */ |
334 | regs->di = sig; | 261 | regs->di = sig; |
335 | /* In case the signal handler was declared without prototypes */ | 262 | /* In case the signal handler was declared without prototypes */ |
336 | regs->ax = 0; | 263 | regs->ax = 0; |
337 | 264 | ||
338 | /* This also works for non SA_SIGINFO handlers because they expect the | 265 | /* This also works for non SA_SIGINFO handlers because they expect the |
@@ -348,44 +275,45 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
348 | regs->cs = __USER_CS; | 275 | regs->cs = __USER_CS; |
349 | 276 | ||
350 | return 0; | 277 | return 0; |
351 | |||
352 | give_sigsegv: | ||
353 | force_sigsegv(sig, current); | ||
354 | return -EFAULT; | ||
355 | } | 278 | } |
356 | 279 | ||
357 | /* | 280 | /* |
358 | * Return -1L or the syscall number that @regs is executing. | 281 | * OK, we're invoking a handler |
359 | */ | 282 | */ |
360 | static long current_syscall(struct pt_regs *regs) | 283 | static int signr_convert(int sig) |
361 | { | 284 | { |
362 | /* | 285 | return sig; |
363 | * We always sign-extend a -1 value being set here, | ||
364 | * so this is always either -1L or a syscall number. | ||
365 | */ | ||
366 | return regs->orig_ax; | ||
367 | } | 286 | } |
368 | 287 | ||
369 | /* | ||
370 | * Return a value that is -EFOO if the system call in @regs->orig_ax | ||
371 | * returned an error. This only works for @regs from @current. | ||
372 | */ | ||
373 | static long current_syscall_ret(struct pt_regs *regs) | ||
374 | { | ||
375 | #ifdef CONFIG_IA32_EMULATION | 288 | #ifdef CONFIG_IA32_EMULATION |
376 | if (test_thread_flag(TIF_IA32)) | 289 | #define is_ia32 test_thread_flag(TIF_IA32) |
377 | /* | 290 | #else |
378 | * Sign-extend the value so (int)-EFOO becomes (long)-EFOO | 291 | #define is_ia32 0 |
379 | * and will match correctly in comparisons. | ||
380 | */ | ||
381 | return (int) regs->ax; | ||
382 | #endif | 292 | #endif |
383 | return regs->ax; | ||
384 | } | ||
385 | 293 | ||
386 | /* | 294 | static int |
387 | * OK, we're invoking a handler | 295 | setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, |
388 | */ | 296 | sigset_t *set, struct pt_regs *regs) |
297 | { | ||
298 | int usig = signr_convert(sig); | ||
299 | int ret; | ||
300 | |||
301 | /* Set up the stack frame */ | ||
302 | if (is_ia32) { | ||
303 | if (ka->sa.sa_flags & SA_SIGINFO) | ||
304 | ret = ia32_setup_rt_frame(usig, ka, info, set, regs); | ||
305 | else | ||
306 | ret = ia32_setup_frame(usig, ka, set, regs); | ||
307 | } else | ||
308 | ret = __setup_rt_frame(sig, ka, info, set, regs); | ||
309 | |||
310 | if (ret) { | ||
311 | force_sigsegv(sig, current); | ||
312 | return -EFAULT; | ||
313 | } | ||
314 | |||
315 | return ret; | ||
316 | } | ||
389 | 317 | ||
390 | static int | 318 | static int |
391 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | 319 | handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, |
@@ -394,9 +322,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
394 | int ret; | 322 | int ret; |
395 | 323 | ||
396 | /* Are we from a system call? */ | 324 | /* Are we from a system call? */ |
397 | if (current_syscall(regs) >= 0) { | 325 | if (syscall_get_nr(current, regs) >= 0) { |
398 | /* If so, check system call restarting.. */ | 326 | /* If so, check system call restarting.. */ |
399 | switch (current_syscall_ret(regs)) { | 327 | switch (syscall_get_error(current, regs)) { |
400 | case -ERESTART_RESTARTBLOCK: | 328 | case -ERESTART_RESTARTBLOCK: |
401 | case -ERESTARTNOHAND: | 329 | case -ERESTARTNOHAND: |
402 | regs->ax = -EINTR; | 330 | regs->ax = -EINTR; |
@@ -423,50 +351,48 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
423 | likely(test_and_clear_thread_flag(TIF_FORCED_TF))) | 351 | likely(test_and_clear_thread_flag(TIF_FORCED_TF))) |
424 | regs->flags &= ~X86_EFLAGS_TF; | 352 | regs->flags &= ~X86_EFLAGS_TF; |
425 | 353 | ||
426 | #ifdef CONFIG_IA32_EMULATION | ||
427 | if (test_thread_flag(TIF_IA32)) { | ||
428 | if (ka->sa.sa_flags & SA_SIGINFO) | ||
429 | ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs); | ||
430 | else | ||
431 | ret = ia32_setup_frame(sig, ka, oldset, regs); | ||
432 | } else | ||
433 | #endif | ||
434 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 354 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
435 | 355 | ||
436 | if (ret == 0) { | 356 | if (ret) |
437 | /* | 357 | return ret; |
438 | * This has nothing to do with segment registers, | ||
439 | * despite the name. This magic affects uaccess.h | ||
440 | * macros' behavior. Reset it to the normal setting. | ||
441 | */ | ||
442 | set_fs(USER_DS); | ||
443 | 358 | ||
444 | /* | 359 | #ifdef CONFIG_X86_64 |
445 | * Clear the direction flag as per the ABI for function entry. | 360 | /* |
446 | */ | 361 | * This has nothing to do with segment registers, |
447 | regs->flags &= ~X86_EFLAGS_DF; | 362 | * despite the name. This magic affects uaccess.h |
363 | * macros' behavior. Reset it to the normal setting. | ||
364 | */ | ||
365 | set_fs(USER_DS); | ||
366 | #endif | ||
448 | 367 | ||
449 | /* | 368 | /* |
450 | * Clear TF when entering the signal handler, but | 369 | * Clear the direction flag as per the ABI for function entry. |
451 | * notify any tracer that was single-stepping it. | 370 | */ |
452 | * The tracer may want to single-step inside the | 371 | regs->flags &= ~X86_EFLAGS_DF; |
453 | * handler too. | ||
454 | */ | ||
455 | regs->flags &= ~X86_EFLAGS_TF; | ||
456 | if (test_thread_flag(TIF_SINGLESTEP)) | ||
457 | ptrace_notify(SIGTRAP); | ||
458 | |||
459 | spin_lock_irq(¤t->sighand->siglock); | ||
460 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | ||
461 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
462 | sigaddset(¤t->blocked,sig); | ||
463 | recalc_sigpending(); | ||
464 | spin_unlock_irq(¤t->sighand->siglock); | ||
465 | } | ||
466 | 372 | ||
467 | return ret; | 373 | /* |
374 | * Clear TF when entering the signal handler, but | ||
375 | * notify any tracer that was single-stepping it. | ||
376 | * The tracer may want to single-step inside the | ||
377 | * handler too. | ||
378 | */ | ||
379 | regs->flags &= ~X86_EFLAGS_TF; | ||
380 | |||
381 | spin_lock_irq(¤t->sighand->siglock); | ||
382 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | ||
383 | if (!(ka->sa.sa_flags & SA_NODEFER)) | ||
384 | sigaddset(¤t->blocked, sig); | ||
385 | recalc_sigpending(); | ||
386 | spin_unlock_irq(¤t->sighand->siglock); | ||
387 | |||
388 | tracehook_signal_handler(sig, info, ka, regs, | ||
389 | test_thread_flag(TIF_SINGLESTEP)); | ||
390 | |||
391 | return 0; | ||
468 | } | 392 | } |
469 | 393 | ||
394 | #define NR_restart_syscall \ | ||
395 | test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall | ||
470 | /* | 396 | /* |
471 | * Note that 'init' is a special process: it doesn't get signals it doesn't | 397 | * Note that 'init' is a special process: it doesn't get signals it doesn't |
472 | * want to handle. Thus you cannot kill init even with a SIGKILL even by | 398 | * want to handle. Thus you cannot kill init even with a SIGKILL even by |
@@ -496,7 +422,8 @@ static void do_signal(struct pt_regs *regs) | |||
496 | 422 | ||
497 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); | 423 | signr = get_signal_to_deliver(&info, &ka, regs, NULL); |
498 | if (signr > 0) { | 424 | if (signr > 0) { |
499 | /* Re-enable any watchpoints before delivering the | 425 | /* |
426 | * Re-enable any watchpoints before delivering the | ||
500 | * signal to user space. The processor register will | 427 | * signal to user space. The processor register will |
501 | * have been cleared if the watchpoint triggered | 428 | * have been cleared if the watchpoint triggered |
502 | * inside the kernel. | 429 | * inside the kernel. |
@@ -504,7 +431,7 @@ static void do_signal(struct pt_regs *regs) | |||
504 | if (current->thread.debugreg7) | 431 | if (current->thread.debugreg7) |
505 | set_debugreg(current->thread.debugreg7, 7); | 432 | set_debugreg(current->thread.debugreg7, 7); |
506 | 433 | ||
507 | /* Whee! Actually deliver the signal. */ | 434 | /* Whee! Actually deliver the signal. */ |
508 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { | 435 | if (handle_signal(signr, &info, &ka, oldset, regs) == 0) { |
509 | /* | 436 | /* |
510 | * A signal was successfully delivered; the saved | 437 | * A signal was successfully delivered; the saved |
@@ -518,19 +445,18 @@ static void do_signal(struct pt_regs *regs) | |||
518 | } | 445 | } |
519 | 446 | ||
520 | /* Did we come from a system call? */ | 447 | /* Did we come from a system call? */ |
521 | if (current_syscall(regs) >= 0) { | 448 | if (syscall_get_nr(current, regs) >= 0) { |
522 | /* Restart the system call - no handlers present */ | 449 | /* Restart the system call - no handlers present */ |
523 | switch (current_syscall_ret(regs)) { | 450 | switch (syscall_get_error(current, regs)) { |
524 | case -ERESTARTNOHAND: | 451 | case -ERESTARTNOHAND: |
525 | case -ERESTARTSYS: | 452 | case -ERESTARTSYS: |
526 | case -ERESTARTNOINTR: | 453 | case -ERESTARTNOINTR: |
527 | regs->ax = regs->orig_ax; | 454 | regs->ax = regs->orig_ax; |
528 | regs->ip -= 2; | 455 | regs->ip -= 2; |
529 | break; | 456 | break; |
457 | |||
530 | case -ERESTART_RESTARTBLOCK: | 458 | case -ERESTART_RESTARTBLOCK: |
531 | regs->ax = test_thread_flag(TIF_IA32) ? | 459 | regs->ax = NR_restart_syscall; |
532 | __NR_ia32_restart_syscall : | ||
533 | __NR_restart_syscall; | ||
534 | regs->ip -= 2; | 460 | regs->ip -= 2; |
535 | break; | 461 | break; |
536 | } | 462 | } |
@@ -546,29 +472,45 @@ static void do_signal(struct pt_regs *regs) | |||
546 | } | 472 | } |
547 | } | 473 | } |
548 | 474 | ||
549 | void do_notify_resume(struct pt_regs *regs, void *unused, | 475 | /* |
550 | __u32 thread_info_flags) | 476 | * notification of userspace execution resumption |
477 | * - triggered by the TIF_WORK_MASK flags | ||
478 | */ | ||
479 | void | ||
480 | do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) | ||
551 | { | 481 | { |
552 | #ifdef CONFIG_X86_MCE | 482 | #if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE) |
553 | /* notify userspace of pending MCEs */ | 483 | /* notify userspace of pending MCEs */ |
554 | if (thread_info_flags & _TIF_MCE_NOTIFY) | 484 | if (thread_info_flags & _TIF_MCE_NOTIFY) |
555 | mce_notify_user(); | 485 | mce_notify_user(); |
556 | #endif /* CONFIG_X86_MCE */ | 486 | #endif /* CONFIG_X86_64 && CONFIG_X86_MCE */ |
557 | 487 | ||
558 | /* deal with pending signal delivery */ | 488 | /* deal with pending signal delivery */ |
559 | if (thread_info_flags & _TIF_SIGPENDING) | 489 | if (thread_info_flags & _TIF_SIGPENDING) |
560 | do_signal(regs); | 490 | do_signal(regs); |
491 | |||
492 | if (thread_info_flags & _TIF_NOTIFY_RESUME) { | ||
493 | clear_thread_flag(TIF_NOTIFY_RESUME); | ||
494 | tracehook_notify_resume(regs); | ||
495 | } | ||
496 | |||
497 | #ifdef CONFIG_X86_32 | ||
498 | clear_thread_flag(TIF_IRET); | ||
499 | #endif /* CONFIG_X86_32 */ | ||
561 | } | 500 | } |
562 | 501 | ||
563 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) | 502 | void signal_fault(struct pt_regs *regs, void __user *frame, char *where) |
564 | { | 503 | { |
565 | struct task_struct *me = current; | 504 | struct task_struct *me = current; |
505 | |||
566 | if (show_unhandled_signals && printk_ratelimit()) { | 506 | if (show_unhandled_signals && printk_ratelimit()) { |
567 | printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", | 507 | printk(KERN_INFO |
568 | me->comm,me->pid,where,frame,regs->ip,regs->sp,regs->orig_ax); | 508 | "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx", |
509 | me->comm, me->pid, where, frame, | ||
510 | regs->ip, regs->sp, regs->orig_ax); | ||
569 | print_vma_addr(" in ", regs->ip); | 511 | print_vma_addr(" in ", regs->ip); |
570 | printk("\n"); | 512 | printk(KERN_CONT "\n"); |
571 | } | 513 | } |
572 | 514 | ||
573 | force_sig(SIGSEGV, me); | 515 | force_sig(SIGSEGV, me); |
574 | } | 516 | } |