aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-06 12:16:40 -0400
committerIngo Molnar <mingo@elte.hu>2008-10-06 12:16:40 -0400
commitb159d7a989e53ab3529084348aa80441520b8575 (patch)
tree416512130cf80ded4cd88fc064d0b28c8220616f /arch/x86
parent0962f402af1bb0b53ccee626785d202a10c12fff (diff)
parent4ab4ba32aa16b012cb0faabf1a27952508fe67f2 (diff)
Merge branch 'x86/tracehook' into x86-v28-for-linus-phase1
Conflicts: arch/x86/kernel/signal_64.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86')
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/kernel/ptrace.c34
-rw-r--r--arch/x86/kernel/signal_32.c11
-rw-r--r--arch/x86/kernel/signal_64.c49
4 files changed, 30 insertions, 65 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index ed92864d1325..ebfd7ff82ade 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -29,6 +29,7 @@ config X86
29 select HAVE_FTRACE 29 select HAVE_FTRACE
30 select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) 30 select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
31 select HAVE_ARCH_KGDB if !X86_VOYAGER 31 select HAVE_ARCH_KGDB if !X86_VOYAGER
32 select HAVE_ARCH_TRACEHOOK
32 select HAVE_GENERIC_DMA_COHERENT if X86_32 33 select HAVE_GENERIC_DMA_COHERENT if X86_32
33 select HAVE_EFFICIENT_UNALIGNED_ACCESS 34 select HAVE_EFFICIENT_UNALIGNED_ACCESS
34 35
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index d00e756c05af..e375b658efc3 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -14,6 +14,7 @@
14#include <linux/errno.h> 14#include <linux/errno.h>
15#include <linux/ptrace.h> 15#include <linux/ptrace.h>
16#include <linux/regset.h> 16#include <linux/regset.h>
17#include <linux/tracehook.h>
17#include <linux/user.h> 18#include <linux/user.h>
18#include <linux/elf.h> 19#include <linux/elf.h>
19#include <linux/security.h> 20#include <linux/security.h>
@@ -1469,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
1469 force_sig_info(SIGTRAP, &info, tsk); 1470 force_sig_info(SIGTRAP, &info, tsk);
1470} 1471}
1471 1472
1472static void syscall_trace(struct pt_regs *regs)
1473{
1474 if (!(current->ptrace & PT_PTRACED))
1475 return;
1476
1477#if 0
1478 printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
1479 current->comm,
1480 regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
1481 current_thread_info()->flags, current->ptrace);
1482#endif
1483
1484 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
1485 ? 0x80 : 0));
1486 /*
1487 * this isn't the same as continuing with a signal, but it will do
1488 * for normal use. strace only continues with a signal if the
1489 * stopping signal is not SIGTRAP. -brl
1490 */
1491 if (current->exit_code) {
1492 send_sig(current->exit_code, current, 1);
1493 current->exit_code = 0;
1494 }
1495}
1496 1473
1497#ifdef CONFIG_X86_32 1474#ifdef CONFIG_X86_32
1498# define IS_IA32 1 1475# define IS_IA32 1
@@ -1526,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
1526 if (unlikely(test_thread_flag(TIF_SYSCALL_EMU))) 1503 if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
1527 ret = -1L; 1504 ret = -1L;
1528 1505
1529 if (ret || test_thread_flag(TIF_SYSCALL_TRACE)) 1506 if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
1530 syscall_trace(regs); 1507 tracehook_report_syscall_entry(regs))
1508 ret = -1L;
1531 1509
1532 if (unlikely(current->audit_context)) { 1510 if (unlikely(current->audit_context)) {
1533 if (IS_IA32) 1511 if (IS_IA32)
@@ -1553,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1553 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); 1531 audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);
1554 1532
1555 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1533 if (test_thread_flag(TIF_SYSCALL_TRACE))
1556 syscall_trace(regs); 1534 tracehook_report_syscall_exit(regs, 0);
1557 1535
1558 /* 1536 /*
1559 * If TIF_SYSCALL_EMU is set, we only get here because of 1537 * If TIF_SYSCALL_EMU is set, we only get here because of
@@ -1569,6 +1547,6 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
1569 * system call instruction. 1547 * system call instruction.
1570 */ 1548 */
1571 if (test_thread_flag(TIF_SINGLESTEP) && 1549 if (test_thread_flag(TIF_SINGLESTEP) &&
1572 (current->ptrace & PT_PTRACED)) 1550 tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
1573 send_sigtrap(current, regs, 0); 1551 send_sigtrap(current, regs, 0);
1574} 1552}
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index 0c727f64e79b..2a2435d3037d 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -17,6 +17,7 @@
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/sched.h> 18#include <linux/sched.h>
19#include <linux/wait.h> 19#include <linux/wait.h>
20#include <linux/tracehook.h>
20#include <linux/elf.h> 21#include <linux/elf.h>
21#include <linux/smp.h> 22#include <linux/smp.h>
22#include <linux/mm.h> 23#include <linux/mm.h>
@@ -559,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
559 * handler too. 560 * handler too.
560 */ 561 */
561 regs->flags &= ~X86_EFLAGS_TF; 562 regs->flags &= ~X86_EFLAGS_TF;
562 if (test_thread_flag(TIF_SINGLESTEP))
563 ptrace_notify(SIGTRAP);
564 563
565 spin_lock_irq(&current->sighand->siglock); 564 spin_lock_irq(&current->sighand->siglock);
566 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask); 565 sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
@@ -569,6 +568,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
569 recalc_sigpending(); 568 recalc_sigpending();
570 spin_unlock_irq(&current->sighand->siglock); 569 spin_unlock_irq(&current->sighand->siglock);
571 570
571 tracehook_signal_handler(sig, info, ka, regs,
572 test_thread_flag(TIF_SINGLESTEP));
573
572 return 0; 574 return 0;
573} 575}
574 576
@@ -662,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
662 if (thread_info_flags & _TIF_SIGPENDING) 664 if (thread_info_flags & _TIF_SIGPENDING)
663 do_signal(regs); 665 do_signal(regs);
664 666
667 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
668 clear_thread_flag(TIF_NOTIFY_RESUME);
669 tracehook_notify_resume(regs);
670 }
671
665 clear_thread_flag(TIF_IRET); 672 clear_thread_flag(TIF_IRET);
666} 673}
diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c
index 2f1464050059..4d32487805ef 100644
--- a/arch/x86/kernel/signal_64.c
+++ b/arch/x86/kernel/signal_64.c
@@ -15,6 +15,7 @@
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/wait.h> 16#include <linux/wait.h>
17#include <linux/ptrace.h> 17#include <linux/ptrace.h>
18#include <linux/tracehook.h>
18#include <linux/unistd.h> 19#include <linux/unistd.h>
19#include <linux/stddef.h> 20#include <linux/stddef.h>
20#include <linux/personality.h> 21#include <linux/personality.h>
@@ -26,6 +27,7 @@
26#include <asm/proto.h> 27#include <asm/proto.h>
27#include <asm/ia32_unistd.h> 28#include <asm/ia32_unistd.h>
28#include <asm/mce.h> 29#include <asm/mce.h>
30#include <asm/syscall.h>
29#include <asm/syscalls.h> 31#include <asm/syscalls.h>
30#include "sigframe.h" 32#include "sigframe.h"
31 33
@@ -356,35 +358,6 @@ give_sigsegv:
356} 358}
357 359
358/* 360/*
359 * Return -1L or the syscall number that @regs is executing.
360 */
361static long current_syscall(struct pt_regs *regs)
362{
363 /*
364 * We always sign-extend a -1 value being set here,
365 * so this is always either -1L or a syscall number.
366 */
367 return regs->orig_ax;
368}
369
370/*
371 * Return a value that is -EFOO if the system call in @regs->orig_ax
372 * returned an error. This only works for @regs from @current.
373 */
374static long current_syscall_ret(struct pt_regs *regs)
375{
376#ifdef CONFIG_IA32_EMULATION
377 if (test_thread_flag(TIF_IA32))
378 /*
379 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
380 * and will match correctly in comparisons.
381 */
382 return (int) regs->ax;
383#endif
384 return regs->ax;
385}
386
387/*
388 * OK, we're invoking a handler 361 * OK, we're invoking a handler
389 */ 362 */
390 363
@@ -395,9 +368,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
395 int ret; 368 int ret;
396 369
397 /* Are we from a system call? */ 370 /* Are we from a system call? */
398 if (current_syscall(regs) >= 0) { 371 if (syscall_get_nr(current, regs) >= 0) {
399 /* If so, check system call restarting.. */ 372 /* If so, check system call restarting.. */
400 switch (current_syscall_ret(regs)) { 373 switch (syscall_get_error(current, regs)) {
401 case -ERESTART_RESTARTBLOCK: 374 case -ERESTART_RESTARTBLOCK:
402 case -ERESTARTNOHAND: 375 case -ERESTARTNOHAND:
403 regs->ax = -EINTR; 376 regs->ax = -EINTR;
@@ -454,8 +427,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
454 * handler too. 427 * handler too.
455 */ 428 */
456 regs->flags &= ~X86_EFLAGS_TF; 429 regs->flags &= ~X86_EFLAGS_TF;
457 if (test_thread_flag(TIF_SINGLESTEP))
458 ptrace_notify(SIGTRAP);
459 430
460 spin_lock_irq(&current->sighand->siglock); 431 spin_lock_irq(&current->sighand->siglock);
461 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 432 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
@@ -463,6 +434,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
463 sigaddset(&current->blocked,sig); 434 sigaddset(&current->blocked,sig);
464 recalc_sigpending(); 435 recalc_sigpending();
465 spin_unlock_irq(&current->sighand->siglock); 436 spin_unlock_irq(&current->sighand->siglock);
437
438 tracehook_signal_handler(sig, info, ka, regs,
439 test_thread_flag(TIF_SINGLESTEP));
466 } 440 }
467 441
468 return ret; 442 return ret;
@@ -519,9 +493,9 @@ static void do_signal(struct pt_regs *regs)
519 } 493 }
520 494
521 /* Did we come from a system call? */ 495 /* Did we come from a system call? */
522 if (current_syscall(regs) >= 0) { 496 if (syscall_get_nr(current, regs) >= 0) {
523 /* Restart the system call - no handlers present */ 497 /* Restart the system call - no handlers present */
524 switch (current_syscall_ret(regs)) { 498 switch (syscall_get_error(current, regs)) {
525 case -ERESTARTNOHAND: 499 case -ERESTARTNOHAND:
526 case -ERESTARTSYS: 500 case -ERESTARTSYS:
527 case -ERESTARTNOINTR: 501 case -ERESTARTNOINTR:
@@ -559,6 +533,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
559 /* deal with pending signal delivery */ 533 /* deal with pending signal delivery */
560 if (thread_info_flags & _TIF_SIGPENDING) 534 if (thread_info_flags & _TIF_SIGPENDING)
561 do_signal(regs); 535 do_signal(regs);
536
537 if (thread_info_flags & _TIF_NOTIFY_RESUME) {
538 clear_thread_flag(TIF_NOTIFY_RESUME);
539 tracehook_notify_resume(regs);
540 }
562} 541}
563 542
564void signal_fault(struct pt_regs *regs, void __user *frame, char *where) 543void signal_fault(struct pt_regs *regs, void __user *frame, char *where)