aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/signal_32.c
diff options
context:
space:
mode:
authorHiroshi Shimamoto <h-shimamoto@ct.jp.nec.com>2008-11-24 21:21:37 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-25 23:11:51 -0500
commit2601657d223d82053d4e1fe1063091401e6b860a (patch)
tree04302bbebc28b0fc63a9e488dfcaeefff62a814f /arch/x86/kernel/signal_32.c
parent2456d738ef051f85170bf018faef63f83fa84eb5 (diff)
x86: signal: move {setup|restore}_sigcontext()
Impact: cleanup Move {setup|restore}_sigcontext() declaration onto head of file. Signed-off-by: Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/signal_32.c')
-rw-r--r--arch/x86/kernel/signal_32.c271
1 files changed, 136 insertions, 135 deletions
diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c
index f7dd6c44c042..b3f30d2a2178 100644
--- a/arch/x86/kernel/signal_32.c
+++ b/arch/x86/kernel/signal_32.c
@@ -70,6 +70,142 @@ static const struct {
70 0 70 0
71}; 71};
72 72
73#define COPY(x) { \
74 err |= __get_user(regs->x, &sc->x); \
75}
76
77#define COPY_SEG(seg) { \
78 unsigned short tmp; \
79 err |= __get_user(tmp, &sc->seg); \
80 regs->seg = tmp; \
81}
82
83#define COPY_SEG_CPL3(seg) { \
84 unsigned short tmp; \
85 err |= __get_user(tmp, &sc->seg); \
86 regs->seg = tmp | 3; \
87}
88
89#define GET_SEG(seg) { \
90 unsigned short tmp; \
91 err |= __get_user(tmp, &sc->seg); \
92 loadsegment(seg, tmp); \
93}
94
95static int
96restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
97 unsigned long *pax)
98{
99 void __user *buf;
100 unsigned int tmpflags;
101 unsigned int err = 0;
102
103 /* Always make any pending restarted system calls return -EINTR */
104 current_thread_info()->restart_block.fn = do_no_restart_syscall;
105
106#ifdef CONFIG_X86_32
107 GET_SEG(gs);
108 COPY_SEG(fs);
109 COPY_SEG(es);
110 COPY_SEG(ds);
111#endif /* CONFIG_X86_32 */
112
113 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
114 COPY(dx); COPY(cx); COPY(ip);
115
116#ifdef CONFIG_X86_64
117 COPY(r8);
118 COPY(r9);
119 COPY(r10);
120 COPY(r11);
121 COPY(r12);
122 COPY(r13);
123 COPY(r14);
124 COPY(r15);
125#endif /* CONFIG_X86_64 */
126
127#ifdef CONFIG_X86_32
128 COPY_SEG_CPL3(cs);
129 COPY_SEG_CPL3(ss);
130#else /* !CONFIG_X86_32 */
131 /* Kernel saves and restores only the CS segment register on signals,
132 * which is the bare minimum needed to allow mixed 32/64-bit code.
133 * App's signal handler can save/restore other segments if needed. */
134 COPY_SEG_CPL3(cs);
135#endif /* CONFIG_X86_32 */
136
137 err |= __get_user(tmpflags, &sc->flags);
138 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
139 regs->orig_ax = -1; /* disable syscall checks */
140
141 err |= __get_user(buf, &sc->fpstate);
142 err |= restore_i387_xstate(buf);
143
144 err |= __get_user(*pax, &sc->ax);
145 return err;
146}
147
148static int
149setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
150 struct pt_regs *regs, unsigned long mask)
151{
152 int err = 0;
153
154#ifdef CONFIG_X86_32
155 {
156 unsigned int tmp;
157
158 savesegment(gs, tmp);
159 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
160 }
161 err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
162 err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
163 err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
164#endif /* CONFIG_X86_32 */
165
166 err |= __put_user(regs->di, &sc->di);
167 err |= __put_user(regs->si, &sc->si);
168 err |= __put_user(regs->bp, &sc->bp);
169 err |= __put_user(regs->sp, &sc->sp);
170 err |= __put_user(regs->bx, &sc->bx);
171 err |= __put_user(regs->dx, &sc->dx);
172 err |= __put_user(regs->cx, &sc->cx);
173 err |= __put_user(regs->ax, &sc->ax);
174#ifdef CONFIG_X86_64
175 err |= __put_user(regs->r8, &sc->r8);
176 err |= __put_user(regs->r9, &sc->r9);
177 err |= __put_user(regs->r10, &sc->r10);
178 err |= __put_user(regs->r11, &sc->r11);
179 err |= __put_user(regs->r12, &sc->r12);
180 err |= __put_user(regs->r13, &sc->r13);
181 err |= __put_user(regs->r14, &sc->r14);
182 err |= __put_user(regs->r15, &sc->r15);
183#endif /* CONFIG_X86_64 */
184
185 err |= __put_user(current->thread.trap_no, &sc->trapno);
186 err |= __put_user(current->thread.error_code, &sc->err);
187 err |= __put_user(regs->ip, &sc->ip);
188#ifdef CONFIG_X86_32
189 err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
190 err |= __put_user(regs->flags, &sc->flags);
191 err |= __put_user(regs->sp, &sc->sp_at_signal);
192 err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
193#else /* !CONFIG_X86_32 */
194 err |= __put_user(regs->flags, &sc->flags);
195 err |= __put_user(regs->cs, &sc->cs);
196 err |= __put_user(0, &sc->gs);
197 err |= __put_user(0, &sc->fs);
198#endif /* CONFIG_X86_32 */
199
200 err |= __put_user(fpstate, &sc->fpstate);
201
202 /* non-iBCS2 extensions.. */
203 err |= __put_user(mask, &sc->oldmask);
204 err |= __put_user(current->thread.cr2, &sc->cr2);
205
206 return err;
207}
208
73/* 209/*
74 * Atomically swap in the new signal mask, and wait for a signal. 210 * Atomically swap in the new signal mask, and wait for a signal.
75 */ 211 */
@@ -147,84 +283,9 @@ sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
147} 283}
148#endif /* CONFIG_X86_32 */ 284#endif /* CONFIG_X86_32 */
149 285
150#define COPY(x) { \
151 err |= __get_user(regs->x, &sc->x); \
152}
153
154#define COPY_SEG(seg) { \
155 unsigned short tmp; \
156 err |= __get_user(tmp, &sc->seg); \
157 regs->seg = tmp; \
158}
159
160#define COPY_SEG_CPL3(seg) { \
161 unsigned short tmp; \
162 err |= __get_user(tmp, &sc->seg); \
163 regs->seg = tmp | 3; \
164}
165
166#define GET_SEG(seg) { \
167 unsigned short tmp; \
168 err |= __get_user(tmp, &sc->seg); \
169 loadsegment(seg, tmp); \
170}
171
172/* 286/*
173 * Do a signal return; undo the signal stack. 287 * Do a signal return; undo the signal stack.
174 */ 288 */
175static int
176restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
177 unsigned long *pax)
178{
179 void __user *buf;
180 unsigned int tmpflags;
181 unsigned int err = 0;
182
183 /* Always make any pending restarted system calls return -EINTR */
184 current_thread_info()->restart_block.fn = do_no_restart_syscall;
185
186#ifdef CONFIG_X86_32
187 GET_SEG(gs);
188 COPY_SEG(fs);
189 COPY_SEG(es);
190 COPY_SEG(ds);
191#endif /* CONFIG_X86_32 */
192
193 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
194 COPY(dx); COPY(cx); COPY(ip);
195
196#ifdef CONFIG_X86_64
197 COPY(r8);
198 COPY(r9);
199 COPY(r10);
200 COPY(r11);
201 COPY(r12);
202 COPY(r13);
203 COPY(r14);
204 COPY(r15);
205#endif /* CONFIG_X86_64 */
206
207#ifdef CONFIG_X86_32
208 COPY_SEG_CPL3(cs);
209 COPY_SEG_CPL3(ss);
210#else /* !CONFIG_X86_32 */
211 /* Kernel saves and restores only the CS segment register on signals,
212 * which is the bare minimum needed to allow mixed 32/64-bit code.
213 * App's signal handler can save/restore other segments if needed. */
214 COPY_SEG_CPL3(cs);
215#endif /* CONFIG_X86_32 */
216
217 err |= __get_user(tmpflags, &sc->flags);
218 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
219 regs->orig_ax = -1; /* disable syscall checks */
220
221 err |= __get_user(buf, &sc->fpstate);
222 err |= restore_i387_xstate(buf);
223
224 err |= __get_user(*pax, &sc->ax);
225 return err;
226}
227
228asmlinkage unsigned long sys_sigreturn(unsigned long __unused) 289asmlinkage unsigned long sys_sigreturn(unsigned long __unused)
229{ 290{
230 struct sigframe __user *frame; 291 struct sigframe __user *frame;
@@ -316,66 +377,6 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
316/* 377/*
317 * Set up a signal frame. 378 * Set up a signal frame.
318 */ 379 */
319static int
320setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
321 struct pt_regs *regs, unsigned long mask)
322{
323 int err = 0;
324
325#ifdef CONFIG_X86_32
326 {
327 unsigned int tmp;
328
329 savesegment(gs, tmp);
330 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
331 }
332 err |= __put_user(regs->fs, (unsigned int __user *)&sc->fs);
333 err |= __put_user(regs->es, (unsigned int __user *)&sc->es);
334 err |= __put_user(regs->ds, (unsigned int __user *)&sc->ds);
335#endif /* CONFIG_X86_32 */
336
337 err |= __put_user(regs->di, &sc->di);
338 err |= __put_user(regs->si, &sc->si);
339 err |= __put_user(regs->bp, &sc->bp);
340 err |= __put_user(regs->sp, &sc->sp);
341 err |= __put_user(regs->bx, &sc->bx);
342 err |= __put_user(regs->dx, &sc->dx);
343 err |= __put_user(regs->cx, &sc->cx);
344 err |= __put_user(regs->ax, &sc->ax);
345#ifdef CONFIG_X86_64
346 err |= __put_user(regs->r8, &sc->r8);
347 err |= __put_user(regs->r9, &sc->r9);
348 err |= __put_user(regs->r10, &sc->r10);
349 err |= __put_user(regs->r11, &sc->r11);
350 err |= __put_user(regs->r12, &sc->r12);
351 err |= __put_user(regs->r13, &sc->r13);
352 err |= __put_user(regs->r14, &sc->r14);
353 err |= __put_user(regs->r15, &sc->r15);
354#endif /* CONFIG_X86_64 */
355
356 err |= __put_user(current->thread.trap_no, &sc->trapno);
357 err |= __put_user(current->thread.error_code, &sc->err);
358 err |= __put_user(regs->ip, &sc->ip);
359#ifdef CONFIG_X86_32
360 err |= __put_user(regs->cs, (unsigned int __user *)&sc->cs);
361 err |= __put_user(regs->flags, &sc->flags);
362 err |= __put_user(regs->sp, &sc->sp_at_signal);
363 err |= __put_user(regs->ss, (unsigned int __user *)&sc->ss);
364#else /* !CONFIG_X86_32 */
365 err |= __put_user(regs->flags, &sc->flags);
366 err |= __put_user(regs->cs, &sc->cs);
367 err |= __put_user(0, &sc->gs);
368 err |= __put_user(0, &sc->fs);
369#endif /* CONFIG_X86_32 */
370
371 err |= __put_user(fpstate, &sc->fpstate);
372
373 /* non-iBCS2 extensions.. */
374 err |= __put_user(mask, &sc->oldmask);
375 err |= __put_user(current->thread.cr2, &sc->cr2);
376
377 return err;
378}
379 380
380/* 381/*
381 * Determine which stack to use.. 382 * Determine which stack to use..