aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/syscalls.h32
-rw-r--r--arch/x86/kernel/entry_32.S69
-rw-r--r--arch/x86/kernel/entry_64.S49
-rw-r--r--arch/x86/kernel/ioport.c28
-rw-r--r--arch/x86/kernel/process.c70
-rw-r--r--arch/x86/kernel/process_32.c73
-rw-r--r--arch/x86/kernel/process_64.c35
-rw-r--r--arch/x86/kernel/signal.c12
-rw-r--r--arch/x86/kernel/vm86_32.c11
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c2
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 */
20asmlinkage long sys_ioperm(unsigned long, unsigned long, int); 20asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
21long sys_iopl(unsigned int, struct pt_regs *);
21 22
22/* kernel/process.c */ 23/* kernel/process.c */
23int sys_fork(struct pt_regs *); 24int sys_fork(struct pt_regs *);
24int sys_vfork(struct pt_regs *); 25int sys_vfork(struct pt_regs *);
26long sys_execve(char __user *, char __user * __user *,
27 char __user * __user *, struct pt_regs *);
28long sys_clone(unsigned long, unsigned long, void __user *,
29 void __user *, struct pt_regs *);
25 30
26/* kernel/ldt.c */ 31/* kernel/ldt.c */
27asmlinkage int sys_modify_ldt(int, void __user *, unsigned long); 32asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
28 33
29/* kernel/signal.c */ 34/* kernel/signal.c */
30long sys_rt_sigreturn(struct pt_regs *); 35long sys_rt_sigreturn(struct pt_regs *);
36long sys_sigaltstack(const stack_t __user *, stack_t __user *,
37 struct pt_regs *);
38
31 39
32/* kernel/tls.c */ 40/* kernel/tls.c */
33asmlinkage int sys_set_thread_area(struct user_desc __user *); 41asmlinkage 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 */
39long sys_iopl(struct pt_regs *);
40
41/* kernel/process_32.c */
42int sys_clone(struct pt_regs *);
43int sys_execve(struct pt_regs *);
44 46
45/* kernel/signal.c */ 47/* kernel/signal.c */
46asmlinkage int sys_sigsuspend(int, int, old_sigset_t); 48asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
47asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, 49asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
48 struct old_sigaction __user *); 50 struct old_sigaction __user *);
49int sys_sigaltstack(struct pt_regs *);
50unsigned long sys_sigreturn(struct pt_regs *); 51unsigned 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 *);
64asmlinkage int sys_olduname(struct oldold_utsname __user *); 65asmlinkage int sys_olduname(struct oldold_utsname __user *);
65 66
66/* kernel/vm86_32.c */ 67/* kernel/vm86_32.c */
67int sys_vm86old(struct pt_regs *); 68int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
68int sys_vm86(struct pt_regs *); 69int 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 */
74asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
75
76/* kernel/process_64.c */ 74/* kernel/process_64.c */
77asmlinkage long sys_clone(unsigned long, unsigned long,
78 void __user *, void __user *,
79 struct pt_regs *);
80asmlinkage long sys_execve(char __user *, char __user * __user *,
81 char __user * __user *,
82 struct pt_regs *);
83long sys_arch_prctl(int, unsigned long); 75long sys_arch_prctl(int, unsigned long);
84 76
85/* kernel/signal.c */
86asmlinkage 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 */
90struct new_utsname; 78struct 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; \
730ptregs_##name: \ 730ptregs_##name: \
731 leal 4(%esp),%eax; \ 731 leal 4(%esp),%eax; \
732 jmp sys_##name; 732 jmp sys_##name;
733 733
734PTREGSCALL(iopl) 734#define PTREGSCALL1(name) \
735PTREGSCALL(fork) 735 ALIGN; \
736PTREGSCALL(clone) 736ptregs_##name: \
737PTREGSCALL(vfork) 737 leal 4(%esp),%edx; \
738PTREGSCALL(execve) 738 movl (PT_EBX+4)(%esp),%eax; \
739PTREGSCALL(sigaltstack) 739 jmp sys_##name;
740PTREGSCALL(sigreturn) 740
741PTREGSCALL(rt_sigreturn) 741#define PTREGSCALL2(name) \
742PTREGSCALL(vm86) 742 ALIGN; \
743PTREGSCALL(vm86old) 743ptregs_##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; \
751ptregs_##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
761PTREGSCALL1(iopl)
762PTREGSCALL0(fork)
763PTREGSCALL0(vfork)
764PTREGSCALL3(execve)
765PTREGSCALL2(sigaltstack)
766PTREGSCALL0(sigreturn)
767PTREGSCALL0(rt_sigreturn)
768PTREGSCALL2(vm86)
769PTREGSCALL1(vm86old)
770
771/* Clone is an oddball. The 4th arg is in %edi */
772 ALIGN;
773ptregs_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)
1008ENTRY(kernel_thread_helper) 1047ENTRY(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/* 1169ENTRY(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 */
1178ENTRY(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
1208END(kernel_thread)
1209
1210ENTRY(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
1225END(child_rip) 1182END(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 */
106static int do_iopl(unsigned int level, struct pt_regs *regs) 106long 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 = &current->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
123long sys_iopl(struct pt_regs *regs)
124{
125 unsigned int level = regs->bx;
126 struct thread_struct *t = &current->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);
135out: 121
136 return rc; 122 return 0;
137}
138#else
139asmlinkage 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
258long
259sys_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 */
272extern void kernel_thread_helper(void);
273
274/*
275 * Create a kernel thread
276 */
277int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
278{
279 struct pt_regs regs;
280
281 memset(&regs, 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, &regs, 0, NULL, NULL);
300}
301EXPORT_SYMBOL(kernel_thread);
302
303/*
304 * sys_execve() executes a new program.
305 */
306long 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, &regs->sp, regs->bp); 180 show_trace(NULL, regs, &regs->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 */
188extern void kernel_thread_helper(void);
189
190/*
191 * Create a kernel thread
192 */
193int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
194{
195 struct pt_regs regs;
196
197 memset(&regs, 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, &regs, 0, NULL, NULL);
213}
214EXPORT_SYMBOL(kernel_thread);
215
216void release_thread(struct task_struct *dead_task) 183void 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
427int 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 */
445int 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);
463out:
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);
57DEFINE_PER_CPU(unsigned long, old_rsp); 57DEFINE_PER_CPU(unsigned long, old_rsp);
58static DEFINE_PER_CPU(unsigned char, is_idle); 58static DEFINE_PER_CPU(unsigned char, is_idle);
59 59
60unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
61
62static ATOMIC_NOTIFIER_HEAD(idle_notifier); 60static ATOMIC_NOTIFIER_HEAD(idle_notifier);
63 61
64void idle_notifier_register(struct notifier_block *n) 62void 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 */
514asmlinkage
515long 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
530void set_personality_64bit(void) 510void 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
544asmlinkage long
545sys_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
553unsigned long get_wchan(struct task_struct *p) 524unsigned 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 548long
549int 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 */
557asmlinkage long
558sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 549sys_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:
197static int do_vm86_irq_handling(int subfunction, int irqnumber); 197static int do_vm86_irq_handling(int subfunction, int irqnumber);
198static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk); 198static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
199 199
200int sys_vm86old(struct pt_regs *regs) 200int 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
230int sys_vm86(struct pt_regs *regs) 229int 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 @@
17EXPORT_SYMBOL(mcount); 17EXPORT_SYMBOL(mcount);
18#endif 18#endif
19 19
20EXPORT_SYMBOL(kernel_thread);
21
22EXPORT_SYMBOL(__get_user_1); 20EXPORT_SYMBOL(__get_user_1);
23EXPORT_SYMBOL(__get_user_2); 21EXPORT_SYMBOL(__get_user_2);
24EXPORT_SYMBOL(__get_user_4); 22EXPORT_SYMBOL(__get_user_4);