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
113113 #undef NSIGSEGV
114114 #define NSIGSEGV 3
115115
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 */
121116 #undef NSIGTRAP
122117 #define NSIGTRAP 4
123118
arch/powerpc/include/asm/siginfo.h+0−5
@@ -15,11 +15,6 @@ · 14 unmodified lines
1515
1616 #include <asm-generic/siginfo.h>
1717
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 */
2318 #undef NSIGTRAP
2419 #define NSIGTRAP 4
2520
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
351351 savesegment(es, tmp);
352352 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
353353
354− err |= __put_user((u32)regs->di, &sc->di);
355− err |= __put_user((u32)regs->si, &sc->si);
356− err |= __put_user((u32)regs->bp, &sc->bp);
357− err |= __put_user((u32)regs->sp, &sc->sp);
358− err |= __put_user((u32)regs->bx, &sc->bx);
359− err |= __put_user((u32)regs->dx, &sc->dx);
360− err |= __put_user((u32)regs->cx, &sc->cx);
361− err |= __put_user((u32)regs->ax, &sc->ax);
362− err |= __put_user((u32)regs->cs, &sc->cs);
363− err |= __put_user((u32)regs->ss, &sc->ss);
354+ err |= __put_user(regs->di, &sc->di);
355+ err |= __put_user(regs->si, &sc->si);
356+ err |= __put_user(regs->bp, &sc->bp);
357+ err |= __put_user(regs->sp, &sc->sp);
358+ err |= __put_user(regs->bx, &sc->bx);
359+ err |= __put_user(regs->dx, &sc->dx);
360+ err |= __put_user(regs->cx, &sc->cx);
361+ err |= __put_user(regs->ax, &sc->ax);
362+ err |= __put_user(regs->cs, &sc->cs);
363+ err |= __put_user(regs->ss, &sc->ss);
364364 err |= __put_user(current->thread.trap_no, &sc->trapno);
365365 err |= __put_user(current->thread.error_code, &sc->err);
366− err |= __put_user((u32)regs->ip, &sc->ip);
367− err |= __put_user((u32)regs->flags, &sc->flags);
368− err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
366+ err |= __put_user(regs->ip, &sc->ip);
367+ err |= __put_user(regs->flags, &sc->flags);
368+ err |= __put_user(regs->sp, &sc->sp_at_signal);
369369
370370 tmp = save_i387_xstate_ia32(fpstate);
371371 if (tmp < 0)
372372 err = -EFAULT;
373− else {
374− clear_used_math();
375− stts();
373+ else
376374 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
377375 &sc->fpstate);
378− }
379376
380377 /* non-iBCS2 extensions.. */
381378 err |= __put_user(mask, &sc->oldmask);
@@ -444,21 +441,18 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 62 unmodified lines
444441 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
445442
446443 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
447− goto give_sigsegv;
444+ return -EFAULT;
448445
449− err |= __put_user(sig, &frame->sig);
450− if (err)
451− goto give_sigsegv;
446+ if (__put_user(sig, &frame->sig))
447+ return -EFAULT;
452448
453− err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
454− if (err)
455− goto give_sigsegv;
449+ if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
450+ return -EFAULT;
456451
457452 if (_COMPAT_NSIG_WORDS > 1) {
458− err |= __copy_to_user(frame->extramask, &set->sig[1],
459− sizeof(frame->extramask));
460− if (err)
461− goto give_sigsegv;
453+ if (__copy_to_user(frame->extramask, &set->sig[1],
454+ sizeof(frame->extramask)))
455+ return -EFAULT;
462456 }
463457
464458 if (ka->sa.sa_flags & SA_RESTORER) {
@@ -479,7 +473,7 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 14 unmodified lines
479473 */
480474 err |= __copy_to_user(frame->retcode, &code, 8);
481475 if (err)
482− goto give_sigsegv;
476+ return -EFAULT;
483477
484478 /* Set up registers for signal handler */
485479 regs->sp = (unsigned long) frame;
@@ -502,10 +496,6 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka, · 16 unmodified lines
502496 #endif
503497
504498 return 0;
505−
506−give_sigsegv:
507− force_sigsegv(sig, current);
508− return -EFAULT;
509499 }
510500
511501 int 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
533523 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
534524
535525 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
536− goto give_sigsegv;
526+ return -EFAULT;
537527
538528 err |= __put_user(sig, &frame->sig);
539529 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
540530 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
541531 err |= copy_siginfo_to_user32(&frame->info, info);
542532 if (err)
543− goto give_sigsegv;
533+ return -EFAULT;
544534
545535 /* Create the ucontext. */
546536 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
556546 regs, set->sig[0]);
557547 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
558548 if (err)
559− goto give_sigsegv;
549+ return -EFAULT;
560550
561551 if (ka->sa.sa_flags & SA_RESTORER)
562552 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
571561 */
572562 err |= __copy_to_user(frame->retcode, &code, 8);
573563 if (err)
574− goto give_sigsegv;
564+ return -EFAULT;
575565
576566 /* Set up registers for signal handler */
577567 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
599589 #endif
600590
601591 return 0;
602−
603−give_sigsegv:
604− force_sigsegv(sig, current);
605− return -EFAULT;
606592 }
arch/x86/kernel/process_64.c+2−2
@@ -736,12 +736,12 @@ unsigned long get_wchan(struct task_struct *p) · 735 unmodified lines
736736 if (!p || p == current || p->state == TASK_RUNNING)
737737 return 0;
738738 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)
740740 return 0;
741741 fp = *(u64 *)(p->thread.sp);
742742 do {
743743 if (fp < (unsigned long)stack ||
744− fp > (unsigned long)stack+THREAD_SIZE)
744+ fp >= (unsigned long)stack+THREAD_SIZE)
745745 return 0;
746746 ip = *(u64 *)(fp+8);
747747 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
14521452 #endif
14531453 }
14541454
1455−void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
1455+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
1456+ int error_code, int si_code)
14561457 {
14571458 struct siginfo info;
14581459
@@ -1461,7 +1462,7 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code) · 2 unmodified lines
14611462
14621463 memset(&info, 0, sizeof(info));
14631464 info.si_signo = SIGTRAP;
1464− info.si_code = TRAP_BRKPT;
1465+ info.si_code = si_code;
14651466
14661467 /* User-mode ip? */
14671468 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
15481549 */
15491550 if (test_thread_flag(TIF_SINGLESTEP) &&
15501551 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
1551− send_sigtrap(current, regs, 0);
1552+ send_sigtrap(current, regs, 0, TRAP_BRKPT);
15521553 }
arch/x86/kernel/signal_32.c+134−88
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <asm/uaccess.h>
2828 #include <asm/i387.h>
2929 #include <asm/vdso.h>
30+#include <asm/syscall.h>
3031 #include <asm/syscalls.h>
3132
3233 #include "sigframe.h"
@@ -112,6 +113,27 @@ asmlinkage int sys_sigaltstack(unsigned long bx) · 79 unmodified lines
112113 return do_sigaltstack(uss, uoss, regs->sp);
113114 }
114115
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+}
115137
116138 /*
117139 * Do a signal return; undo the signal stack.
@@ -120,28 +142,13 @@ static int · 2 unmodified lines
120142 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
121143 unsigned long *pax)
122144 {
145+ void __user *buf;
146+ unsigned int tmpflags;
123147 unsigned int err = 0;
124148
125149 /* Always make any pending restarted system calls return -EINTR */
126150 current_thread_info()->restart_block.fn = do_no_restart_syscall;
127151
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−
145152 GET_SEG(gs);
146153 COPY_SEG(fs);
147154 COPY_SEG(es);
@@ -151,21 +158,12 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, · 3 unmodified lines
151158 COPY_SEG_STRICT(cs);
152159 COPY_SEG_STRICT(ss);
153160
154− {
155− unsigned int tmpflags;
156−
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;
161+ err |= __get_user(tmpflags, &sc->flags);
162+ regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
163+ regs->orig_ax = -1; /* disable syscall checks */
165164
166− err |= __get_user(buf, &sc->fpstate);
167− err |= restore_i387_xstate(buf);
168− }
165+ err |= __get_user(buf, &sc->fpstate);
166+ err |= restore_i387_xstate(buf);
169167
170168 err |= __get_user(*pax, &sc->ax);
171169 return err;
@@ -214,9 +212,8 @@ badframe: · 42 unmodified lines
214212 return 0;
215213 }
216214
217−asmlinkage int sys_rt_sigreturn(unsigned long __unused)
215+static long do_rt_sigreturn(struct pt_regs *regs)
218216 {
219− struct pt_regs *regs = (struct pt_regs *)&__unused;
220217 struct rt_sigframe __user *frame;
221218 unsigned long ax;
222219 sigset_t set;
@@ -242,10 +239,17 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused) · 19 unmodified lines
242239 return ax;
243240
244241 badframe:
245− force_sig(SIGSEGV, current);
242+ signal_fault(regs, frame, "rt_sigreturn");
246243 return 0;
247244 }
248245
246+asmlinkage 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+
249253 /*
250254 * Set up a signal frame.
251255 */
@@ -337,39 +341,29 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size, · 85 unmodified lines
337341 }
338342
339343 static int
340−setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
341− struct pt_regs *regs)
344+__setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
345+ struct pt_regs *regs)
342346 {
343347 struct sigframe __user *frame;
344348 void __user *restorer;
345349 int err = 0;
346− int usig;
347350 void __user *fpstate = NULL;
348351
349352 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
350353
351354 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
352− goto give_sigsegv;
355+ return -EFAULT;
353356
354− usig = current_thread_info()->exec_domain
355− && current_thread_info()->exec_domain->signal_invmap
356− && sig < 32
357− ? current_thread_info()->exec_domain->signal_invmap[sig]
358− : sig;
357+ if (__put_user(sig, &frame->sig))
358+ return -EFAULT;
359359
360− err = __put_user(usig, &frame->sig);
361− if (err)
362− goto give_sigsegv;
363−
364− err = setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
365− if (err)
366− goto give_sigsegv;
360+ if (setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
361+ return -EFAULT;
367362
368363 if (_NSIG_WORDS > 1) {
369− err = __copy_to_user(&frame->extramask, &set->sig[1],
370− sizeof(frame->extramask));
371− if (err)
372− goto give_sigsegv;
364+ if (__copy_to_user(&frame->extramask, &set->sig[1],
365+ sizeof(frame->extramask)))
366+ return -EFAULT;
373367 }
374368
375369 if (current->mm->context.vdso)
@@ -394,7 +388,7 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, · 18 unmodified lines
394388 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
395389
396390 if (err)
397− goto give_sigsegv;
391+ return -EFAULT;
398392
399393 /* Set up registers for signal handler */
400394 regs->sp = (unsigned long)frame;
@@ -409,38 +403,27 @@ setup_frame(int sig, struct k_sigaction *ka, sigset_t *set, · 8 unmodified lines
409403 regs->cs = __USER_CS;
410404
411405 return 0;
412−
413−give_sigsegv:
414− force_sigsegv(sig, current);
415− return -EFAULT;
416406 }
417407
418−static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
419− sigset_t *set, struct pt_regs *regs)
408+static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
409+ sigset_t *set, struct pt_regs *regs)
420410 {
421411 struct rt_sigframe __user *frame;
422412 void __user *restorer;
423413 int err = 0;
424− int usig;
425414 void __user *fpstate = NULL;
426415
427416 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
428417
429418 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
430− goto give_sigsegv;
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;
419+ return -EFAULT;
437420
438− err |= __put_user(usig, &frame->sig);
421+ err |= __put_user(sig, &frame->sig);
439422 err |= __put_user(&frame->info, &frame->pinfo);
440423 err |= __put_user(&frame->uc, &frame->puc);
441424 err |= copy_siginfo_to_user(&frame->info, info);
442425 if (err)
443− goto give_sigsegv;
426+ return -EFAULT;
444427
445428 /* Create the ucontext. */
446429 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
456439 regs, set->sig[0]);
457440 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
458441 if (err)
459− goto give_sigsegv;
442+ return -EFAULT;
460443
461444 /* Set up to return from userspace. */
462445 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
476459 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
477460
478461 if (err)
479− goto give_sigsegv;
462+ return -EFAULT;
480463
481464 /* Set up registers for signal handler */
482465 regs->sp = (unsigned long)frame;
483466 regs->ip = (unsigned long)ka->sa.sa_handler;
484− regs->ax = (unsigned long)usig;
467+ regs->ax = (unsigned long)sig;
485468 regs->dx = (unsigned long)&frame->info;
486469 regs->cx = (unsigned long)&frame->uc;
487470
@@ -491,15 +474,48 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 3 unmodified lines
491474 regs->cs = __USER_CS;
492475
493476 return 0;
494−
495−give_sigsegv:
496− force_sigsegv(sig, current);
497− return -EFAULT;
498477 }
499478
500479 /*
501480 * OK, we're invoking a handler:
502481 */
482+static 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+
495+static int
496+setup_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+
503519 static int
504520 handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
505521 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
507523 int ret;
508524
509525 /* Are we from a system call? */
510− if ((long)regs->orig_ax >= 0) {
526+ if (syscall_get_nr(current, regs) >= 0) {
511527 /* If so, check system call restarting.. */
512− switch (regs->ax) {
528+ switch (syscall_get_error(current, regs)) {
513529 case -ERESTART_RESTARTBLOCK:
514530 case -ERESTARTNOHAND:
515531 regs->ax = -EINTR;
@@ -536,15 +552,20 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 20 unmodified lines
536552 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
537553 regs->flags &= ~X86_EFLAGS_TF;
538554
539− /* Set up the stack frame */
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);
555+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
544556
545557 if (ret)
546558 return ret;
547559
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+
548569 /*
549570 * Clear the direction flag as per the ABI for function entry.
550571 */
@@ -571,6 +592,7 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, · 20 unmodified lines
571592 return 0;
572593 }
573594
595+#define NR_restart_syscall __NR_restart_syscall
574596 /*
575597 * Note that 'init' is a special process: it doesn't get signals it doesn't
576598 * 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
623645 }
624646
625647 /* Did we come from a system call? */
626− if ((long)regs->orig_ax >= 0) {
648+ if (syscall_get_nr(current, regs) >= 0) {
627649 /* Restart the system call - no handlers present */
628− switch (regs->ax) {
650+ switch (syscall_get_error(current, regs)) {
629651 case -ERESTARTNOHAND:
630652 case -ERESTARTSYS:
631653 case -ERESTARTNOINTR:
@@ -634,7 +656,7 @@ static void do_signal(struct pt_regs *regs) · 2 unmodified lines
634656 break;
635657
636658 case -ERESTART_RESTARTBLOCK:
637− regs->ax = __NR_restart_syscall;
659+ regs->ax = NR_restart_syscall;
638660 regs->ip -= 2;
639661 break;
640662 }
@@ -657,6 +679,12 @@ static void do_signal(struct pt_regs *regs) · 16 unmodified lines
657679 void
658680 do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
659681 {
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+
660688 /* deal with pending signal delivery */
661689 if (thread_info_flags & _TIF_SIGPENDING)
662690 do_signal(regs);
@@ -666,5 +694,23 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags) · 3 unmodified lines
666694 tracehook_notify_resume(regs);
667695 }
668696
697+#ifdef CONFIG_X86_32
669698 clear_thread_flag(TIF_IRET);
699+#endif /* CONFIG_X86_32 */
700+}
701+
702+void 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);
670716 }
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
5252 return do_sigaltstack(uss, uoss, regs->sp);
5353 }
5454
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+
5565 /*
5666 * Do a signal return; undo the signal stack.
5767 */
@@ -59,13 +69,13 @@ static int · 1 unmodified line
5969 restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
6070 unsigned long *pax)
6171 {
72+ void __user *buf;
73+ unsigned int tmpflags;
6274 unsigned int err = 0;
6375
6476 /* Always make any pending restarted system calls return -EINTR */
6577 current_thread_info()->restart_block.fn = do_no_restart_syscall;
6678
67−#define COPY(x) (err |= __get_user(regs->x, &sc->x))
68−
6979 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
7080 COPY(dx); COPY(cx); COPY(ip);
7181 COPY(r8);
@@ -80,34 +90,24 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, · 8 unmodified lines
8090 /* Kernel saves and restores only the CS segment register on signals,
8191 * which is the bare minimum needed to allow mixed 32/64-bit code.
8292 * App's signal handler can save/restore other segments if needed. */
83− {
84− unsigned cs;
85− err |= __get_user(cs, &sc->cs);
86− regs->cs = cs | 3; /* Force into user mode */
87− }
93+ COPY_SEG_STRICT(cs);
8894
89− {
90− unsigned int tmpflags;
91− err |= __get_user(tmpflags, &sc->flags);
92− regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
93− regs->orig_ax = -1; /* disable syscall checks */
94− }
95+ err |= __get_user(tmpflags, &sc->flags);
96+ regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
97+ regs->orig_ax = -1; /* disable syscall checks */
9598
96− {
97− struct _fpstate __user *buf;
98− err |= __get_user(buf, &sc->fpstate);
99− err |= restore_i387_xstate(buf);
100− }
99+ err |= __get_user(buf, &sc->fpstate);
100+ err |= restore_i387_xstate(buf);
101101
102102 err |= __get_user(*pax, &sc->ax);
103103 return err;
104104 }
105105
106−asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
106+static long do_rt_sigreturn(struct pt_regs *regs)
107107 {
108108 struct rt_sigframe __user *frame;
109− sigset_t set;
110109 unsigned long ax;
110+ sigset_t set;
111111
112112 frame = (struct rt_sigframe __user *)(regs->sp - sizeof(long));
113113 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
@@ -130,10 +130,15 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) · 16 unmodified lines
130130 return ax;
131131
132132 badframe:
133− signal_fault(regs, frame, "sigreturn");
133+ signal_fault(regs, frame, "rt_sigreturn");
134134 return 0;
135135 }
136136
137+asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
138+{
139+ return do_rt_sigreturn(regs);
140+}
141+
137142 /*
138143 * Set up a signal frame.
139144 */
@@ -195,8 +200,8 @@ get_stack(struct k_sigaction *ka, struct pt_regs *regs, unsigned long size) · 55 unmodified lines
195200 return (void __user *)round_down(sp - size, 64);
196201 }
197202
198−static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
199− sigset_t *set, struct pt_regs *regs)
203+static int __setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
204+ sigset_t *set, struct pt_regs *regs)
200205 {
201206 struct rt_sigframe __user *frame;
202207 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
209214 (unsigned long)fp - sizeof(struct rt_sigframe), 16) - 8;
210215
211216 if (save_i387_xstate(fp) < 0)
212− err |= -1;
217+ return -EFAULT;
213218 } else
214219 frame = get_stack(ka, regs, sizeof(struct rt_sigframe)) - 8;
215220
216221 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
217− goto give_sigsegv;
222+ return -EFAULT;
218223
219224 if (ka->sa.sa_flags & SA_SIGINFO) {
220− err |= copy_siginfo_to_user(&frame->info, info);
221− if (err)
222− goto give_sigsegv;
225+ if (copy_siginfo_to_user(&frame->info, info))
226+ return -EFAULT;
223227 }
224228
225229 /* Create the ucontext. */
@@ -247,11 +251,11 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 21 unmodified lines
247251 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
248252 } else {
249253 /* could use a vstub here */
250− goto give_sigsegv;
254+ return -EFAULT;
251255 }
252256
253257 if (err)
254− goto give_sigsegv;
258+ return -EFAULT;
255259
256260 /* Set up registers for signal handler */
257261 regs->di = sig;
@@ -271,15 +275,45 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, · 13 unmodified lines
271275 regs->cs = __USER_CS;
272276
273277 return 0;
274−
275−give_sigsegv:
276− force_sigsegv(sig, current);
277− return -EFAULT;
278278 }
279279
280280 /*
281281 * OK, we're invoking a handler
282282 */
283+static 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+
294+static int
295+setup_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+}
283317
284318 static int
285319 handle_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
317351 likely(test_and_clear_thread_flag(TIF_FORCED_TF)))
318352 regs->flags &= ~X86_EFLAGS_TF;
319353
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
328354 ret = setup_rt_frame(sig, ka, info, oldset, regs);
329355
330− if (ret == 0) {
331− /*
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);
356+ if (ret)
357+ return ret;
337358
338− /*
339− * Clear the direction flag as per the ABI for function entry.
340− */
341− regs->flags &= ~X86_EFLAGS_DF;
359+#ifdef CONFIG_X86_64
360+ /*
361+ * This has nothing to do with segment registers,
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
342367
343− /*
344− * Clear TF when entering the signal handler, but
345− * notify any tracer that was single-stepping it.
346− * The tracer may want to single-step inside the
347− * handler too.
348− */
349− regs->flags &= ~X86_EFLAGS_TF;
368+ /*
369+ * Clear the direction flag as per the ABI for function entry.
370+ */
371+ regs->flags &= ~X86_EFLAGS_DF;
350372
351− spin_lock_irq(&current->sighand->siglock);
352− sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
353− if (!(ka->sa.sa_flags & SA_NODEFER))
354− sigaddset(&current->blocked, sig);
355− recalc_sigpending();
356− spin_unlock_irq(&current->sighand->siglock);
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;
357380
358− tracehook_signal_handler(sig, info, ka, regs,
359− test_thread_flag(TIF_SINGLESTEP));
360− }
381+ spin_lock_irq(&current->sighand->siglock);
382+ sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
383+ if (!(ka->sa.sa_flags & SA_NODEFER))
384+ sigaddset(&current->blocked, sig);
385+ recalc_sigpending();
386+ spin_unlock_irq(&current->sighand->siglock);
361387
362− return ret;
388+ tracehook_signal_handler(sig, info, ka, regs,
389+ test_thread_flag(TIF_SINGLESTEP));
390+
391+ return 0;
363392 }
364393
394+#define NR_restart_syscall \
395+ test_thread_flag(TIF_IA32) ? __NR_ia32_restart_syscall : __NR_restart_syscall
365396 /*
366397 * Note that 'init' is a special process: it doesn't get signals it doesn't
367398 * 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
391422
392423 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
393424 if (signr > 0) {
394− /* Re-enable any watchpoints before delivering the
425+ /*
426+ * Re-enable any watchpoints before delivering the
395427 * signal to user space. The processor register will
396428 * have been cleared if the watchpoint triggered
397429 * inside the kernel.
@@ -399,7 +431,7 @@ static void do_signal(struct pt_regs *regs) · 1 unmodified line
399431 if (current->thread.debugreg7)
400432 set_debugreg(current->thread.debugreg7, 7);
401433
402− /* Whee! Actually deliver the signal. */
434+ /* Whee! Actually deliver the signal. */
403435 if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
404436 /*
405437 * A signal was successfully delivered; the saved
@@ -422,10 +454,9 @@ static void do_signal(struct pt_regs *regs) · 16 unmodified lines
422454 regs->ax = regs->orig_ax;
423455 regs->ip -= 2;
424456 break;
457+
425458 case -ERESTART_RESTARTBLOCK:
426− regs->ax = test_thread_flag(TIF_IA32) ?
427− __NR_ia32_restart_syscall :
428− __NR_restart_syscall;
459+ regs->ax = NR_restart_syscall;
429460 regs->ip -= 2;
430461 break;
431462 }
@@ -441,14 +472,18 @@ static void do_signal(struct pt_regs *regs) · 9 unmodified lines
441472 }
442473 }
443474
444−void do_notify_resume(struct pt_regs *regs, void *unused,
445− __u32 thread_info_flags)
475+/*
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)
446481 {
447−#ifdef CONFIG_X86_MCE
482+#if defined(CONFIG_X86_64) && defined(CONFIG_X86_MCE)
448483 /* notify userspace of pending MCEs */
449484 if (thread_info_flags & _TIF_MCE_NOTIFY)
450485 mce_notify_user();
451−#endif /* CONFIG_X86_MCE */
486+#endif /* CONFIG_X86_64 && CONFIG_X86_MCE */
452487
453488 /* deal with pending signal delivery */
454489 if (thread_info_flags & _TIF_SIGPENDING)
@@ -458,17 +493,23 @@ void do_notify_resume(struct pt_regs *regs, void *unused, · 3 unmodified lines
458493 clear_thread_flag(TIF_NOTIFY_RESUME);
459494 tracehook_notify_resume(regs);
460495 }
496+
497+#ifdef CONFIG_X86_32
498+ clear_thread_flag(TIF_IRET);
499+#endif /* CONFIG_X86_32 */
461500 }
462501
463502 void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
464503 {
465504 struct task_struct *me = current;
505+
466506 if (show_unhandled_signals && printk_ratelimit()) {
467− printk("%s[%d] bad frame in %s frame:%p ip:%lx sp:%lx orax:%lx",
468− me->comm, me->pid, where, frame, regs->ip,
469− regs->sp, regs->orig_ax);
507+ printk(KERN_INFO
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);
470511 print_vma_addr(" in ", regs->ip);
471− printk("\n");
512+ printk(KERN_CONT "\n");
472513 }
473514
474515 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
891891 {
892892 struct task_struct *tsk = current;
893893 unsigned int condition;
894+ int si_code;
894895
895896 trace_hardirqs_fixup();
896897
@@ -935,8 +936,9 @@ void __kprobes do_debug(struct pt_regs *regs, long error_code) · 38 unmodified lines
935936 goto clear_TF_reenable;
936937 }
937938
939+ si_code = get_si_code((unsigned long)condition);
938940 /* Ok, finally something we can handle */
939− send_sigtrap(tsk, regs, error_code);
941+ send_sigtrap(tsk, regs, error_code, si_code);
940942
941943 /*
942944 * 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
940940 tsk->thread.error_code = error_code;
941941 info.si_signo = SIGTRAP;
942942 info.si_errno = 0;
943− info.si_code = TRAP_BRKPT;
943+ info.si_code = get_si_code(condition);
944944 info.si_addr = user_mode(regs) ? (void __user *)regs->ip : NULL;
945945 force_sig_info(SIGTRAP, &info, tsk);
946946
arch/x86/kernel/vmlinux_64.lds.S+1−1
@@ -172,8 +172,8 @@ SECTIONS · 171 unmodified lines
172172 .x86_cpu_dev.init : AT(ADDR(.x86_cpu_dev.init) - LOAD_OFFSET) {
173173 *(.x86_cpu_dev.init)
174174 }
175− SECURITY_INIT
176175 __x86_cpu_dev_end = .;
176+ SECURITY_INIT
177177
178178 . = ALIGN(8);
179179 .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
614614 */
615615 offset = phys_addr & ~PAGE_MASK;
616616 phys_addr &= PAGE_MASK;
617− size = PAGE_ALIGN(last_addr) - phys_addr;
617+ size = PAGE_ALIGN(last_addr + 1) - phys_addr;
618618
619619 /*
620620 * 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
199199 */
200200 #define TRAP_BRKPT (__SI_FAULT|1) /* process breakpoint */
201201 #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 */
202204 #define NSIGTRAP 2
203205
204206 /*
include/asm-parisc/siginfo.h+0−5
@@ -3,11 +3,6 @@ · 2 unmodified lines
33
44 #include <asm-generic/siginfo.h>
55
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 */
116 #undef NSIGTRAP
127 #define NSIGTRAP 4
138
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
177177
178178 #ifdef CONFIG_X86_32
179179 extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs,
180− int error_code);
181−#else
182−void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
180+ int error_code, int si_code);
183181 #endif
184182
183+void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
184+
185185 extern long syscall_trace_enter(struct pt_regs *);
186186 extern void syscall_trace_leave(struct pt_regs *);
187187
include/asm-x86/spinlock.h+25−35
@@ -21,8 +21,10 @@ · 20 unmodified lines
2121
2222 #ifdef CONFIG_X86_32
2323 # define LOCK_PTR_REG "a"
24+# define REG_PTR_MODE "k"
2425 #else
2526 # define LOCK_PTR_REG "D"
27+# define REG_PTR_MODE "q"
2628 #endif
2729
2830 #if defined(CONFIG_X86_32) && \
@@ -54,19 +56,7 @@ · 25 unmodified lines
5456 * much between them in performance though, especially as locks are out of line.
5557 */
5658 #if (NR_CPUS < 256)
57−static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
58−{
59− int tmp = ACCESS_ONCE(lock->slock);
60−
61− return (((tmp >> 8) & 0xff) != (tmp & 0xff));
62−}
63−
64−static 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−}
59+#define TICKET_SHIFT 8
7060
7161 static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
7262 {
@@ -89,19 +79,17 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) · 16 unmodified lines
8979
9080 static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock)
9181 {
92− int tmp;
93− short new;
82+ int tmp, new;
9483
95− asm volatile("movw %2,%w0\n\t"
84+ asm volatile("movzwl %2, %0\n\t"
9685 "cmpb %h0,%b0\n\t"
86+ "leal 0x100(%" REG_PTR_MODE "0), %1\n\t"
9787 "jne 1f\n\t"
98− "movw %w0,%w1\n\t"
99− "incb %h1\n\t"
10088 LOCK_PREFIX "cmpxchgw %w1,%2\n\t"
10189 "1:"
10290 "sete %b1\n\t"
10391 "movzbl %b1,%0\n\t"
104− : "=&a" (tmp), "=Q" (new), "+m" (lock->slock)
92+ : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
10593 :
10694 : "memory", "cc");
10795
@@ -116,19 +104,7 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) · 8 unmodified lines
116104 : "memory", "cc");
117105 }
118106 #else
119−static inline int __ticket_spin_is_locked(raw_spinlock_t *lock)
120−{
121− int tmp = ACCESS_ONCE(lock->slock);
122−
123− return (((tmp >> 16) & 0xffff) != (tmp & 0xffff));
124−}
125−
126−static 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−}
107+#define TICKET_SHIFT 16
132108
133109 static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock)
134110 {
@@ -146,7 +122,7 @@ static __always_inline void __ticket_spin_lock(raw_spinlock_t *lock) · 11 unmodified lines
146122 /* don't need lfence here, because loads are in-order */
147123 "jmp 1b\n"
148124 "2:"
149− : "+Q" (inc), "+m" (lock->slock), "=r" (tmp)
125+ : "+r" (inc), "+m" (lock->slock), "=&r" (tmp)
150126 :
151127 : "memory", "cc");
152128 }
@@ -160,13 +136,13 @@ static __always_inline int __ticket_spin_trylock(raw_spinlock_t *lock) · 7 unmodified lines
160136 "movl %0,%1\n\t"
161137 "roll $16, %0\n\t"
162138 "cmpl %0,%1\n\t"
139+ "leal 0x00010000(%" REG_PTR_MODE "0), %1\n\t"
163140 "jne 1f\n\t"
164− "addl $0x00010000, %1\n\t"
165141 LOCK_PREFIX "cmpxchgl %1,%2\n\t"
166142 "1:"
167143 "sete %b1\n\t"
168144 "movzbl %b1,%0\n\t"
169− : "=&a" (tmp), "=r" (new), "+m" (lock->slock)
145+ : "=&a" (tmp), "=&q" (new), "+m" (lock->slock)
170146 :
171147 : "memory", "cc");
172148
@@ -182,6 +158,20 @@ static __always_inline void __ticket_spin_unlock(raw_spinlock_t *lock) · 9 unmodified lines
182158 }
183159 #endif
184160
161+static 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+
168+static 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+
185175 #ifdef CONFIG_PARAVIRT
186176 /*
187177 * Define virtualization-friendly old-style lock byte lock, for use in
include/asm-x86/traps.h+12−0
@@ -1,6 +1,8 @@
11 #ifndef ASM_X86__TRAPS_H
22 #define ASM_X86__TRAPS_H
33
4+#include <asm/debugreg.h>
5+
46 /* Common in X86_32 and X86_64 */
57 asmlinkage void divide_error(void);
68 asmlinkage void debug(void);
@@ -36,6 +38,16 @@ void do_invalid_op(struct pt_regs *, long); · 29 unmodified lines
3638 void do_general_protection(struct pt_regs *, long);
3739 void do_nmi(struct pt_regs *, long);
3840
41+static 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+
3951 extern int panic_on_unrecovered_nmi;
4052 extern int kstack_depth_to_print;
4153

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