aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/linkage.h7
-rw-r--r--arch/x86/include/asm/syscalls.h25
-rw-r--r--arch/x86/kernel/ioport.c3
-rw-r--r--arch/x86/kernel/process_32.c27
-rw-r--r--arch/x86/kernel/signal.c21
-rw-r--r--arch/x86/kernel/vm86_32.c11
6 files changed, 49 insertions, 45 deletions
diff --git a/arch/x86/include/asm/linkage.h b/arch/x86/include/asm/linkage.h
index 2fd5926fb97d..5d98d0b68ffc 100644
--- a/arch/x86/include/asm/linkage.h
+++ b/arch/x86/include/asm/linkage.h
@@ -18,13 +18,6 @@
18#define asmregparm __attribute__((regparm(3))) 18#define asmregparm __attribute__((regparm(3)))
19 19
20/* 20/*
21 * For syscalls that need a pointer to the pt_regs struct (ie. fork).
22 * The regs pointer is passed in %eax as the first argument. The
23 * remaining function arguments remain on the stack.
24 */
25#define ptregscall __attribute__((regparm(1)))
26
27/*
28 * Make sure the compiler doesn't do anything stupid with the 21 * Make sure the compiler doesn't do anything stupid with the
29 * arguments on the stack - they are owned by the *caller*, not 22 * arguments on the stack - they are owned by the *caller*, not
30 * the callee. This just fools gcc into not spilling into them, 23 * the callee. This just fools gcc into not spilling into them,
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 617295255a17..77bb31a88ba8 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -29,26 +29,21 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
29/* X86_32 only */ 29/* X86_32 only */
30#ifdef CONFIG_X86_32 30#ifdef CONFIG_X86_32
31/* kernel/process_32.c */ 31/* kernel/process_32.c */
32ptregscall int sys_fork(struct pt_regs *); 32int sys_fork(struct pt_regs *);
33ptregscall int sys_clone(struct pt_regs *, unsigned long, 33int sys_clone(struct pt_regs *);
34 unsigned long, int __user *, 34int sys_vfork(struct pt_regs *);
35 unsigned long, int __user *); 35int sys_execve(struct pt_regs *);
36ptregscall int sys_vfork(struct pt_regs *);
37ptregscall int sys_execve(struct pt_regs *, char __user *,
38 char __user * __user *,
39 char __user * __user *);
40 36
41/* kernel/signal_32.c */ 37/* kernel/signal_32.c */
42asmlinkage int sys_sigsuspend(int, int, old_sigset_t); 38asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
43asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, 39asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
44 struct old_sigaction __user *); 40 struct old_sigaction __user *);
45ptregscall int sys_sigaltstack(struct pt_regs *, const stack_t __user *, 41int sys_sigaltstack(struct pt_regs *);
46 stack_t __user *); 42unsigned long sys_sigreturn(struct pt_regs *);
47ptregscall unsigned long sys_sigreturn(struct pt_regs *); 43int sys_rt_sigreturn(struct pt_regs *);
48ptregscall int sys_rt_sigreturn(struct pt_regs *);
49 44
50/* kernel/ioport.c */ 45/* kernel/ioport.c */
51ptregscall long sys_iopl(struct pt_regs *, unsigned int); 46long sys_iopl(struct pt_regs *);
52 47
53/* kernel/sys_i386_32.c */ 48/* kernel/sys_i386_32.c */
54asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, 49asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long,
@@ -64,8 +59,8 @@ struct oldold_utsname;
64asmlinkage int sys_olduname(struct oldold_utsname __user *); 59asmlinkage int sys_olduname(struct oldold_utsname __user *);
65 60
66/* kernel/vm86_32.c */ 61/* kernel/vm86_32.c */
67ptregscall int sys_vm86old(struct pt_regs *, struct vm86_struct __user *); 62int sys_vm86old(struct pt_regs *);
68ptregscall int sys_vm86(struct pt_regs *, unsigned long, unsigned long); 63int sys_vm86(struct pt_regs *);
69 64
70#else /* CONFIG_X86_32 */ 65#else /* CONFIG_X86_32 */
71 66
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 7ec148646312..e41980a373ab 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -131,8 +131,9 @@ static int do_iopl(unsigned int level, struct pt_regs *regs)
131} 131}
132 132
133#ifdef CONFIG_X86_32 133#ifdef CONFIG_X86_32
134ptregscall long sys_iopl(struct pt_regs *regs, unsigned int level) 134long sys_iopl(struct pt_regs *regs)
135{ 135{
136 unsigned int level = regs->bx;
136 struct thread_struct *t = &current->thread; 137 struct thread_struct *t = &current->thread;
137 int rc; 138 int rc;
138 139
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 5a9dcfb01f71..fec79ad85dc6 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -603,15 +603,21 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
603 return prev_p; 603 return prev_p;
604} 604}
605 605
606ptregscall int sys_fork(struct pt_regs *regs) 606int sys_fork(struct pt_regs *regs)
607{ 607{
608 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); 608 return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL);
609} 609}
610 610
611ptregscall int sys_clone(struct pt_regs *regs, unsigned long clone_flags, 611int sys_clone(struct pt_regs *regs)
612 unsigned long newsp, int __user *parent_tidptr,
613 unsigned long unused, int __user *child_tidptr)
614{ 612{
613 unsigned long clone_flags;
614 unsigned long newsp;
615 int __user *parent_tidptr, *child_tidptr;
616
617 clone_flags = regs->bx;
618 newsp = regs->cx;
619 parent_tidptr = (int __user *)regs->dx;
620 child_tidptr = (int __user *)regs->di;
615 if (!newsp) 621 if (!newsp)
616 newsp = regs->sp; 622 newsp = regs->sp;
617 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); 623 return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
@@ -627,7 +633,7 @@ ptregscall int sys_clone(struct pt_regs *regs, unsigned long clone_flags,
627 * do not have enough call-clobbered registers to hold all 633 * do not have enough call-clobbered registers to hold all
628 * the information you need. 634 * the information you need.
629 */ 635 */
630ptregscall int sys_vfork(struct pt_regs *regs) 636int sys_vfork(struct pt_regs *regs)
631{ 637{
632 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL); 638 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL);
633} 639}
@@ -635,18 +641,19 @@ ptregscall int sys_vfork(struct pt_regs *regs)
635/* 641/*
636 * sys_execve() executes a new program. 642 * sys_execve() executes a new program.
637 */ 643 */
638ptregscall int sys_execve(struct pt_regs *regs, char __user *u_filename, 644int sys_execve(struct pt_regs *regs)
639 char __user * __user *argv,
640 char __user * __user *envp)
641{ 645{
642 int error; 646 int error;
643 char *filename; 647 char *filename;
644 648
645 filename = getname(u_filename); 649 filename = getname((char __user *) regs->bx);
646 error = PTR_ERR(filename); 650 error = PTR_ERR(filename);
647 if (IS_ERR(filename)) 651 if (IS_ERR(filename))
648 goto out; 652 goto out;
649 error = do_execve(filename, argv, envp, regs); 653 error = do_execve(filename,
654 (char __user * __user *) regs->cx,
655 (char __user * __user *) regs->dx,
656 regs);
650 if (error == 0) { 657 if (error == 0) {
651 /* Make sure we don't return using sysenter.. */ 658 /* Make sure we don't return using sysenter.. */
652 set_thread_flag(TIF_IRET); 659 set_thread_flag(TIF_IRET);
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index d7a158367e38..ccfb27412f0f 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -549,23 +549,27 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
549#endif /* CONFIG_X86_32 */ 549#endif /* CONFIG_X86_32 */
550 550
551#ifdef CONFIG_X86_32 551#ifdef CONFIG_X86_32
552ptregscall int 552int sys_sigaltstack(struct pt_regs *regs)
553sys_sigaltstack(struct pt_regs *regs, const stack_t __user *uss, 553{
554 stack_t __user *uoss) 554 const stack_t __user *uss = (const stack_t __user *)regs->bx;
555 stack_t __user *uoss = (stack_t __user *)regs->cx;
556
557 return do_sigaltstack(uss, uoss, regs->sp);
558}
555#else /* !CONFIG_X86_32 */ 559#else /* !CONFIG_X86_32 */
556asmlinkage long 560asmlinkage long
557sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, 561sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
558 struct pt_regs *regs) 562 struct pt_regs *regs)
559#endif /* CONFIG_X86_32 */
560{ 563{
561 return do_sigaltstack(uss, uoss, regs->sp); 564 return do_sigaltstack(uss, uoss, regs->sp);
562} 565}
566#endif /* CONFIG_X86_32 */
563 567
564/* 568/*
565 * Do a signal return; undo the signal stack. 569 * Do a signal return; undo the signal stack.
566 */ 570 */
567#ifdef CONFIG_X86_32 571#ifdef CONFIG_X86_32
568ptregscall unsigned long sys_sigreturn(struct pt_regs *regs) 572unsigned long sys_sigreturn(struct pt_regs *regs)
569{ 573{
570 struct sigframe __user *frame; 574 struct sigframe __user *frame;
571 unsigned long ax; 575 unsigned long ax;
@@ -629,13 +633,16 @@ badframe:
629} 633}
630 634
631#ifdef CONFIG_X86_32 635#ifdef CONFIG_X86_32
632ptregscall int sys_rt_sigreturn(struct pt_regs *regs) 636int sys_rt_sigreturn(struct pt_regs *regs)
637{
638 return do_rt_sigreturn(regs);
639}
633#else /* !CONFIG_X86_32 */ 640#else /* !CONFIG_X86_32 */
634asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) 641asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
635#endif /* CONFIG_X86_32 */
636{ 642{
637 return do_rt_sigreturn(regs); 643 return do_rt_sigreturn(regs);
638} 644}
645#endif /* CONFIG_X86_32 */
639 646
640/* 647/*
641 * OK, we're invoking a handler: 648 * OK, we're invoking a handler:
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 8fa6ba7c9233..d7ac84e7fc1c 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -197,8 +197,9 @@ 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
200ptregscall int sys_vm86old(struct pt_regs *regs, struct vm86_struct __user *v86) 200int sys_vm86old(struct pt_regs *regs)
201{ 201{
202 struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx;
202 struct kernel_vm86_struct info; /* declare this _on top_, 203 struct kernel_vm86_struct info; /* declare this _on top_,
203 * this avoids wasting of stack space. 204 * this avoids wasting of stack space.
204 * This remains on the stack until we 205 * This remains on the stack until we
@@ -226,7 +227,7 @@ out:
226} 227}
227 228
228 229
229ptregscall int sys_vm86(struct pt_regs *regs, unsigned long cmd, unsigned long arg) 230int sys_vm86(struct pt_regs *regs)
230{ 231{
231 struct kernel_vm86_struct info; /* declare this _on top_, 232 struct kernel_vm86_struct info; /* declare this _on top_,
232 * this avoids wasting of stack space. 233 * this avoids wasting of stack space.
@@ -238,12 +239,12 @@ ptregscall int sys_vm86(struct pt_regs *regs, unsigned long cmd, unsigned long a
238 struct vm86plus_struct __user *v86; 239 struct vm86plus_struct __user *v86;
239 240
240 tsk = current; 241 tsk = current;
241 switch (cmd) { 242 switch (regs->bx) {
242 case VM86_REQUEST_IRQ: 243 case VM86_REQUEST_IRQ:
243 case VM86_FREE_IRQ: 244 case VM86_FREE_IRQ:
244 case VM86_GET_IRQ_BITS: 245 case VM86_GET_IRQ_BITS:
245 case VM86_GET_AND_RESET_IRQ: 246 case VM86_GET_AND_RESET_IRQ:
246 ret = do_vm86_irq_handling(cmd, (int)arg); 247 ret = do_vm86_irq_handling(regs->bx, (int)regs->cx);
247 goto out; 248 goto out;
248 case VM86_PLUS_INSTALL_CHECK: 249 case VM86_PLUS_INSTALL_CHECK:
249 /* 250 /*
@@ -260,7 +261,7 @@ ptregscall int sys_vm86(struct pt_regs *regs, unsigned long cmd, unsigned long a
260 ret = -EPERM; 261 ret = -EPERM;
261 if (tsk->thread.saved_sp0) 262 if (tsk->thread.saved_sp0)
262 goto out; 263 goto out;
263 v86 = (struct vm86plus_struct __user *)arg; 264 v86 = (struct vm86plus_struct __user *)regs->cx;
264 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs, 265 tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
265 offsetof(struct kernel_vm86_struct, regs32) - 266 offsetof(struct kernel_vm86_struct, regs32) -
266 sizeof(info.regs)); 267 sizeof(info.regs));