Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b159d7a9 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'x86/tracehook' into x86-v28-for-linus-phase1



Conflicts:
	arch/x86/kernel/signal_64.c

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents 0962f402 4ab4ba32
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ config X86
	select HAVE_FTRACE
	select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64)
	select HAVE_ARCH_KGDB if !X86_VOYAGER
	select HAVE_ARCH_TRACEHOOK
	select HAVE_GENERIC_DMA_COHERENT if X86_32
	select HAVE_EFFICIENT_UNALIGNED_ACCESS

+6 −28
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/errno.h>
#include <linux/ptrace.h>
#include <linux/regset.h>
#include <linux/tracehook.h>
#include <linux/user.h>
#include <linux/elf.h>
#include <linux/security.h>
@@ -1469,30 +1470,6 @@ void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, int error_code)
	force_sig_info(SIGTRAP, &info, tsk);
}

static void syscall_trace(struct pt_regs *regs)
{
	if (!(current->ptrace & PT_PTRACED))
		return;

#if 0
	printk("trace %s ip %lx sp %lx ax %d origrax %d caller %lx tiflags %x ptrace %x\n",
	       current->comm,
	       regs->ip, regs->sp, regs->ax, regs->orig_ax, __builtin_return_address(0),
	       current_thread_info()->flags, current->ptrace);
#endif

	ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
				? 0x80 : 0));
	/*
	 * this isn't the same as continuing with a signal, but it will do
	 * for normal use.  strace only continues with a signal if the
	 * stopping signal is not SIGTRAP.  -brl
	 */
	if (current->exit_code) {
		send_sig(current->exit_code, current, 1);
		current->exit_code = 0;
	}
}

#ifdef CONFIG_X86_32
# define IS_IA32	1
@@ -1526,8 +1503,9 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)
	if (unlikely(test_thread_flag(TIF_SYSCALL_EMU)))
		ret = -1L;

	if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
		syscall_trace(regs);
	if ((ret || test_thread_flag(TIF_SYSCALL_TRACE)) &&
	    tracehook_report_syscall_entry(regs))
		ret = -1L;

	if (unlikely(current->audit_context)) {
		if (IS_IA32)
@@ -1553,7 +1531,7 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)
		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax);

	if (test_thread_flag(TIF_SYSCALL_TRACE))
		syscall_trace(regs);
		tracehook_report_syscall_exit(regs, 0);

	/*
	 * 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)
	 * system call instruction.
	 */
	if (test_thread_flag(TIF_SINGLESTEP) &&
	    (current->ptrace & PT_PTRACED))
	    tracehook_consider_fatal_signal(current, SIGTRAP, SIG_DFL))
		send_sigtrap(current, regs, 0);
}
+9 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/tracehook.h>
#include <linux/elf.h>
#include <linux/smp.h>
#include <linux/mm.h>
@@ -559,8 +560,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
	 * handler too.
	 */
	regs->flags &= ~X86_EFLAGS_TF;
	if (test_thread_flag(TIF_SINGLESTEP))
		ptrace_notify(SIGTRAP);

	spin_lock_irq(&current->sighand->siglock);
	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,
	recalc_sigpending();
	spin_unlock_irq(&current->sighand->siglock);

	tracehook_signal_handler(sig, info, ka, regs,
				 test_thread_flag(TIF_SINGLESTEP));

	return 0;
}

@@ -662,5 +664,10 @@ do_notify_resume(struct pt_regs *regs, void *unused, __u32 thread_info_flags)
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(regs);

	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
		clear_thread_flag(TIF_NOTIFY_RESUME);
		tracehook_notify_resume(regs);
	}

	clear_thread_flag(TIF_IRET);
}
+14 −35
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/wait.h>
#include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
#include <linux/personality.h>
@@ -26,6 +27,7 @@
#include <asm/proto.h>
#include <asm/ia32_unistd.h>
#include <asm/mce.h>
#include <asm/syscall.h>
#include <asm/syscalls.h>
#include "sigframe.h"

@@ -355,35 +357,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
	return -EFAULT;
}

/*
 * Return -1L or the syscall number that @regs is executing.
 */
static long current_syscall(struct pt_regs *regs)
{
	/*
	 * We always sign-extend a -1 value being set here,
	 * so this is always either -1L or a syscall number.
	 */
	return regs->orig_ax;
}

/*
 * Return a value that is -EFOO if the system call in @regs->orig_ax
 * returned an error.  This only works for @regs from @current.
 */
static long current_syscall_ret(struct pt_regs *regs)
{
#ifdef CONFIG_IA32_EMULATION
	if (test_thread_flag(TIF_IA32))
		/*
		 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
		 * and will match correctly in comparisons.
		 */
		return (int) regs->ax;
#endif
	return regs->ax;
}

/*
 * OK, we're invoking a handler
 */	
@@ -395,9 +368,9 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
	int ret;

	/* Are we from a system call? */
	if (current_syscall(regs) >= 0) {
	if (syscall_get_nr(current, regs) >= 0) {
		/* If so, check system call restarting.. */
		switch (current_syscall_ret(regs)) {
		switch (syscall_get_error(current, regs)) {
		case -ERESTART_RESTARTBLOCK:
		case -ERESTARTNOHAND:
			regs->ax = -EINTR;
@@ -454,8 +427,6 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
		 * handler too.
		 */
		regs->flags &= ~X86_EFLAGS_TF;
		if (test_thread_flag(TIF_SINGLESTEP))
			ptrace_notify(SIGTRAP);

		spin_lock_irq(&current->sighand->siglock);
		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,
			sigaddset(&current->blocked,sig);
		recalc_sigpending();
		spin_unlock_irq(&current->sighand->siglock);

		tracehook_signal_handler(sig, info, ka, regs,
					 test_thread_flag(TIF_SINGLESTEP));
	}

	return ret;
@@ -519,9 +493,9 @@ static void do_signal(struct pt_regs *regs)
	}

	/* Did we come from a system call? */
	if (current_syscall(regs) >= 0) {
	if (syscall_get_nr(current, regs) >= 0) {
		/* Restart the system call - no handlers present */
		switch (current_syscall_ret(regs)) {
		switch (syscall_get_error(current, regs)) {
		case -ERESTARTNOHAND:
		case -ERESTARTSYS:
		case -ERESTARTNOINTR:
@@ -559,6 +533,11 @@ void do_notify_resume(struct pt_regs *regs, void *unused,
	/* deal with pending signal delivery */
	if (thread_info_flags & _TIF_SIGPENDING)
		do_signal(regs);

	if (thread_info_flags & _TIF_NOTIFY_RESUME) {
		clear_thread_flag(TIF_NOTIFY_RESUME);
		tracehook_notify_resume(regs);
	}
}

void signal_fault(struct pt_regs *regs, void __user *frame, char *where)
+5 −0
Original line number Diff line number Diff line
@@ -250,6 +250,11 @@ static inline unsigned long frame_pointer(struct pt_regs *regs)
	return regs->bp;
}

static inline unsigned long user_stack_pointer(struct pt_regs *regs)
{
	return regs->sp;
}

/*
 * These are defined as per linux/ptrace.h, which see.
 */
Loading