diff options
-rw-r--r-- | arch/x86/include/asm/syscalls.h | 32 | ||||
-rw-r--r-- | arch/x86/kernel/entry_32.S | 69 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 49 | ||||
-rw-r--r-- | arch/x86/kernel/ioport.c | 28 | ||||
-rw-r--r-- | arch/x86/kernel/process.c | 70 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 73 | ||||
-rw-r--r-- | arch/x86/kernel/process_64.c | 35 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 12 | ||||
-rw-r--r-- | arch/x86/kernel/vm86_32.c | 11 | ||||
-rw-r--r-- | arch/x86/kernel/x8664_ksyms_64.c | 2 |
10 files changed, 148 insertions, 233 deletions
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h index 372b76edd63f..b0ce78061708 100644 --- a/arch/x86/include/asm/syscalls.h +++ b/arch/x86/include/asm/syscalls.h | |||
@@ -18,16 +18,24 @@ | |||
18 | /* Common in X86_32 and X86_64 */ | 18 | /* Common in X86_32 and X86_64 */ |
19 | /* kernel/ioport.c */ | 19 | /* kernel/ioport.c */ |
20 | asmlinkage long sys_ioperm(unsigned long, unsigned long, int); | 20 | asmlinkage long sys_ioperm(unsigned long, unsigned long, int); |
21 | long sys_iopl(unsigned int, struct pt_regs *); | ||
21 | 22 | ||
22 | /* kernel/process.c */ | 23 | /* kernel/process.c */ |
23 | int sys_fork(struct pt_regs *); | 24 | int sys_fork(struct pt_regs *); |
24 | int sys_vfork(struct pt_regs *); | 25 | int sys_vfork(struct pt_regs *); |
26 | long sys_execve(char __user *, char __user * __user *, | ||
27 | char __user * __user *, struct pt_regs *); | ||
28 | long sys_clone(unsigned long, unsigned long, void __user *, | ||
29 | void __user *, struct pt_regs *); | ||
25 | 30 | ||
26 | /* kernel/ldt.c */ | 31 | /* kernel/ldt.c */ |
27 | asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); | 32 | asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); |
28 | 33 | ||
29 | /* kernel/signal.c */ | 34 | /* kernel/signal.c */ |
30 | long sys_rt_sigreturn(struct pt_regs *); | 35 | long sys_rt_sigreturn(struct pt_regs *); |
36 | long sys_sigaltstack(const stack_t __user *, stack_t __user *, | ||
37 | struct pt_regs *); | ||
38 | |||
31 | 39 | ||
32 | /* kernel/tls.c */ | 40 | /* kernel/tls.c */ |
33 | asmlinkage int sys_set_thread_area(struct user_desc __user *); | 41 | asmlinkage int sys_set_thread_area(struct user_desc __user *); |
@@ -35,18 +43,11 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *); | |||
35 | 43 | ||
36 | /* X86_32 only */ | 44 | /* X86_32 only */ |
37 | #ifdef CONFIG_X86_32 | 45 | #ifdef CONFIG_X86_32 |
38 | /* kernel/ioport.c */ | ||
39 | long sys_iopl(struct pt_regs *); | ||
40 | |||
41 | /* kernel/process_32.c */ | ||
42 | int sys_clone(struct pt_regs *); | ||
43 | int sys_execve(struct pt_regs *); | ||
44 | 46 | ||
45 | /* kernel/signal.c */ | 47 | /* kernel/signal.c */ |
46 | asmlinkage int sys_sigsuspend(int, int, old_sigset_t); | 48 | asmlinkage int sys_sigsuspend(int, int, old_sigset_t); |
47 | asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, | 49 | asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, |
48 | struct old_sigaction __user *); | 50 | struct old_sigaction __user *); |
49 | int sys_sigaltstack(struct pt_regs *); | ||
50 | unsigned long sys_sigreturn(struct pt_regs *); | 51 | unsigned long sys_sigreturn(struct pt_regs *); |
51 | 52 | ||
52 | /* kernel/sys_i386_32.c */ | 53 | /* kernel/sys_i386_32.c */ |
@@ -64,28 +65,15 @@ asmlinkage int sys_uname(struct old_utsname __user *); | |||
64 | asmlinkage int sys_olduname(struct oldold_utsname __user *); | 65 | asmlinkage int sys_olduname(struct oldold_utsname __user *); |
65 | 66 | ||
66 | /* kernel/vm86_32.c */ | 67 | /* kernel/vm86_32.c */ |
67 | int sys_vm86old(struct pt_regs *); | 68 | int sys_vm86old(struct vm86_struct __user *, struct pt_regs *); |
68 | int sys_vm86(struct pt_regs *); | 69 | int sys_vm86(unsigned long, unsigned long, struct pt_regs *); |
69 | 70 | ||
70 | #else /* CONFIG_X86_32 */ | 71 | #else /* CONFIG_X86_32 */ |
71 | 72 | ||
72 | /* X86_64 only */ | 73 | /* X86_64 only */ |
73 | /* kernel/ioport.c */ | ||
74 | asmlinkage long sys_iopl(unsigned int, struct pt_regs *); | ||
75 | |||
76 | /* kernel/process_64.c */ | 74 | /* kernel/process_64.c */ |
77 | asmlinkage long sys_clone(unsigned long, unsigned long, | ||
78 | void __user *, void __user *, | ||
79 | struct pt_regs *); | ||
80 | asmlinkage long sys_execve(char __user *, char __user * __user *, | ||
81 | char __user * __user *, | ||
82 | struct pt_regs *); | ||
83 | long sys_arch_prctl(int, unsigned long); | 75 | long sys_arch_prctl(int, unsigned long); |
84 | 76 | ||
85 | /* kernel/signal.c */ | ||
86 | asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *, | ||
87 | struct pt_regs *); | ||
88 | |||
89 | /* kernel/sys_x86_64.c */ | 77 | /* kernel/sys_x86_64.c */ |
90 | struct new_utsname; | 78 | struct new_utsname; |
91 | 79 | ||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 50b9c220e121..44a8e0dc6737 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -725,22 +725,61 @@ END(syscall_badsys) | |||
725 | /* | 725 | /* |
726 | * System calls that need a pt_regs pointer. | 726 | * System calls that need a pt_regs pointer. |
727 | */ | 727 | */ |
728 | #define PTREGSCALL(name) \ | 728 | #define PTREGSCALL0(name) \ |
729 | ALIGN; \ | 729 | ALIGN; \ |
730 | ptregs_##name: \ | 730 | ptregs_##name: \ |
731 | leal 4(%esp),%eax; \ | 731 | leal 4(%esp),%eax; \ |
732 | jmp sys_##name; | 732 | jmp sys_##name; |
733 | 733 | ||
734 | PTREGSCALL(iopl) | 734 | #define PTREGSCALL1(name) \ |
735 | PTREGSCALL(fork) | 735 | ALIGN; \ |
736 | PTREGSCALL(clone) | 736 | ptregs_##name: \ |
737 | PTREGSCALL(vfork) | 737 | leal 4(%esp),%edx; \ |
738 | PTREGSCALL(execve) | 738 | movl (PT_EBX+4)(%esp),%eax; \ |
739 | PTREGSCALL(sigaltstack) | 739 | jmp sys_##name; |
740 | PTREGSCALL(sigreturn) | 740 | |
741 | PTREGSCALL(rt_sigreturn) | 741 | #define PTREGSCALL2(name) \ |
742 | PTREGSCALL(vm86) | 742 | ALIGN; \ |
743 | PTREGSCALL(vm86old) | 743 | ptregs_##name: \ |
744 | leal 4(%esp),%ecx; \ | ||
745 | movl (PT_ECX+4)(%esp),%edx; \ | ||
746 | movl (PT_EBX+4)(%esp),%eax; \ | ||
747 | jmp sys_##name; | ||
748 | |||
749 | #define PTREGSCALL3(name) \ | ||
750 | ALIGN; \ | ||
751 | ptregs_##name: \ | ||
752 | leal 4(%esp),%eax; \ | ||
753 | pushl %eax; \ | ||
754 | movl PT_EDX(%eax),%ecx; \ | ||
755 | movl PT_ECX(%eax),%edx; \ | ||
756 | movl PT_EBX(%eax),%eax; \ | ||
757 | call sys_##name; \ | ||
758 | addl $4,%esp; \ | ||
759 | ret | ||
760 | |||
761 | PTREGSCALL1(iopl) | ||
762 | PTREGSCALL0(fork) | ||
763 | PTREGSCALL0(vfork) | ||
764 | PTREGSCALL3(execve) | ||
765 | PTREGSCALL2(sigaltstack) | ||
766 | PTREGSCALL0(sigreturn) | ||
767 | PTREGSCALL0(rt_sigreturn) | ||
768 | PTREGSCALL2(vm86) | ||
769 | PTREGSCALL1(vm86old) | ||
770 | |||
771 | /* Clone is an oddball. The 4th arg is in %edi */ | ||
772 | ALIGN; | ||
773 | ptregs_clone: | ||
774 | leal 4(%esp),%eax | ||
775 | pushl %eax | ||
776 | pushl PT_EDI(%eax) | ||
777 | movl PT_EDX(%eax),%ecx | ||
778 | movl PT_ECX(%eax),%edx | ||
779 | movl PT_EBX(%eax),%eax | ||
780 | call sys_clone | ||
781 | addl $8,%esp | ||
782 | ret | ||
744 | 783 | ||
745 | .macro FIXUP_ESPFIX_STACK | 784 | .macro FIXUP_ESPFIX_STACK |
746 | /* | 785 | /* |
@@ -1008,12 +1047,8 @@ END(spurious_interrupt_bug) | |||
1008 | ENTRY(kernel_thread_helper) | 1047 | ENTRY(kernel_thread_helper) |
1009 | pushl $0 # fake return address for unwinder | 1048 | pushl $0 # fake return address for unwinder |
1010 | CFI_STARTPROC | 1049 | CFI_STARTPROC |
1011 | movl %edx,%eax | 1050 | movl %edi,%eax |
1012 | push %edx | 1051 | call *%esi |
1013 | CFI_ADJUST_CFA_OFFSET 4 | ||
1014 | call *%ebx | ||
1015 | push %eax | ||
1016 | CFI_ADJUST_CFA_OFFSET 4 | ||
1017 | call do_exit | 1052 | call do_exit |
1018 | ud2 # padding for call trace | 1053 | ud2 # padding for call trace |
1019 | CFI_ENDPROC | 1054 | CFI_ENDPROC |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 63bca794c8f9..73d9b2c0e217 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1166,63 +1166,20 @@ bad_gs: | |||
1166 | jmp 2b | 1166 | jmp 2b |
1167 | .previous | 1167 | .previous |
1168 | 1168 | ||
1169 | /* | 1169 | ENTRY(kernel_thread_helper) |
1170 | * Create a kernel thread. | ||
1171 | * | ||
1172 | * C extern interface: | ||
1173 | * extern long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | ||
1174 | * | ||
1175 | * asm input arguments: | ||
1176 | * rdi: fn, rsi: arg, rdx: flags | ||
1177 | */ | ||
1178 | ENTRY(kernel_thread) | ||
1179 | CFI_STARTPROC | ||
1180 | FAKE_STACK_FRAME $child_rip | ||
1181 | SAVE_ALL | ||
1182 | |||
1183 | # rdi: flags, rsi: usp, rdx: will be &pt_regs | ||
1184 | movq %rdx,%rdi | ||
1185 | orq kernel_thread_flags(%rip),%rdi | ||
1186 | movq $-1, %rsi | ||
1187 | movq %rsp, %rdx | ||
1188 | |||
1189 | xorl %r8d,%r8d | ||
1190 | xorl %r9d,%r9d | ||
1191 | |||
1192 | # clone now | ||
1193 | call do_fork | ||
1194 | movq %rax,RAX(%rsp) | ||
1195 | xorl %edi,%edi | ||
1196 | |||
1197 | /* | ||
1198 | * It isn't worth to check for reschedule here, | ||
1199 | * so internally to the x86_64 port you can rely on kernel_thread() | ||
1200 | * not to reschedule the child before returning, this avoids the need | ||
1201 | * of hacks for example to fork off the per-CPU idle tasks. | ||
1202 | * [Hopefully no generic code relies on the reschedule -AK] | ||
1203 | */ | ||
1204 | RESTORE_ALL | ||
1205 | UNFAKE_STACK_FRAME | ||
1206 | ret | ||
1207 | CFI_ENDPROC | ||
1208 | END(kernel_thread) | ||
1209 | |||
1210 | ENTRY(child_rip) | ||
1211 | pushq $0 # fake return address | 1170 | pushq $0 # fake return address |
1212 | CFI_STARTPROC | 1171 | CFI_STARTPROC |
1213 | /* | 1172 | /* |
1214 | * Here we are in the child and the registers are set as they were | 1173 | * Here we are in the child and the registers are set as they were |
1215 | * at kernel_thread() invocation in the parent. | 1174 | * at kernel_thread() invocation in the parent. |
1216 | */ | 1175 | */ |
1217 | movq %rdi, %rax | 1176 | call *%rsi |
1218 | movq %rsi, %rdi | ||
1219 | call *%rax | ||
1220 | # exit | 1177 | # exit |
1221 | mov %eax, %edi | 1178 | mov %eax, %edi |
1222 | call do_exit | 1179 | call do_exit |
1223 | ud2 # padding for call trace | 1180 | ud2 # padding for call trace |
1224 | CFI_ENDPROC | 1181 | CFI_ENDPROC |
1225 | END(child_rip) | 1182 | END(kernel_thread_helper) |
1226 | 1183 | ||
1227 | /* | 1184 | /* |
1228 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. | 1185 | * execve(). This function needs to use IRET, not SYSRET, to set up all state properly. |
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 99c4d308f16b..8eec0ec59af2 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c | |||
@@ -103,9 +103,10 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) | |||
103 | * on system-call entry - see also fork() and the signal handling | 103 | * on system-call entry - see also fork() and the signal handling |
104 | * code. | 104 | * code. |
105 | */ | 105 | */ |
106 | static int do_iopl(unsigned int level, struct pt_regs *regs) | 106 | long sys_iopl(unsigned int level, struct pt_regs *regs) |
107 | { | 107 | { |
108 | unsigned int old = (regs->flags >> 12) & 3; | 108 | unsigned int old = (regs->flags >> 12) & 3; |
109 | struct thread_struct *t = ¤t->thread; | ||
109 | 110 | ||
110 | if (level > 3) | 111 | if (level > 3) |
111 | return -EINVAL; | 112 | return -EINVAL; |
@@ -115,29 +116,8 @@ static int do_iopl(unsigned int level, struct pt_regs *regs) | |||
115 | return -EPERM; | 116 | return -EPERM; |
116 | } | 117 | } |
117 | regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); | 118 | regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12); |
118 | |||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | #ifdef CONFIG_X86_32 | ||
123 | long sys_iopl(struct pt_regs *regs) | ||
124 | { | ||
125 | unsigned int level = regs->bx; | ||
126 | struct thread_struct *t = ¤t->thread; | ||
127 | int rc; | ||
128 | |||
129 | rc = do_iopl(level, regs); | ||
130 | if (rc < 0) | ||
131 | goto out; | ||
132 | |||
133 | t->iopl = level << 12; | 119 | t->iopl = level << 12; |
134 | set_iopl_mask(t->iopl); | 120 | set_iopl_mask(t->iopl); |
135 | out: | 121 | |
136 | return rc; | 122 | return 0; |
137 | } | ||
138 | #else | ||
139 | asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs) | ||
140 | { | ||
141 | return do_iopl(level, regs); | ||
142 | } | 123 | } |
143 | #endif | ||
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 7a7bd4e3ec49..98c2cdeb599e 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
@@ -255,6 +255,76 @@ int sys_vfork(struct pt_regs *regs) | |||
255 | NULL, NULL); | 255 | NULL, NULL); |
256 | } | 256 | } |
257 | 257 | ||
258 | long | ||
259 | sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
260 | void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) | ||
261 | { | ||
262 | if (!newsp) | ||
263 | newsp = regs->sp; | ||
264 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); | ||
265 | } | ||
266 | |||
267 | /* | ||
268 | * This gets run with %si containing the | ||
269 | * function to call, and %di containing | ||
270 | * the "args". | ||
271 | */ | ||
272 | extern void kernel_thread_helper(void); | ||
273 | |||
274 | /* | ||
275 | * Create a kernel thread | ||
276 | */ | ||
277 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
278 | { | ||
279 | struct pt_regs regs; | ||
280 | |||
281 | memset(®s, 0, sizeof(regs)); | ||
282 | |||
283 | regs.si = (unsigned long) fn; | ||
284 | regs.di = (unsigned long) arg; | ||
285 | |||
286 | #ifdef CONFIG_X86_32 | ||
287 | regs.ds = __USER_DS; | ||
288 | regs.es = __USER_DS; | ||
289 | regs.fs = __KERNEL_PERCPU; | ||
290 | regs.gs = __KERNEL_STACK_CANARY; | ||
291 | #endif | ||
292 | |||
293 | regs.orig_ax = -1; | ||
294 | regs.ip = (unsigned long) kernel_thread_helper; | ||
295 | regs.cs = __KERNEL_CS | get_kernel_rpl(); | ||
296 | regs.flags = X86_EFLAGS_IF | 0x2; | ||
297 | |||
298 | /* Ok, create the new process.. */ | ||
299 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
300 | } | ||
301 | EXPORT_SYMBOL(kernel_thread); | ||
302 | |||
303 | /* | ||
304 | * sys_execve() executes a new program. | ||
305 | */ | ||
306 | long sys_execve(char __user *name, char __user * __user *argv, | ||
307 | char __user * __user *envp, struct pt_regs *regs) | ||
308 | { | ||
309 | long error; | ||
310 | char *filename; | ||
311 | |||
312 | filename = getname(name); | ||
313 | error = PTR_ERR(filename); | ||
314 | if (IS_ERR(filename)) | ||
315 | return error; | ||
316 | error = do_execve(filename, argv, envp, regs); | ||
317 | |||
318 | #ifdef CONFIG_X86_32 | ||
319 | if (error == 0) { | ||
320 | /* Make sure we don't return using sysenter.. */ | ||
321 | set_thread_flag(TIF_IRET); | ||
322 | } | ||
323 | #endif | ||
324 | |||
325 | putname(filename); | ||
326 | return error; | ||
327 | } | ||
258 | 328 | ||
259 | /* | 329 | /* |
260 | * Idle related variables and functions | 330 | * Idle related variables and functions |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 120b88797a75..9c517b5858f0 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -180,39 +180,6 @@ void show_regs(struct pt_regs *regs) | |||
180 | show_trace(NULL, regs, ®s->sp, regs->bp); | 180 | show_trace(NULL, regs, ®s->sp, regs->bp); |
181 | } | 181 | } |
182 | 182 | ||
183 | /* | ||
184 | * This gets run with %bx containing the | ||
185 | * function to call, and %dx containing | ||
186 | * the "args". | ||
187 | */ | ||
188 | extern void kernel_thread_helper(void); | ||
189 | |||
190 | /* | ||
191 | * Create a kernel thread | ||
192 | */ | ||
193 | int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags) | ||
194 | { | ||
195 | struct pt_regs regs; | ||
196 | |||
197 | memset(®s, 0, sizeof(regs)); | ||
198 | |||
199 | regs.bx = (unsigned long) fn; | ||
200 | regs.dx = (unsigned long) arg; | ||
201 | |||
202 | regs.ds = __USER_DS; | ||
203 | regs.es = __USER_DS; | ||
204 | regs.fs = __KERNEL_PERCPU; | ||
205 | regs.gs = __KERNEL_STACK_CANARY; | ||
206 | regs.orig_ax = -1; | ||
207 | regs.ip = (unsigned long) kernel_thread_helper; | ||
208 | regs.cs = __KERNEL_CS | get_kernel_rpl(); | ||
209 | regs.flags = X86_EFLAGS_IF | X86_EFLAGS_SF | X86_EFLAGS_PF | 0x2; | ||
210 | |||
211 | /* Ok, create the new process.. */ | ||
212 | return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, NULL); | ||
213 | } | ||
214 | EXPORT_SYMBOL(kernel_thread); | ||
215 | |||
216 | void release_thread(struct task_struct *dead_task) | 183 | void release_thread(struct task_struct *dead_task) |
217 | { | 184 | { |
218 | BUG_ON(dead_task->mm); | 185 | BUG_ON(dead_task->mm); |
@@ -424,46 +391,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
424 | return prev_p; | 391 | return prev_p; |
425 | } | 392 | } |
426 | 393 | ||
427 | int sys_clone(struct pt_regs *regs) | ||
428 | { | ||
429 | unsigned long clone_flags; | ||
430 | unsigned long newsp; | ||
431 | int __user *parent_tidptr, *child_tidptr; | ||
432 | |||
433 | clone_flags = regs->bx; | ||
434 | newsp = regs->cx; | ||
435 | parent_tidptr = (int __user *)regs->dx; | ||
436 | child_tidptr = (int __user *)regs->di; | ||
437 | if (!newsp) | ||
438 | newsp = regs->sp; | ||
439 | return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); | ||
440 | } | ||
441 | |||
442 | /* | ||
443 | * sys_execve() executes a new program. | ||
444 | */ | ||
445 | int sys_execve(struct pt_regs *regs) | ||
446 | { | ||
447 | int error; | ||
448 | char *filename; | ||
449 | |||
450 | filename = getname((char __user *) regs->bx); | ||
451 | error = PTR_ERR(filename); | ||
452 | if (IS_ERR(filename)) | ||
453 | goto out; | ||
454 | error = do_execve(filename, | ||
455 | (char __user * __user *) regs->cx, | ||
456 | (char __user * __user *) regs->dx, | ||
457 | regs); | ||
458 | if (error == 0) { | ||
459 | /* Make sure we don't return using sysenter.. */ | ||
460 | set_thread_flag(TIF_IRET); | ||
461 | } | ||
462 | putname(filename); | ||
463 | out: | ||
464 | return error; | ||
465 | } | ||
466 | |||
467 | #define top_esp (THREAD_SIZE - sizeof(unsigned long)) | 394 | #define top_esp (THREAD_SIZE - sizeof(unsigned long)) |
468 | #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) | 395 | #define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long)) |
469 | 396 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index e5ab0cd0ef36..52fbd0c60198 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -57,8 +57,6 @@ asmlinkage extern void ret_from_fork(void); | |||
57 | DEFINE_PER_CPU(unsigned long, old_rsp); | 57 | DEFINE_PER_CPU(unsigned long, old_rsp); |
58 | static DEFINE_PER_CPU(unsigned char, is_idle); | 58 | static DEFINE_PER_CPU(unsigned char, is_idle); |
59 | 59 | ||
60 | unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED; | ||
61 | |||
62 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); | 60 | static ATOMIC_NOTIFIER_HEAD(idle_notifier); |
63 | 61 | ||
64 | void idle_notifier_register(struct notifier_block *n) | 62 | void idle_notifier_register(struct notifier_block *n) |
@@ -273,8 +271,9 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
273 | *childregs = *regs; | 271 | *childregs = *regs; |
274 | 272 | ||
275 | childregs->ax = 0; | 273 | childregs->ax = 0; |
276 | childregs->sp = sp; | 274 | if (user_mode(regs)) |
277 | if (sp == ~0UL) | 275 | childregs->sp = sp; |
276 | else | ||
278 | childregs->sp = (unsigned long)childregs; | 277 | childregs->sp = (unsigned long)childregs; |
279 | 278 | ||
280 | p->thread.sp = (unsigned long) childregs; | 279 | p->thread.sp = (unsigned long) childregs; |
@@ -508,25 +507,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
508 | return prev_p; | 507 | return prev_p; |
509 | } | 508 | } |
510 | 509 | ||
511 | /* | ||
512 | * sys_execve() executes a new program. | ||
513 | */ | ||
514 | asmlinkage | ||
515 | long sys_execve(char __user *name, char __user * __user *argv, | ||
516 | char __user * __user *envp, struct pt_regs *regs) | ||
517 | { | ||
518 | long error; | ||
519 | char *filename; | ||
520 | |||
521 | filename = getname(name); | ||
522 | error = PTR_ERR(filename); | ||
523 | if (IS_ERR(filename)) | ||
524 | return error; | ||
525 | error = do_execve(filename, argv, envp, regs); | ||
526 | putname(filename); | ||
527 | return error; | ||
528 | } | ||
529 | |||
530 | void set_personality_64bit(void) | 510 | void set_personality_64bit(void) |
531 | { | 511 | { |
532 | /* inherit personality from parent */ | 512 | /* inherit personality from parent */ |
@@ -541,15 +521,6 @@ void set_personality_64bit(void) | |||
541 | current->personality &= ~READ_IMPLIES_EXEC; | 521 | current->personality &= ~READ_IMPLIES_EXEC; |
542 | } | 522 | } |
543 | 523 | ||
544 | asmlinkage long | ||
545 | sys_clone(unsigned long clone_flags, unsigned long newsp, | ||
546 | void __user *parent_tid, void __user *child_tid, struct pt_regs *regs) | ||
547 | { | ||
548 | if (!newsp) | ||
549 | newsp = regs->sp; | ||
550 | return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); | ||
551 | } | ||
552 | |||
553 | unsigned long get_wchan(struct task_struct *p) | 524 | unsigned long get_wchan(struct task_struct *p) |
554 | { | 525 | { |
555 | unsigned long stack; | 526 | unsigned long stack; |
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c index 74fe6d86dc5d..4fd173cd8e57 100644 --- a/arch/x86/kernel/signal.c +++ b/arch/x86/kernel/signal.c | |||
@@ -545,22 +545,12 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
545 | } | 545 | } |
546 | #endif /* CONFIG_X86_32 */ | 546 | #endif /* CONFIG_X86_32 */ |
547 | 547 | ||
548 | #ifdef CONFIG_X86_32 | 548 | long |
549 | int sys_sigaltstack(struct pt_regs *regs) | ||
550 | { | ||
551 | const stack_t __user *uss = (const stack_t __user *)regs->bx; | ||
552 | stack_t __user *uoss = (stack_t __user *)regs->cx; | ||
553 | |||
554 | return do_sigaltstack(uss, uoss, regs->sp); | ||
555 | } | ||
556 | #else /* !CONFIG_X86_32 */ | ||
557 | asmlinkage long | ||
558 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 549 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, |
559 | struct pt_regs *regs) | 550 | struct pt_regs *regs) |
560 | { | 551 | { |
561 | return do_sigaltstack(uss, uoss, regs->sp); | 552 | return do_sigaltstack(uss, uoss, regs->sp); |
562 | } | 553 | } |
563 | #endif /* CONFIG_X86_32 */ | ||
564 | 554 | ||
565 | /* | 555 | /* |
566 | * Do a signal return; undo the signal stack. | 556 | * Do a signal return; undo the signal stack. |
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c index 9c4e62539058..5ffb5622f793 100644 --- a/arch/x86/kernel/vm86_32.c +++ b/arch/x86/kernel/vm86_32.c | |||
@@ -197,9 +197,8 @@ out: | |||
197 | static int do_vm86_irq_handling(int subfunction, int irqnumber); | 197 | static int do_vm86_irq_handling(int subfunction, int irqnumber); |
198 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); | 198 | static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); |
199 | 199 | ||
200 | int sys_vm86old(struct pt_regs *regs) | 200 | int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs) |
201 | { | 201 | { |
202 | struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx; | ||
203 | struct kernel_vm86_struct info; /* declare this _on top_, | 202 | struct kernel_vm86_struct info; /* declare this _on top_, |
204 | * this avoids wasting of stack space. | 203 | * this avoids wasting of stack space. |
205 | * This remains on the stack until we | 204 | * This remains on the stack until we |
@@ -227,7 +226,7 @@ out: | |||
227 | } | 226 | } |
228 | 227 | ||
229 | 228 | ||
230 | int sys_vm86(struct pt_regs *regs) | 229 | int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs) |
231 | { | 230 | { |
232 | struct kernel_vm86_struct info; /* declare this _on top_, | 231 | struct kernel_vm86_struct info; /* declare this _on top_, |
233 | * this avoids wasting of stack space. | 232 | * this avoids wasting of stack space. |
@@ -239,12 +238,12 @@ int sys_vm86(struct pt_regs *regs) | |||
239 | struct vm86plus_struct __user *v86; | 238 | struct vm86plus_struct __user *v86; |
240 | 239 | ||
241 | tsk = current; | 240 | tsk = current; |
242 | switch (regs->bx) { | 241 | switch (cmd) { |
243 | case VM86_REQUEST_IRQ: | 242 | case VM86_REQUEST_IRQ: |
244 | case VM86_FREE_IRQ: | 243 | case VM86_FREE_IRQ: |
245 | case VM86_GET_IRQ_BITS: | 244 | case VM86_GET_IRQ_BITS: |
246 | case VM86_GET_AND_RESET_IRQ: | 245 | case VM86_GET_AND_RESET_IRQ: |
247 | ret = do_vm86_irq_handling(regs->bx, (int)regs->cx); | 246 | ret = do_vm86_irq_handling(cmd, (int)arg); |
248 | goto out; | 247 | goto out; |
249 | case VM86_PLUS_INSTALL_CHECK: | 248 | case VM86_PLUS_INSTALL_CHECK: |
250 | /* | 249 | /* |
@@ -261,7 +260,7 @@ int sys_vm86(struct pt_regs *regs) | |||
261 | ret = -EPERM; | 260 | ret = -EPERM; |
262 | if (tsk->thread.saved_sp0) | 261 | if (tsk->thread.saved_sp0) |
263 | goto out; | 262 | goto out; |
264 | v86 = (struct vm86plus_struct __user *)regs->cx; | 263 | v86 = (struct vm86plus_struct __user *)arg; |
265 | tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, | 264 | tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, |
266 | offsetof(struct kernel_vm86_struct, regs32) - | 265 | offsetof(struct kernel_vm86_struct, regs32) - |
267 | sizeof(info.regs)); | 266 | sizeof(info.regs)); |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index a1029769b6f2..9fafaf83b3b8 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -17,8 +17,6 @@ | |||
17 | EXPORT_SYMBOL(mcount); | 17 | EXPORT_SYMBOL(mcount); |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | EXPORT_SYMBOL(kernel_thread); | ||
21 | |||
22 | EXPORT_SYMBOL(__get_user_1); | 20 | EXPORT_SYMBOL(__get_user_1); |
23 | EXPORT_SYMBOL(__get_user_2); | 21 | EXPORT_SYMBOL(__get_user_2); |
24 | EXPORT_SYMBOL(__get_user_4); | 22 | EXPORT_SYMBOL(__get_user_4); |