summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-28 17:03:43 +0200
committerIngo Molnar <mingo@elte.hu>2008-07-28 17:03:43 +0200
commit71998e83c520c7a91b254dc9705baeedbee0d44f (patch)
treebe5bd54e975c416d3b607c91f6099e45cd0cd432 /include
parentMerge branch 'hotfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6 (diff)
parentx86: tracehook: CONFIG_HAVE_ARCH_TRACEHOOK (diff)
downloadlinux-71998e83c520c7a91b254dc9705baeedbee0d44f.tar.xz
linux-71998e83c520c7a91b254dc9705baeedbee0d44f.zip
Merge branch 'x86-tracehook' of git://git.kernel.org/pub/scm/linux/kernel/git/frob/linux-2.6-utrace into x86/tracehook
Diffstat (limited to 'include')
-rw-r--r--include/asm-x86/ptrace.h5
-rw-r--r--include/asm-x86/syscall.h210
-rw-r--r--include/asm-x86/thread_info.h4
3 files changed, 218 insertions, 1 deletions
diff --git a/include/asm-x86/ptrace.h b/include/asm-x86/ptrace.h
index 8a71db803da6..91a77f5c4678 100644
--- a/include/asm-x86/ptrace.h
+++ b/include/asm-x86/ptrace.h
@@ -213,6 +213,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.
*/
diff --git a/include/asm-x86/syscall.h b/include/asm-x86/syscall.h
new file mode 100644
index 000000000000..6f293892895a
--- /dev/null
+++ b/include/asm-x86/syscall.h
@@ -0,0 +1,210 @@
+/*
+ * Access to user system call parameters and results
+ *
+ * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU General Public License v.2.
+ *
+ * See asm-generic/syscall.h for descriptions of what we must do here.
+ */
+
+#ifndef _ASM_SYSCALL_H
+#define _ASM_SYSCALL_H 1
+
+#include <linux/sched.h>
+
+static inline long syscall_get_nr(struct task_struct *task,
+ 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;
+}
+
+static inline void syscall_rollback(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ regs->ax = regs->orig_ax;
+}
+
+static inline long syscall_get_error(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ unsigned long error = regs->ax;
+#ifdef CONFIG_IA32_EMULATION
+ /*
+ * TS_COMPAT is set for 32-bit syscall entries and then
+ * remains set until we return to user mode.
+ */
+ if (task_thread_info(task)->status & TS_COMPAT)
+ /*
+ * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
+ * and will match correctly in comparisons.
+ */
+ error = (long) (int) error;
+#endif
+ return error >= -4095L ? error : 0;
+}
+
+static inline long syscall_get_return_value(struct task_struct *task,
+ struct pt_regs *regs)
+{
+ return regs->ax;
+}
+
+static inline void syscall_set_return_value(struct task_struct *task,
+ struct pt_regs *regs,
+ int error, long val)
+{
+ regs->ax = (long) error ?: val;
+}
+
+#ifdef CONFIG_X86_32
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(args, &regs->bx + i, n * sizeof(args[0]));
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+ BUG_ON(i + n > 6);
+ memcpy(&regs->bx + i, args, n * sizeof(args[0]));
+}
+
+#else /* CONFIG_X86_64 */
+
+static inline void syscall_get_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+ if (task_thread_info(task)->status & TS_COMPAT)
+ switch (i + n) {
+ case 6:
+ if (!n--) break;
+ *args++ = regs->bp;
+ case 5:
+ if (!n--) break;
+ *args++ = regs->di;
+ case 4:
+ if (!n--) break;
+ *args++ = regs->si;
+ case 3:
+ if (!n--) break;
+ *args++ = regs->dx;
+ case 2:
+ if (!n--) break;
+ *args++ = regs->cx;
+ case 1:
+ if (!n--) break;
+ *args++ = regs->bx;
+ case 0:
+ if (!n--) break;
+ default:
+ BUG();
+ break;
+ }
+ else
+# endif
+ switch (i + n) {
+ case 6:
+ if (!n--) break;
+ *args++ = regs->r9;
+ case 5:
+ if (!n--) break;
+ *args++ = regs->r8;
+ case 4:
+ if (!n--) break;
+ *args++ = regs->r10;
+ case 3:
+ if (!n--) break;
+ *args++ = regs->dx;
+ case 2:
+ if (!n--) break;
+ *args++ = regs->si;
+ case 1:
+ if (!n--) break;
+ *args++ = regs->di;
+ case 0:
+ if (!n--) break;
+ default:
+ BUG();
+ break;
+ }
+}
+
+static inline void syscall_set_arguments(struct task_struct *task,
+ struct pt_regs *regs,
+ unsigned int i, unsigned int n,
+ const unsigned long *args)
+{
+# ifdef CONFIG_IA32_EMULATION
+ if (task_thread_info(task)->status & TS_COMPAT)
+ switch (i + n) {
+ case 6:
+ if (!n--) break;
+ regs->bp = *args++;
+ case 5:
+ if (!n--) break;
+ regs->di = *args++;
+ case 4:
+ if (!n--) break;
+ regs->si = *args++;
+ case 3:
+ if (!n--) break;
+ regs->dx = *args++;
+ case 2:
+ if (!n--) break;
+ regs->cx = *args++;
+ case 1:
+ if (!n--) break;
+ regs->bx = *args++;
+ case 0:
+ if (!n--) break;
+ default:
+ BUG();
+ }
+ else
+# endif
+ switch (i + n) {
+ case 6:
+ if (!n--) break;
+ regs->r9 = *args++;
+ case 5:
+ if (!n--) break;
+ regs->r8 = *args++;
+ case 4:
+ if (!n--) break;
+ regs->r10 = *args++;
+ case 3:
+ if (!n--) break;
+ regs->dx = *args++;
+ case 2:
+ if (!n--) break;
+ regs->si = *args++;
+ case 1:
+ if (!n--) break;
+ regs->di = *args++;
+ case 0:
+ if (!n--) break;
+ default:
+ BUG();
+ }
+}
+
+#endif /* CONFIG_X86_32 */
+
+#endif /* _ASM_SYSCALL_H */
diff --git a/include/asm-x86/thread_info.h b/include/asm-x86/thread_info.h
index da0a675adf94..4cd5b7bdc8cc 100644
--- a/include/asm-x86/thread_info.h
+++ b/include/asm-x86/thread_info.h
@@ -71,6 +71,7 @@ struct thread_info {
* Warning: layout of LSW is hardcoded in entry.S
*/
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
#define TIF_SIGPENDING 2 /* signal pending */
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
@@ -93,6 +94,7 @@ struct thread_info {
#define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
@@ -133,7 +135,7 @@ struct thread_info {
/* Only used for 64 bit */
#define _TIF_DO_NOTIFY_MASK \
- (_TIF_SIGPENDING|_TIF_MCE_NOTIFY)
+ (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
/* flags to check in __switch_to() */
#define _TIF_WORK_CTXSW \