diff options
author | Hiroshi Shimamoto <h-shimamoto@ct.jp.nec.com> | 2008-11-24 21:21:37 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-11-25 23:11:51 -0500 |
commit | 2601657d223d82053d4e1fe1063091401e6b860a (patch) | |
tree | 04302bbebc28b0fc63a9e488dfcaeefff62a814f /arch/x86/kernel/signal_32.c | |
parent | 2456d738ef051f85170bf018faef63f83fa84eb5 (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.c | 271 |
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 | |||
95 | static int | ||
96 | restore_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 | |||
148 | static int | ||
149 | setup_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 | */ |
175 | static int | ||
176 | restore_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 | |||
228 | asmlinkage unsigned long sys_sigreturn(unsigned long __unused) | 289 | asmlinkage 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 | */ |
319 | static int | ||
320 | setup_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.. |