History

Merge branches 'core/signal' and 'x86/spinlocks' into x86/xen

Ingo Molnar committed 18 years ago

Commit eceb1383 parents 365d46d 84e9c95 4c7145a16 files · +339 −274Browse files

Unified · Split

16 files
  1. arch/ia64/include/asm/siginfo.h +0 −5
  2. arch/powerpc/include/asm/siginfo.h +0 −5
  3. arch/x86/ia32/ia32_signal.c +27 −41
  4. arch/x86/kernel/process_64.c +2 −2
  5. arch/x86/kernel/ptrace.c +4 −3
  6. arch/x86/kernel/signal_32.c +134 −88
  7. arch/x86/kernel/signal_64.c +124 −83
  8. arch/x86/kernel/traps_32.c +3 −1
  9. arch/x86/kernel/traps_64.c +1 −1
  10. arch/x86/kernel/vmlinux_64.lds.S +1 −1
  11. arch/x86/mm/ioremap.c +1 −1
  12. include/asm-generic/siginfo.h +2 −0
  13. include/asm-parisc/siginfo.h +0 −5
  14. include/asm-x86/ptrace.h +3 −3
  15. include/asm-x86/spinlock.h +25 −35
  16. include/asm-x86/traps.h +12 −0
arch/ia64/include/asm/siginfo.h+0−5
@@ -113,11 +113,6 @@ typedef struct siginfo { · 112 unmodified lines
113#undef NSIGSEGV113#undef NSIGSEGV
114#define NSIGSEGV 3114#define NSIGSEGV 3
115 115
116/*
117 * SIGTRAP si_codes
118 */
119#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
120#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
121#undef NSIGTRAP116#undef NSIGTRAP
122#define NSIGTRAP 4117#define NSIGTRAP 4
123 118
arch/powerpc/include/asm/siginfo.h+0−5
@@ -15,11 +15,6 @@ · 14 unmodified lines
15 15
16#include <asm-generic/siginfo.h>16#include <asm-generic/siginfo.h>
17 17
18/*
19 * SIGTRAP si_codes
20 */
21#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
22#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
23#undef NSIGTRAP18#undef NSIGTRAP
24#define NSIGTRAP 419#define NSIGTRAP 4
25 20
arch/x86/ia32/ia32_signal.c+27−41
@@ -351,31 +351,28 @@ static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, · 350 unmodified lines
351 savesegment(es, tmp);351 savesegment(es, tmp);
352 err |= __put_user(tmp, (unsigned int __user *)&sc->es);352 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
353 353
354 err |= __put_user((u32)regs->di, &sc->di);354 err |= __put_user(regs->di, &sc->di);
355 err |= __put_user((u32)regs->si, &sc->si);355 err |= __put_user(regs->si, &sc->si);
356 err |= __put_user((u32)regs->bp, &sc->bp);356 err |= __put_user(regs->bp, &sc->bp);
357 err |= __put_user((u32)regs->sp, &sc->sp);357 err |= __put_user(regs->sp, &sc->sp);
358 err |= __put_user((u32)regs->bx, &sc->bx);358 err |= __put_user(regs->bx, &sc->bx);
359 err |= __put_user((u32)regs->dx, &sc->dx);359 err |= __put_user(regs->dx, &sc->dx);
360 err |= __put_user((u32)regs->cx, &sc->cx);360 err |= __put_user(regs->cx, &sc->cx);
361 err |= __put_user((u32)regs->ax, &sc->ax);361 err |= __put_user(regs->ax, &sc->ax);
362 err |= __put_user((u32)regs->cs, &sc->cs);362 err |= __put_user(regs->cs, &sc->cs);
363 err |= __put_user((u32)regs->ss, &sc->ss);363 err |= __put_user(regs->ss, &sc->ss);
364 err |= __put_user(current->thread.trap_no, &sc->trapno);364 err |= __put_user(current->thread.trap_no, &sc->trapno);
365 err |= __put_user(current->thread.error_code, &sc->err);365 err |= __put_user(current->thread.error_code, &sc->err);
366 err |= __put_user((u32)regs->ip, &sc->ip);366 err |= __put_user(regs->ip, &sc->ip);
367 err |= __put_user((u32)regs->flags, &sc->flags);367 err |= __put_user(regs->flags, &sc->flags);
368 err |= __put_user((u32)regs->sp, &sc->sp_at_signal);368 err |= __put_user(regs->sp, &sc->sp_at_signal);
369 369
370 tmp = save_i387_xstate_ia32(fpstate);370 tmp = save_i387_xstate_ia32(fpstate);
371 if (tmp < 0)371 if (tmp < 0)
372 err = -EFAULT;372 err = -EFAULT;
373 else {373 else
374 clear_used_math();
375 stts();
376 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),374 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
377 &sc->fpstate);375 &sc->fpstate);
378 }
379 376
380 /* non-iBCS2 extensions.. */377 /* non-iBCS2 extensions.. */
381 err |= __put_user(mask, &sc->oldmask);378 err |= __put_user(mask, &sc->oldmask);
@@ -444,21 +441,18 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 62 unmodified lines
444 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);441 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
445 442
446 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))443 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
447 goto give_sigsegv;444 return -EFAULT;
448 445
449 err |= __put_user(sig, &frame->sig);446 if (__put_user(sig, &frame->sig))
450 if (err)447 return -EFAULT;
451 goto give_sigsegv;
452 448
453 err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);449 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
454 if (err)450 return -EFAULT;
455 goto give_sigsegv;
456 451
457 if (_COMPAT_NSIG_WORDS > 1) {452 if (_COMPAT_NSIG_WORDS > 1) {
458 err |= __copy_to_user(frame->extramask, &set->sig[1],453 if (__copy_to_user(frame->extramask, &set->sig[1],
459 sizeof(frame->extramask));454 sizeof(frame->extramask)))
460 if (err)455 return -EFAULT;
461 goto give_sigsegv;
462 }456 }
463 457
464 if (ka->sa.sa_flags & SA_RESTORER) {458 if (ka->sa.sa_flags & SA_RESTORER) {
@@ -479,7 +473,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 14 unmodified lines
479 */473 */
480 err |= __copy_to_user(frame->retcode, &code, 8);474 err |= __copy_to_user(frame->retcode, &code, 8);
481 if (err)475 if (err)
482 goto give_sigsegv;476 return -EFAULT;
483 477
484 /* Set up registers for signal handler */478 /* Set up registers for signal handler */
485 regs->sp = (unsigned long) frame;479 regs->sp = (unsigned long) frame;
@@ -502,10 +496,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 16 unmodified lines
502#endif496#endif
503 497
504 return 0;498 return 0;
505
506give_sigsegv:
507 force_sigsegv(sig, current);
508 return -EFAULT;
509}499}
510 500
511int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,501int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
@@ -533,14 +523,14 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 21 unmodified lines
533 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);523 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
534 524
535 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))525 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
536 goto give_sigsegv;526 return -EFAULT;
537 527
538 err |= __put_user(sig, &frame->sig);528 err |= __put_user(sig, &frame->sig);
539 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);529 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
540 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);530 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
541 err |= copy_siginfo_to_user32(&frame->info, info);531 err |= copy_siginfo_to_user32(&frame->info, info);
542 if (err)532 if (err)
543 goto give_sigsegv;533 return -EFAULT;
544 534
545 /* Create the ucontext. */535 /* Create the ucontext. */
546 if (cpu_has_xsave)536 if (cpu_has_xsave)
@@ -556,7 +546,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 9 unmodified lines
556 regs, set->sig[0]);546 regs, set->sig[0]);
557 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));547 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
558 if (err)548 if (err)
559 goto give_sigsegv;549 return -EFAULT;
560 550
561 if (ka->sa.sa_flags & SA_RESTORER)551 if (ka->sa.sa_flags & SA_RESTORER)
562 restorer = ka->sa.sa_restorer;552 restorer = ka->sa.sa_restorer;
@@ -571,7 +561,7 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 8 unmodified lines
571 */561 */
572 err |= __copy_to_user(frame->retcode, &code, 8);562 err |= __copy_to_user(frame->retcode, &code, 8);
573 if (err)563 if (err)
574 goto give_sigsegv;564 return -EFAULT;
575 565
576 /* Set up registers for signal handler */566 /* Set up registers for signal handler */
577 regs->sp = (unsigned long) frame;567 regs->sp = (unsigned long) frame;
@@ -599,8 +589,4 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 21 unmodified lines
599#endif589#endif
600 590
601 return 0;591 return 0;
602
603give_sigsegv:
604 force_sigsegv(sig, current);
605 return -EFAULT;
606}592}
arch/x86/kernel/process_64.c+2−2
@@ -736,12 +736,12 @@ unsigned long get_wchan(struct task_struct *p) · 735 unmodified lines
736 if (!p || p == current || p->state == TASK_RUNNING)736 if (!p || p == current || p->state == TASK_RUNNING)
737 return 0;737 return 0;
738 stack = (unsigned long)task_stack_page(p);738 stack = (unsigned long)task_stack_page(p);
739 if (p->thread.sp < stack || p->thread.sp > stack+THREAD_SIZE)739 if (p->thread.sp < stack || p->thread.sp >= stack+THREAD_SIZE)
740 return 0;740 return 0;
741 fp = *(u64 *)(p->thread.sp);741 fp = *(u64 *)(p->thread.sp);
742 do {742 do {
743 if (fp < (unsigned long)stack ||743 if (fp < (unsigned long)stack ||
744 fp > (unsigned long)stack+THREAD_SIZE)744 fp >= (unsigned long)stack+THREAD_SIZE)
745 return 0;745 return 0;
746 ip = *(u64 *)(fp+8);746 ip = *(u64 *)(fp+8);
747 if (!in_sched_functions(ip))747 if (!in_sched_functions(ip))
arch/x86/kernel/ptrace.c+4−3
@@ -1452,7 +1452,8 @@ const struct user_regset_view *task_user_regset_view(struct task_struct *task) · 1451 unmodified lines
1452#endif1452#endif
1453}1453}
1454 1454
1455void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)1455void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
1456 int error_code, int si_code)
1456{1457{
1457 struct siginfo info;1458 struct siginfo info;
1458 1459
@@ -1461,7 +1462,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) · 2 unmodified lines
1461 1462
1462 memset(&info, 0, sizeof(info));1463 memset(&info, 0, sizeof(info));
1463 info.si_signo = SIGTRAP;1464 info.si_signo = SIGTRAP;
1464 info.si_code = TRAP_BRKPT;1465 info.si_code = si_code;
1465 1466
1466 /* User-mode ip? */1467 /* User-mode ip? */
1467 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;1468 info.si_addr = user_mode_vm(regs) ? (void __user *) regs->ip : NULL;
@@ -1548,5 +1549,5 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs) · 80 unmodified lines
1548 */1549 */
1549 if (test_thread_flag(TIF_SINGLESTEP) &&1550 if (test_thread_flag(TIF_SINGLESTEP) &&
1550 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))1551 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
1551 send_sigtrap(current, regs, 0);1552 send_sigtrap(current, regs, 0, TRAP_BRKPT);
1552}1553}
arch/x86/kernel/signal_32.c+134−88
@@ -27,6 +27,7 @@ · 26 unmodified lines
27#include <asm/uaccess.h>27#include <asm/uaccess.h>
28#include <asm/i387.h>28#include <asm/i387.h>
29#include <asm/vdso.h>29#include <asm/vdso.h>
30#include <asm/syscall.h>
30#include <asm/syscalls.h>31#include <asm/syscalls.h>
31 32
32#include "sigframe.h"33#include "sigframe.h"
@@ -112,6 +113,27 @@ asmlinkage int sys_sigaltstack(unsigned long bx) · 79 unmodified lines
112 return do_sigaltstack(uss, uoss, regs->sp);113 return do_sigaltstack(uss, uoss, regs->sp);
113}114}
114 115
116#define COPY(x) { \
117 err |= __get_user(regs->x, &sc->x); \
118}
119
120#define COPY_SEG(seg) { \
121 unsigned short tmp; \
122 err |= __get_user(tmp, &sc->seg); \
123 regs->seg = tmp; \
124}
125
126#define COPY_SEG_STRICT(seg) { \
127 unsigned short tmp; \
128 err |= __get_user(tmp, &sc->seg); \
129 regs->seg = tmp | 3; \
130}
131
132#define GET_SEG(seg) { \
133 unsigned short tmp; \
134 err |= __get_user(tmp, &sc->seg); \
135 loadsegment(seg, tmp); \
136}
115 137
116/*138/*
117 * Do a signal return; undo the signal stack.139 * Do a signal return; undo the signal stack.
@@ -120,28 +142,13 @@ static int · 2 unmodified lines
120restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,142restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
121 unsigned long *pax)143 unsigned long *pax)
122{144{
145 void __user *buf;
146 unsigned int tmpflags;
123 unsigned int err = 0;147 unsigned int err = 0;
124 148
125 /* Always make any pending restarted system calls return -EINTR */149 /* Always make any pending restarted system calls return -EINTR */
126 current_thread_info()->restart_block.fn = do_no_restart_syscall;150 current_thread_info()->restart_block.fn = do_no_restart_syscall;
127 151
128#define COPY(x) err |= __get_user(regs->x, &sc->x)
129
130#define COPY_SEG(seg) \
131 { unsigned short tmp; \
132 err |= __get_user(tmp, &sc->seg); \
133 regs->seg = tmp; }
134
135#define COPY_SEG_STRICT(seg) \
136 { unsigned short tmp; \
137 err |= __get_user(tmp, &sc->seg); \
138 regs->seg = tmp|3; }
139
140#define GET_SEG(seg) \
141 { unsigned short tmp; \
142 err |= __get_user(tmp, &sc->seg); \
143 loadsegment(seg, tmp); }
144
145 GET_SEG(gs);152 GET_SEG(gs);
146 COPY_SEG(fs);153 COPY_SEG(fs);
147 COPY_SEG(es);154 COPY_SEG(es);
@@ -151,21 +158,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, · 3 unmodified lines
151 COPY_SEG_STRICT(cs);158 COPY_SEG_STRICT(cs);
152 COPY_SEG_STRICT(ss);159 COPY_SEG_STRICT(ss);
153 160
154 {161 err |= __get_user(tmpflags, &sc->flags);
155 unsigned int tmpflags;162 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
156 163 regs->orig_ax = -1; /* disable syscall checks */
157 err |= __get_user(tmpflags, &sc->flags);
158 regs->flags = (regs->flags & ~FIX_EFLAGS) |
159 (tmpflags & FIX_EFLAGS);
160 regs->orig_ax = -1; /* disable syscall checks */
161 }
162
163 {
164 void __user *buf;
165 164
166 err |= __get_user(buf, &sc->fpstate);165 err |= __get_user(buf, &sc->fpstate);
167 err |= restore_i387_xstate(buf);166 err |= restore_i387_xstate(buf);
168 }
169 167
170 err |= __get_user(*pax, &sc->ax);168 err |= __get_user(*pax, &sc->ax);
171 return err;169 return err;
@@ -214,9 +212,8 @@ badframe: · 42 unmodified lines
214 return 0;212 return 0;
215}213}
216 214
217asmlinkage int sys_rt_sigreturn(unsigned long __unused)215static long do_rt_sigreturn(struct pt_regs *regs)
218{216{
219 struct pt_regs *regs = (struct pt_regs *)&__unused;
220 struct rt_sigframe __user *frame;217 struct rt_sigframe __user *frame;
221 unsigned long ax;218 unsigned long ax;
222 sigset_t set;219 sigset_t set;
@@ -242,10 +239,17 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused) · 19 unmodified lines
242 return ax;239 return ax;
243 240
244badframe:241badframe:
245 force_sig(SIGSEGV, current);242 signal_fault(regs, frame, "rt_sigreturn");
246 return 0;243 return 0;
247}244}
248 245
246asmlinkage int sys_rt_sigreturn(unsigned long __unused)
247{
248 struct pt_regs *regs = (struct pt_regs *)&__unused;
249
250 return do_rt_sigreturn(regs);
251}
252
249/*253/*
250 * Set up a signal frame.254 * Set up a signal frame.
251 */255 */
@@ -337,39 +341,29 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 85 unmodified lines
337}341}
338 342
339static int343static int
340setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,344__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
341 struct pt_regs *regs)345 struct pt_regs *regs)
342{346{
343 struct sigframe __user *frame;347 struct sigframe __user *frame;
344 void __user *restorer;348 void __user *restorer;
345 int err = 0;349 int err = 0;
346 int usig;
347 void __user *fpstate = NULL;350 void __user *fpstate = NULL;
348 351
349 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);352 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
350 353
351 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))354 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
352 goto give_sigsegv;355 return -EFAULT;
353 356
354 usig = current_thread_info()->exec_domain357 if (__put_user(sig, &frame->sig))
355 && current_thread_info()->exec_domain->signal_invmap358 return -EFAULT;
356 && sig < 32
357 ? current_thread_info()->exec_domain->signal_invmap[sig]
358 : sig;
359 359
360 err = __put_user(usig, &frame->sig);360 if (setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
361 if (err)361 return -EFAULT;
362 goto give_sigsegv;
363
364 err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
365 if (err)
366 goto give_sigsegv;
367 362
368 if (_NSIG_WORDS > 1) {363 if (_NSIG_WORDS > 1) {
369 err = __copy_to_user(&frame->extramask, &set->sig[1],364 if (__copy_to_user(&frame->extramask, &set->sig[1],
370 sizeof(frame->extramask));365 sizeof(frame->extramask)))
371 if (err)366 return -EFAULT;
372 goto give_sigsegv;
373 }367 }
374 368
375 if (current->mm->context.vdso)369 if (current->mm->context.vdso)
@@ -394,7 +388,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, · 18 unmodified lines
394 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));388 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
395 389
396 if (err)390 if (err)
397 goto give_sigsegv;391 return -EFAULT;
398 392
399 /* Set up registers for signal handler */393 /* Set up registers for signal handler */
400 regs->sp = (unsigned long)frame;394 regs->sp = (unsigned long)frame;
@@ -409,38 +403,27 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, · 8 unmodified lines
409 regs->cs = __USER_CS;403 regs->cs = __USER_CS;
410 404
411 return 0;405 return 0;
412
413give_sigsegv:
414 force_sigsegv(sig, current);
415 return -EFAULT;
416}406}
417 407
418static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,408static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
419 sigset_t *set, struct pt_regs *regs)409 sigset_t *set, struct pt_regs *regs)
420{410{
421 struct rt_sigframe __user *frame;411 struct rt_sigframe __user *frame;
422 void __user *restorer;412 void __user *restorer;
423 int err = 0;413 int err = 0;
424 int usig;
425 void __user *fpstate = NULL;414 void __user *fpstate = NULL;
426 415
427 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);416 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
428 417
429 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))418 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
430 goto give_sigsegv;419 return -EFAULT;
431
432 usig = current_thread_info()->exec_domain
433 && current_thread_info()->exec_domain->signal_invmap
434 && sig < 32
435 ? current_thread_info()->exec_domain->signal_invmap[sig]
436 : sig;
437 420
438 err |= __put_user(usig, &frame->sig);421 err |= __put_user(sig, &frame->sig);
439 err |= __put_user(&frame->info, &frame->pinfo);422 err |= __put_user(&frame->info, &frame->pinfo);
440 err |= __put_user(&frame->uc, &frame->puc);423 err |= __put_user(&frame->uc, &frame->puc);
441 err |= copy_siginfo_to_user(&frame->info, info);424 err |= copy_siginfo_to_user(&frame->info, info);
442 if (err)425 if (err)
443 goto give_sigsegv;426 return -EFAULT;
444 427
445 /* Create the ucontext. */428 /* Create the ucontext. */
446 if (cpu_has_xsave)429 if (cpu_has_xsave)
@@ -456,7 +439,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 9 unmodified lines
456 regs, set->sig[0]);439 regs, set->sig[0]);
457 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));440 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
458 if (err)441 if (err)
459 goto give_sigsegv;442 return -EFAULT;
460 443
461 /* Set up to return from userspace. */444 /* Set up to return from userspace. */
462 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);445 restorer = VDSO32_SYMBOL(current->mm->context.vdso, rt_sigreturn);
@@ -476,12 +459,12 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 13 unmodified lines
476 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));459 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
477 460
478 if (err)461 if (err)
479 goto give_sigsegv;462 return -EFAULT;
480 463
481 /* Set up registers for signal handler */464 /* Set up registers for signal handler */
482 regs->sp = (unsigned long)frame;465 regs->sp = (unsigned long)frame;
483 regs->ip = (unsigned long)ka->sa.sa_handler;466 regs->ip = (unsigned long)ka->sa.sa_handler;
484 regs->ax = (unsigned long)usig;467 regs->ax = (unsigned long)sig;
485 regs->dx = (unsigned long)&frame->info;468 regs->dx = (unsigned long)&frame->info;
486 regs->cx = (unsigned long)&frame->uc;469 regs->cx = (unsigned long)&frame->uc;
487 470
@@ -491,15 +474,48 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 3 unmodified lines
491 regs->cs = __USER_CS;474 regs->cs = __USER_CS;
492 475
493 return 0;476 return 0;
494
495give_sigsegv:
496 force_sigsegv(sig, current);
497 return -EFAULT;
498}477}
499 478
500/*479/*
501 * OK, we're invoking a handler:480 * OK, we're invoking a handler:
502 */481 */
482static int signr_convert(int sig)
483{
484 struct thread_info *info = current_thread_info();
485
486 if (info->exec_domain && info->exec_domain->signal_invmap && sig < 32)
487 return info->exec_domain->signal_invmap[sig];
488 return sig;
489}
490
491#define is_ia32 1
492#define ia32_setup_frame __setup_frame
493#define ia32_setup_rt_frame __setup_rt_frame
494
495static int
496setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
497 sigset_t *set, struct pt_regs *regs)
498{
499 int usig = signr_convert(sig);
500 int ret;
501
502 /* Set up the stack frame */
503 if (is_ia32) {
504 if (ka->sa.sa_flags & SA_SIGINFO)
505 ret = ia32_setup_rt_frame(usig, ka, info, set, regs);
506 else
507 ret = ia32_setup_frame(usig, ka, set, regs);
508 } else
509 ret = __setup_rt_frame(sig, ka, info, set, regs);
510
511 if (ret) {
512 force_sigsegv(sig, current);
513 return -EFAULT;
514 }
515
516 return ret;
517}
518
503static int519static int
504handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,520handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
505 sigset_t *oldset, struct pt_regs *regs)521 sigset_t *oldset, struct pt_regs *regs)
@@ -507,9 +523,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 1 unmodified line
507 int ret;523 int ret;
508 524
509 /* Are we from a system call? */525 /* Are we from a system call? */
510 if ((long)regs->orig_ax >= 0) {526 if (syscall_get_nr(current, regs) >= 0) {
511 /* If so, check system call restarting.. */527 /* If so, check system call restarting.. */
512 switch (regs->ax) {528 switch (syscall_get_error(current, regs)) {
513 case -ERESTART_RESTARTBLOCK:529 case -ERESTART_RESTARTBLOCK:
514 case -ERESTARTNOHAND:530 case -ERESTARTNOHAND:
515 regs->ax = -EINTR;531 regs->ax = -EINTR;
@@ -536,15 +552,20 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 20 unmodified lines
536 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))552 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
537 regs->flags &= ~X86_EFLAGS_TF;553 regs->flags &= ~X86_EFLAGS_TF;
538 554
539 /* Set up the stack frame */555 ret = setup_rt_frame(sig, ka, info, oldset, regs);
540 if (ka->sa.sa_flags & SA_SIGINFO)
541 ret = setup_rt_frame(sig, ka, info, oldset, regs);
542 else
543 ret = setup_frame(sig, ka, oldset, regs);
544 556
545 if (ret)557 if (ret)
546 return ret;558 return ret;
547 559
560#ifdef CONFIG_X86_64
561 /*
562 * This has nothing to do with segment registers,
563 * despite the name. This magic affects uaccess.h
564 * macros' behavior. Reset it to the normal setting.
565 */
566 set_fs(USER_DS);
567#endif
568
548 /*569 /*
549 * Clear the direction flag as per the ABI for function entry.570 * Clear the direction flag as per the ABI for function entry.
550 */571 */
@@ -571,6 +592,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 20 unmodified lines
571 return 0;592 return 0;
572}593}
573 594
595#define NR_restart_syscall __NR_restart_syscall
574/*596/*
575 * Note that 'init' is a special process: it doesn't get signals it doesn't597 * Note that 'init' is a special process: it doesn't get signals it doesn't
576 * want to handle. Thus you cannot kill init even with a SIGKILL even by598 * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -623,9 +645,9 @@ static void do_signal(struct pt_regs *regs) · 46 unmodified lines
623 }645 }
624 646
625 /* Did we come from a system call? */647 /* Did we come from a system call? */
626 if ((long)regs->orig_ax >= 0) {648 if (syscall_get_nr(current, regs) >= 0) {
627 /* Restart the system call - no handlers present */649 /* Restart the system call - no handlers present */
628 switch (regs->ax) {650 switch (syscall_get_error(current, regs)) {
629 case -ERESTARTNOHAND:651 case -ERESTARTNOHAND:
630 case -ERESTARTSYS:652 case -ERESTARTSYS:
631 case -ERESTARTNOINTR:653 case -ERESTARTNOINTR:
@@ -634,7 +656,7 @@ static void do_signal(struct pt_regs *regs) · 2 unmodified lines
634 break;656 break;
635 657
636 case -ERESTART_RESTARTBLOCK:658 case -ERESTART_RESTARTBLOCK:
637 regs->ax = __NR_restart_syscall;659 regs->ax = NR_restart_syscall;
638 regs->ip -= 2;660 regs->ip -= 2;
639 break;661 break;
640 }662 }
@@ -657,6 +679,12 @@ static void do_signal(struct pt_regs *regs) · 16 unmodified lines
657void679void
658do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)680do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
659{681{
682#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
683 /* notify userspace of pending MCEs */
684 if (thread_info_flags & _TIF_MCE_NOTIFY)
685 mce_notify_user();
686#endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
687
660 /* deal with pending signal delivery */688 /* deal with pending signal delivery */
661 if (thread_info_flags & _TIF_SIGPENDING)689 if (thread_info_flags & _TIF_SIGPENDING)
662 do_signal(regs);690 do_signal(regs);
@@ -666,5 +694,23 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) · 3 unmodified lines
666 tracehook_notify_resume(regs);694 tracehook_notify_resume(regs);
667 }695 }
668 696
697#ifdef CONFIG_X86_32
669 clear_thread_flag(TIF_IRET);698 clear_thread_flag(TIF_IRET);
699#endif /* CONFIG_X86_32 */
700}
701
702void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
703{
704 struct task_struct *me = current;
705
706 if (show_unhandled_signals && printk_ratelimit()) {
707 printk(KERN_INFO
708 "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
709 me->comm, me->pid, where, frame,
710 regs->ip, regs->sp, regs->orig_ax);
711 print_vma_addr(" in ", regs->ip);
712 printk(KERN_CONT "\n");
713 }
714
715 force_sig(SIGSEGV, me);
670}716}
arch/x86/kernel/signal_64.c+124−83
@@ -52,6 +52,16 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, · 51 unmodified lines
52 return do_sigaltstack(uss, uoss, regs->sp);52 return do_sigaltstack(uss, uoss, regs->sp);
53}53}
54 54
55#define COPY(x) { \
56 err |= __get_user(regs->x, &sc->x); \
57}
58
59#define COPY_SEG_STRICT(seg) { \
60 unsigned short tmp; \
61 err |= __get_user(tmp, &sc->seg); \
62 regs->seg = tmp | 3; \
63}
64
55/*65/*
56 * Do a signal return; undo the signal stack.66 * Do a signal return; undo the signal stack.
57 */67 */
@@ -59,13 +69,13 @@ static int · 1 unmodified line
59restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,69restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
60 unsigned long *pax)70 unsigned long *pax)
61{71{
72 void __user *buf;
73 unsigned int tmpflags;
62 unsigned int err = 0;74 unsigned int err = 0;
63 75
64 /* Always make any pending restarted system calls return -EINTR */76 /* Always make any pending restarted system calls return -EINTR */
65 current_thread_info()->restart_block.fn = do_no_restart_syscall;77 current_thread_info()->restart_block.fn = do_no_restart_syscall;
66 78
67#define COPY(x) (err |= __get_user(regs->x, &sc->x))
68
69 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);79 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
70 COPY(dx); COPY(cx); COPY(ip);80 COPY(dx); COPY(cx); COPY(ip);
71 COPY(r8);81 COPY(r8);
@@ -80,34 +90,24 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, · 8 unmodified lines
80 /* Kernel saves and restores only the CS segment register on signals,90 /* Kernel saves and restores only the CS segment register on signals,
81 * 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.
82 * App's signal handler can save/restore other segments if needed. */92 * App's signal handler can save/restore other segments if needed. */
83 {93 COPY_SEG_STRICT(cs);
84 unsigned cs;
85 err |= __get_user(cs, &sc->cs);
86 regs->cs = cs | 3; /* Force into user mode */
87 }
88 94
89 {95 err |= __get_user(tmpflags, &sc->flags);
90 unsigned int tmpflags;96 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
91 err |= __get_user(tmpflags, &sc->flags);97 regs->orig_ax = -1; /* disable syscall checks */
92 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
93 regs->orig_ax = -1; /* disable syscall checks */
94 }
95 98
96 {99 err |= __get_user(buf, &sc->fpstate);
97 struct _fpstate __user *buf;100 err |= restore_i387_xstate(buf);
98 err |= __get_user(buf, &sc->fpstate);
99 err |= restore_i387_xstate(buf);
100 }
101 101
102 err |= __get_user(*pax, &sc->ax);102 err |= __get_user(*pax, &sc->ax);
103 return err;103 return err;
104}104}
105 105
106asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)106static long do_rt_sigreturn(struct pt_regs *regs)
107{107{
108 struct rt_sigframe __user *frame;108 struct rt_sigframe __user *frame;
109 sigset_t set;
110 unsigned long ax;109 unsigned long ax;
110 sigset_t set;
111 111
112 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));112 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
113 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))113 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -130,10 +130,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) · 16 unmodified lines
130 return ax;130 return ax;
131 131
132badframe:132badframe:
133 signal_fault(regs, frame, "sigreturn");133 signal_fault(regs, frame, "rt_sigreturn");
134 return 0;134 return 0;
135}135}
136 136
137asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
138{
139 return do_rt_sigreturn(regs);
140}
141
137/*142/*
138 * Set up a signal frame.143 * Set up a signal frame.
139 */144 */
@@ -195,8 +200,8 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) · 55 unmodified lines
195 return (void __user *)round_down(sp - size, 64);200 return (void __user *)round_down(sp - size, 64);
196}201}
197 202
198static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,203static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
199 sigset_t *set, struct pt_regs *regs)204 sigset_t *set, struct pt_regs *regs)
200{205{
201 struct rt_sigframe __user *frame;206 struct rt_sigframe __user *frame;
202 void __user *fp = NULL;207 void __user *fp = NULL;
@@ -209,17 +214,16 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 6 unmodified lines
209 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;214 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
210 215
211 if (save_i387_xstate(fp) < 0)216 if (save_i387_xstate(fp) < 0)
212 err |= -1;217 return -EFAULT;
213 } else218 } else
214 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;219 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
215 220
216 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))221 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
217 goto give_sigsegv;222 return -EFAULT;
218 223
219 if (ka->sa.sa_flags & SA_SIGINFO) {224 if (ka->sa.sa_flags & SA_SIGINFO) {
220 err |= copy_siginfo_to_user(&frame->info, info);225 if (copy_siginfo_to_user(&frame->info, info))
221 if (err)226 return -EFAULT;
222 goto give_sigsegv;
223 }227 }
224 228
225 /* Create the ucontext. */229 /* Create the ucontext. */
@@ -247,11 +251,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 21 unmodified lines
247 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);251 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
248 } else {252 } else {
249 /* could use a vstub here */253 /* could use a vstub here */
250 goto give_sigsegv;254 return -EFAULT;
251 }255 }
252 256
253 if (err)257 if (err)
254 goto give_sigsegv;258 return -EFAULT;
255 259
256 /* Set up registers for signal handler */260 /* Set up registers for signal handler */
257 regs->di = sig;261 regs->di = sig;
@@ -271,15 +275,45 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 13 unmodified lines
271 regs->cs = __USER_CS;275 regs->cs = __USER_CS;
272 276
273 return 0;277 return 0;
274
275give_sigsegv:
276 force_sigsegv(sig, current);
277 return -EFAULT;
278}278}
279 279
280/*280/*
281 * OK, we're invoking a handler281 * OK, we're invoking a handler
282 */282 */
283static int signr_convert(int sig)
284{
285 return sig;
286}
287
288#ifdef CONFIG_IA32_EMULATION
289#define is_ia32 test_thread_flag(TIF_IA32)
290#else
291#define is_ia32 0
292#endif
293
294static int
295setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
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}
283 317
284static int318static int
285handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,319handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
@@ -317,51 +351,48 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 31 unmodified lines
317 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))351 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
318 regs->flags &= ~X86_EFLAGS_TF;352 regs->flags &= ~X86_EFLAGS_TF;
319 353
320#ifdef CONFIG_IA32_EMULATION
321 if (test_thread_flag(TIF_IA32)) {
322 if (ka->sa.sa_flags & SA_SIGINFO)
323 ret = ia32_setup_rt_frame(sig, ka, info, oldset, regs);
324 else
325 ret = ia32_setup_frame(sig, ka, oldset, regs);
326 } else
327#endif
328 ret = setup_rt_frame(sig, ka, info, oldset, regs);354 ret = setup_rt_frame(sig, ka, info, oldset, regs);
329 355
330 if (ret == 0) {356 if (ret)
331 /*357 return ret;
332 * This has nothing to do with segment registers,
333 * despite the name. This magic affects uaccess.h
334 * macros' behavior. Reset it to the normal setting.
335 */
336 set_fs(USER_DS);
337 358
338 /*359#ifdef CONFIG_X86_64
339 * Clear the direction flag as per the ABI for function entry.360 /*
340 */361 * This has nothing to do with segment registers,
341 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
342 367
343 /*368 /*
344 * Clear TF when entering the signal handler, but369 * Clear the direction flag as per the ABI for function entry.
345 * notify any tracer that was single-stepping it.370 */
346 * The tracer may want to single-step inside the371 regs->flags &= ~X86_EFLAGS_DF;
347 * handler too.
348 */
349 regs->flags &= ~X86_EFLAGS_TF;
350 372
351 spin_lock_irq(&current->sighand->siglock);373 /*
352 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);374 * Clear TF when entering the signal handler, but
353 if (!(ka->sa.sa_flags & SA_NODEFER))375 * notify any tracer that was single-stepping it.
354 sigaddset(&current->blocked, sig);376 * The tracer may want to single-step inside the
355 recalc_sigpending();377 * handler too.
356 spin_unlock_irq(&current->sighand->siglock);378 */
379 regs->flags &= ~X86_EFLAGS_TF;
357 380
358 tracehook_signal_handler(sig, info, ka, regs,381 spin_lock_irq(&current->sighand->siglock);
359 test_thread_flag(TIF_SINGLESTEP));382 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
360 }383 if (!(ka->sa.sa_flags & SA_NODEFER))
384 sigaddset(&current->blocked, sig);
385 recalc_sigpending();
386 spin_unlock_irq(&current->sighand->siglock);
361 387
362 return ret;388 tracehook_signal_handler(sig, info, ka, regs,
389 test_thread_flag(TIF_SINGLESTEP));
390
391 return 0;
363}392}
364 393
394#define NR_restart_syscall \
395 test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
365/*396/*
366 * Note that 'init' is a special process: it doesn't get signals it doesn't397 * Note that 'init' is a special process: it doesn't get signals it doesn't
367 * want to handle. Thus you cannot kill init even with a SIGKILL even by398 * want to handle. Thus you cannot kill init even with a SIGKILL even by
@@ -391,7 +422,8 @@ static void do_signal(struct pt_regs *regs) · 23 unmodified lines
391 422
392 signr = get_signal_to_deliver(&info, &ka, regs, NULL);423 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
393 if (signr > 0) {424 if (signr > 0) {
394 /* Re-enable any watchpoints before delivering the425 /*
426 * Re-enable any watchpoints before delivering the
395 * signal to user space. The processor register will427 * signal to user space. The processor register will
396 * have been cleared if the watchpoint triggered428 * have been cleared if the watchpoint triggered
397 * inside the kernel.429 * inside the kernel.
@@ -399,7 +431,7 @@ static void do_signal(struct pt_regs *regs) · 1 unmodified line
399 if (current->thread.debugreg7)431 if (current->thread.debugreg7)
400 set_debugreg(current->thread.debugreg7, 7);432 set_debugreg(current->thread.debugreg7, 7);
401 433
402 /* Whee! Actually deliver the signal. */434 /* Whee! Actually deliver the signal. */
403 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {435 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
404 /*436 /*
405 * A signal was successfully delivered; the saved437 * A signal was successfully delivered; the saved
@@ -422,10 +454,9 @@ static void do_signal(struct pt_regs *regs) · 16 unmodified lines
422 regs->ax = regs->orig_ax;454 regs->ax = regs->orig_ax;
423 regs->ip -= 2;455 regs->ip -= 2;
424 break;456 break;
457
425 case -ERESTART_RESTARTBLOCK:458 case -ERESTART_RESTARTBLOCK:
426 regs->ax = test_thread_flag(TIF_IA32) ?459 regs->ax = NR_restart_syscall;
427 __NR_ia32_restart_syscall :
428 __NR_restart_syscall;
429 regs->ip -= 2;460 regs->ip -= 2;
430 break;461 break;
431 }462 }
@@ -441,14 +472,18 @@ static void do_signal(struct pt_regs *regs) · 9 unmodified lines
441 }472 }
442}473}
443 474
444void do_notify_resume(struct pt_regs *regs, void *unused,475/*
445 __u32 thread_info_flags)476 * notification of userspace execution resumption
477 * - triggered by the TIF_WORK_MASK flags
478 */
479void
480do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
446{481{
447#ifdef CONFIG_X86_MCE482#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
448 /* notify userspace of pending MCEs */483 /* notify userspace of pending MCEs */
449 if (thread_info_flags & _TIF_MCE_NOTIFY)484 if (thread_info_flags & _TIF_MCE_NOTIFY)
450 mce_notify_user();485 mce_notify_user();
451#endif /* CONFIG_X86_MCE */486#endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
452 487
453 /* deal with pending signal delivery */488 /* deal with pending signal delivery */
454 if (thread_info_flags & _TIF_SIGPENDING)489 if (thread_info_flags & _TIF_SIGPENDING)
@@ -458,17 +493,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused, · 3 unmodified lines
458 clear_thread_flag(TIF_NOTIFY_RESUME);493 clear_thread_flag(TIF_NOTIFY_RESUME);
459 tracehook_notify_resume(regs);494 tracehook_notify_resume(regs);
460 }495 }
496
497#ifdef CONFIG_X86_32
498 clear_thread_flag(TIF_IRET);
499#endif /* CONFIG_X86_32 */
461}500}
462 501
463void signal_fault(struct pt_regs *regs, void __user *frame, char *where)502void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
464{503{
465 struct task_struct *me = current;504 struct task_struct *me = current;
505
466 if (show_unhandled_signals && printk_ratelimit()) {506 if (show_unhandled_signals && printk_ratelimit()) {
467 printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",507 printk(KERN_INFO
468 me->comm, me->pid, where, frame, regs->ip,508 "%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
469 regs->sp, regs->orig_ax);509 me->comm, me->pid, where, frame,
510 regs->ip, regs->sp, regs->orig_ax);
470 print_vma_addr(" in ", regs->ip);511 print_vma_addr(" in ", regs->ip);
471 printk("\n");512 printk(KERN_CONT "\n");
472 }513 }
473 514
474 force_sig(SIGSEGV, me);515 force_sig(SIGSEGV, me);
arch/x86/kernel/traps_32.c+3−1
@@ -891,6 +891,7 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code) · 890 unmodified lines
891{891{
892 struct task_struct *tsk = current;892 struct task_struct *tsk = current;
893 unsigned int condition;893 unsigned int condition;
894 int si_code;
894 895
895 trace_hardirqs_fixup();896 trace_hardirqs_fixup();
896 897
@@ -935,8 +936,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code) · 38 unmodified lines
935 goto clear_TF_reenable;936 goto clear_TF_reenable;
936 }937 }
937 938
939 si_code = get_si_code((unsigned long)condition);
938 /* Ok, finally something we can handle */940 /* Ok, finally something we can handle */
939 send_sigtrap(tsk, regs, error_code);941 send_sigtrap(tsk, regs, error_code, si_code);
940 942
941 /*943 /*
942 * Disable additional traps. They'll be re-enabled when944 * Disable additional traps. They'll be re-enabled when
arch/x86/kernel/traps_64.c+1−1
@@ -940,7 +940,7 @@ asmlinkage void __kprobes do_debug(struct pt_regs *regs, · 939 unmodified lines
940 tsk->thread.error_code = error_code;940 tsk->thread.error_code = error_code;
941 info.si_signo = SIGTRAP;941 info.si_signo = SIGTRAP;
942 info.si_errno = 0;942 info.si_errno = 0;
943 info.si_code = TRAP_BRKPT;943 info.si_code = get_si_code(condition);
944 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;944 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
945 force_sig_info(SIGTRAP, &info, tsk);945 force_sig_info(SIGTRAP, &info, tsk);
946 946
arch/x86/kernel/vmlinux_64.lds.S+1−1
@@ -172,8 +172,8 @@ SECTIONS · 171 unmodified lines
172 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {172 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
173 *(.x86_cpu_dev.init)173 *(.x86_cpu_dev.init)
174 }174 }
175 SECURITY_INIT
176 __x86_cpu_dev_end = .;175 __x86_cpu_dev_end = .;
176 SECURITY_INIT
177 177
178 . = ALIGN(8);178 . = ALIGN(8);
179 .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {179 .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) {
arch/x86/mm/ioremap.c+1−1
@@ -614,7 +614,7 @@ void __init *early_ioremap(unsigned long phys_addr, unsigned long size) · 613 unmodified lines
614 */614 */
615 offset = phys_addr & ~PAGE_MASK;615 offset = phys_addr & ~PAGE_MASK;
616 phys_addr &= PAGE_MASK;616 phys_addr &= PAGE_MASK;
617 size = PAGE_ALIGN(last_addr) - phys_addr;617 size = PAGE_ALIGN(last_addr + 1) - phys_addr;
618 618
619 /*619 /*
620 * Mappings have to fit in the FIX_BTMAP area.620 * Mappings have to fit in the FIX_BTMAP area.
include/asm-generic/siginfo.h+2−0
@@ -199,6 +199,8 @@ typedef struct siginfo { · 198 unmodified lines
199 */199 */
200#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */200#define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
201#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */201#define TRAP_TRACE (__SI_FAULT|2) /* process trace trap */
202#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
203#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint/watchpoint */
202#define NSIGTRAP 2204#define NSIGTRAP 2
203 205
204/*206/*
include/asm-parisc/siginfo.h+0−5
@@ -3,11 +3,6 @@ · 2 unmodified lines
3 3
4#include <asm-generic/siginfo.h>4#include <asm-generic/siginfo.h>
5 5
6/*
7 * SIGTRAP si_codes
8 */
9#define TRAP_BRANCH (__SI_FAULT|3) /* process taken branch trap */
10#define TRAP_HWBKPT (__SI_FAULT|4) /* hardware breakpoint or watchpoint */
11#undef NSIGTRAP6#undef NSIGTRAP
12#define NSIGTRAP 47#define NSIGTRAP 4
13 8
include/asm-x86/ptrace.h+3−3
@@ -177,11 +177,11 @@ convert_ip_to_linear(struct task_struct *child, struct pt_regs *regs); · 176 unmodified lines
177 177
178#ifdef CONFIG_X86_32178#ifdef CONFIG_X86_32
179extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,179extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
180 int error_code);180 int error_code, int si_code);
181#else
182void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
183#endif181#endif
184 182
183void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
184
185extern long syscall_trace_enter(struct pt_regs *);185extern long syscall_trace_enter(struct pt_regs *);
186extern void syscall_trace_leave(struct pt_regs *);186extern void syscall_trace_leave(struct pt_regs *);
187 187
include/asm-x86/spinlock.h+25−35
@@ -21,8 +21,10 @@ · 20 unmodified lines
21 21
22#ifdef CONFIG_X86_3222#ifdef CONFIG_X86_32
23# define LOCK_PTR_REG "a"23# define LOCK_PTR_REG "a"
24# define REG_PTR_MODE "k"
24#else25#else
25# define LOCK_PTR_REG "D"26# define LOCK_PTR_REG "D"
27# define REG_PTR_MODE "q"
26#endif28#endif
27 29
28#if defined(CONFIG_X86_32) && \30#if defined(CONFIG_X86_32) && \
@@ -54,19 +56,7 @@ · 25 unmodified lines
54 * much between them in performance though, especially as locks are out of line.56 * much between them in performance though, especially as locks are out of line.
55 */57 */
56#if (NR_CPUS < 256)58#if (NR_CPUS < 256)
57static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)59#define TICKET_SHIFT 8
58{
59 int tmp = ACCESS_ONCE(lock->slock);
60
61 return (((tmp >> 8) & 0xff) != (tmp & 0xff));
62}
63
64static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
65{
66 int tmp = ACCESS_ONCE(lock->slock);
67
68 return (((tmp >> 8) - tmp) & 0xff) > 1;
69}
70 60
71static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)61static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
72{62{
@@ -89,19 +79,17 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) · 16 unmodified lines
89 79
90static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)80static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
91{81{
92 int tmp;82 int tmp, new;
93 short new;
94 83
95 asm volatile("movw %2,%w0\n\t"84 asm volatile("movzwl %2, %0\n\t"
96 "cmpb %h0,%b0\n\t"85 "cmpb %h0,%b0\n\t"
86 "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"
97 "jne 1f\n\t"87 "jne 1f\n\t"
98 "movw %w0,%w1\n\t"
99 "incb %h1\n\t"
100 LOCK_PREFIX "cmpxchgw %w1,%2\n\t"88 LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
101 "1:"89 "1:"
102 "sete %b1\n\t"90 "sete %b1\n\t"
103 "movzbl %b1,%0\n\t"91 "movzbl %b1,%0\n\t"
104 : "=&a" (tmp), "=Q" (new), "+m" (lock->slock)92 : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
105 :93 :
106 : "memory", "cc");94 : "memory", "cc");
107 95
@@ -116,19 +104,7 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) · 8 unmodified lines
116 : "memory", "cc");104 : "memory", "cc");
117}105}
118#else106#else
119static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)107#define TICKET_SHIFT 16
120{
121 int tmp = ACCESS_ONCE(lock->slock);
122
123 return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
124}
125
126static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
127{
128 int tmp = ACCESS_ONCE(lock->slock);
129
130 return (((tmp >> 16) - tmp) & 0xffff) > 1;
131}
132 108
133static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)109static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
134{110{
@@ -146,7 +122,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) · 11 unmodified lines
146 /* don't need lfence here, because loads are in-order */122 /* don't need lfence here, because loads are in-order */
147 "jmp 1b\n"123 "jmp 1b\n"
148 "2:"124 "2:"
149 : "+Q" (inc), "+m" (lock->slock), "=r" (tmp)125 : "+r" (inc), "+m" (lock->slock), "=&r" (tmp)
150 :126 :
151 : "memory", "cc");127 : "memory", "cc");
152}128}
@@ -160,13 +136,13 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) · 7 unmodified lines
160 "movl %0,%1\n\t"136 "movl %0,%1\n\t"
161 "roll $16, %0\n\t"137 "roll $16, %0\n\t"
162 "cmpl %0,%1\n\t"138 "cmpl %0,%1\n\t"
139 "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
163 "jne 1f\n\t"140 "jne 1f\n\t"
164 "addl $0x00010000, %1\n\t"
165 LOCK_PREFIX "cmpxchgl %1,%2\n\t"141 LOCK_PREFIX "cmpxchgl %1,%2\n\t"
166 "1:"142 "1:"
167 "sete %b1\n\t"143 "sete %b1\n\t"
168 "movzbl %b1,%0\n\t"144 "movzbl %b1,%0\n\t"
169 : "=&a" (tmp), "=r" (new), "+m" (lock->slock)145 : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
170 :146 :
171 : "memory", "cc");147 : "memory", "cc");
172 148
@@ -182,6 +158,20 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) · 9 unmodified lines
182}158}
183#endif159#endif
184 160
161static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
162{
163 int tmp = ACCESS_ONCE(lock->slock);
164
165 return !!(((tmp >> TICKET_SHIFT) ^ tmp) & ((1 << TICKET_SHIFT) - 1));
166}
167
168static inline int __ticket_spin_is_contended(raw_spinlock_t *lock)
169{
170 int tmp = ACCESS_ONCE(lock->slock);
171
172 return (((tmp >> TICKET_SHIFT) - tmp) & ((1 << TICKET_SHIFT) - 1)) > 1;
173}
174
185#ifdef CONFIG_PARAVIRT175#ifdef CONFIG_PARAVIRT
186/*176/*
187 * Define virtualization-friendly old-style lock byte lock, for use in177 * Define virtualization-friendly old-style lock byte lock, for use in
include/asm-x86/traps.h+12−0
@@ -1,6 +1,8 @@
1#ifndef ASM_X86__TRAPS_H1#ifndef ASM_X86__TRAPS_H
2#define ASM_X86__TRAPS_H2#define ASM_X86__TRAPS_H
3 3
4#include <asm/debugreg.h>
5
4/* Common in X86_32 and X86_64 */6/* Common in X86_32 and X86_64 */
5asmlinkage void divide_error(void);7asmlinkage void divide_error(void);
6asmlinkage void debug(void);8asmlinkage void debug(void);
@@ -36,6 +38,16 @@ void do_invalid_op(struct pt_regs *, long); · 29 unmodified lines
36void do_general_protection(struct pt_regs *, long);38void do_general_protection(struct pt_regs *, long);
37void do_nmi(struct pt_regs *, long);39void do_nmi(struct pt_regs *, long);
38 40
41static inline int get_si_code(unsigned long condition)
42{
43 if (condition & DR_STEP)
44 return TRAP_TRACE;
45 else if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3))
46 return TRAP_HWBKPT;
47 else
48 return TRAP_BRKPT;
49}
50
39extern int panic_on_unrecovered_nmi;51extern int panic_on_unrecovered_nmi;
40extern int kstack_depth_to_print;52extern int kstack_depth_to_print;
41 53

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t