aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-x86
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-28 11:03:43 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-28 11:03:43 -0400
commit71998e83c520c7a91b254dc9705baeedbee0d44f (patch)
treebe5bd54e975c416d3b607c91f6099e45cd0cd432 /include/asm-x86
parentc9272c4f9fbe2087beb3392f526dc5b19efaa56b (diff)
parent99bbc4b1e677ac695431e8d9c8e710ef391c567f (diff)
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/asm-x86')
-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)
213 return regs->bp; 213 return regs->bp;
214} 214}
215 215
216static inline unsigned long user_stack_pointer(struct pt_regs *regs)
217{
218 return regs->sp;
219}
220
216/* 221/*
217 * These are defined as per linux/ptrace.h, which see. 222 * These are defined as per linux/ptrace.h, which see.
218 */ 223 */
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 @@
1/*
2 * Access to user system call parameters and results
3 *
4 * Copyright (C) 2008 Red Hat, Inc. All rights reserved.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU General Public License v.2.
9 *
10 * See asm-generic/syscall.h for descriptions of what we must do here.
11 */
12
13#ifndef _ASM_SYSCALL_H
14#define _ASM_SYSCALL_H 1
15
16#include <linux/sched.h>
17
18static inline long syscall_get_nr(struct task_struct *task,
19 struct pt_regs *regs)
20{
21 /*
22 * We always sign-extend a -1 value being set here,
23 * so this is always either -1L or a syscall number.
24 */
25 return regs->orig_ax;
26}
27
28static inline void syscall_rollback(struct task_struct *task,
29 struct pt_regs *regs)
30{
31 regs->ax = regs->orig_ax;
32}
33
34static inline long syscall_get_error(struct task_struct *task,
35 struct pt_regs *regs)
36{
37 unsigned long error = regs->ax;
38#ifdef CONFIG_IA32_EMULATION
39 /*
40 * TS_COMPAT is set for 32-bit syscall entries and then
41 * remains set until we return to user mode.
42 */
43 if (task_thread_info(task)->status & TS_COMPAT)
44 /*
45 * Sign-extend the value so (int)-EFOO becomes (long)-EFOO
46 * and will match correctly in comparisons.
47 */
48 error = (long) (int) error;
49#endif
50 return error >= -4095L ? error : 0;
51}
52
53static inline long syscall_get_return_value(struct task_struct *task,
54 struct pt_regs *regs)
55{
56 return regs->ax;
57}
58
59static inline void syscall_set_return_value(struct task_struct *task,
60 struct pt_regs *regs,
61 int error, long val)
62{
63 regs->ax = (long) error ?: val;
64}
65
66#ifdef CONFIG_X86_32
67
68static inline void syscall_get_arguments(struct task_struct *task,
69 struct pt_regs *regs,
70 unsigned int i, unsigned int n,
71 unsigned long *args)
72{
73 BUG_ON(i + n > 6);
74 memcpy(args, &regs->bx + i, n * sizeof(args[0]));
75}
76
77static inline void syscall_set_arguments(struct task_struct *task,
78 struct pt_regs *regs,
79 unsigned int i, unsigned int n,
80 const unsigned long *args)
81{
82 BUG_ON(i + n > 6);
83 memcpy(&regs->bx + i, args, n * sizeof(args[0]));
84}
85
86#else /* CONFIG_X86_64 */
87
88static inline void syscall_get_arguments(struct task_struct *task,
89 struct pt_regs *regs,
90 unsigned int i, unsigned int n,
91 unsigned long *args)
92{
93# ifdef CONFIG_IA32_EMULATION
94 if (task_thread_info(task)->status & TS_COMPAT)
95 switch (i + n) {
96 case 6:
97 if (!n--) break;
98 *args++ = regs->bp;
99 case 5:
100 if (!n--) break;
101 *args++ = regs->di;
102 case 4:
103 if (!n--) break;
104 *args++ = regs->si;
105 case 3:
106 if (!n--) break;
107 *args++ = regs->dx;
108 case 2:
109 if (!n--) break;
110 *args++ = regs->cx;
111 case 1:
112 if (!n--) break;
113 *args++ = regs->bx;
114 case 0:
115 if (!n--) break;
116 default:
117 BUG();
118 break;
119 }
120 else
121# endif
122 switch (i + n) {
123 case 6:
124 if (!n--) break;
125 *args++ = regs->r9;
126 case 5:
127 if (!n--) break;
128 *args++ = regs->r8;
129 case 4:
130 if (!n--) break;
131 *args++ = regs->r10;
132 case 3:
133 if (!n--) break;
134 *args++ = regs->dx;
135 case 2:
136 if (!n--) break;
137 *args++ = regs->si;
138 case 1:
139 if (!n--) break;
140 *args++ = regs->di;
141 case 0:
142 if (!n--) break;
143 default:
144 BUG();
145 break;
146 }
147}
148
149static inline void syscall_set_arguments(struct task_struct *task,
150 struct pt_regs *regs,
151 unsigned int i, unsigned int n,
152 const unsigned long *args)
153{
154# ifdef CONFIG_IA32_EMULATION
155 if (task_thread_info(task)->status & TS_COMPAT)
156 switch (i + n) {
157 case 6:
158 if (!n--) break;
159 regs->bp = *args++;
160 case 5:
161 if (!n--) break;
162 regs->di = *args++;
163 case 4:
164 if (!n--) break;
165 regs->si = *args++;
166 case 3:
167 if (!n--) break;
168 regs->dx = *args++;
169 case 2:
170 if (!n--) break;
171 regs->cx = *args++;
172 case 1:
173 if (!n--) break;
174 regs->bx = *args++;
175 case 0:
176 if (!n--) break;
177 default:
178 BUG();
179 }
180 else
181# endif
182 switch (i + n) {
183 case 6:
184 if (!n--) break;
185 regs->r9 = *args++;
186 case 5:
187 if (!n--) break;
188 regs->r8 = *args++;
189 case 4:
190 if (!n--) break;
191 regs->r10 = *args++;
192 case 3:
193 if (!n--) break;
194 regs->dx = *args++;
195 case 2:
196 if (!n--) break;
197 regs->si = *args++;
198 case 1:
199 if (!n--) break;
200 regs->di = *args++;
201 case 0:
202 if (!n--) break;
203 default:
204 BUG();
205 }
206}
207
208#endif /* CONFIG_X86_32 */
209
210#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 {
71 * Warning: layout of LSW is hardcoded in entry.S 71 * Warning: layout of LSW is hardcoded in entry.S
72 */ 72 */
73#define TIF_SYSCALL_TRACE 0 /* syscall trace active */ 73#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
74#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
74#define TIF_SIGPENDING 2 /* signal pending */ 75#define TIF_SIGPENDING 2 /* signal pending */
75#define TIF_NEED_RESCHED 3 /* rescheduling necessary */ 76#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
76#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ 77#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
@@ -93,6 +94,7 @@ struct thread_info {
93#define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */ 94#define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */
94 95
95#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) 96#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
97#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
96#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 98#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
97#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) 99#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
98#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) 100#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
@@ -133,7 +135,7 @@ struct thread_info {
133 135
134/* Only used for 64 bit */ 136/* Only used for 64 bit */
135#define _TIF_DO_NOTIFY_MASK \ 137#define _TIF_DO_NOTIFY_MASK \
136 (_TIF_SIGPENDING|_TIF_MCE_NOTIFY) 138 (_TIF_SIGPENDING|_TIF_MCE_NOTIFY|_TIF_NOTIFY_RESUME)
137 139
138/* flags to check in __switch_to() */ 140/* flags to check in __switch_to() */
139#define _TIF_WORK_CTXSW \ 141#define _TIF_WORK_CTXSW \