diff options
-rw-r--r-- | arch/x86/include/asm/linkage.h | 7 | ||||
-rw-r--r-- | arch/x86/include/asm/syscalls.h | 25 | ||||
-rw-r--r-- | arch/x86/kernel/ioport.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/process_32.c | 27 | ||||
-rw-r--r-- | arch/x86/kernel/signal.c | 21 | ||||
-rw-r--r-- | arch/x86/kernel/vm86_32.c | 11 |
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 */ |
32 | ptregscall int sys_fork(struct pt_regs *); | 32 | int sys_fork(struct pt_regs *); |
33 | ptregscall int sys_clone(struct pt_regs *, unsigned long, | 33 | int sys_clone(struct pt_regs *); |
34 | unsigned long, int __user *, | 34 | int sys_vfork(struct pt_regs *); |
35 | unsigned long, int __user *); | 35 | int sys_execve(struct pt_regs *); |
36 | ptregscall int sys_vfork(struct pt_regs *); | ||
37 | ptregscall 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 */ |
42 | asmlinkage int sys_sigsuspend(int, int, old_sigset_t); | 38 | asmlinkage int sys_sigsuspend(int, int, old_sigset_t); |
43 | asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, | 39 | asmlinkage int sys_sigaction(int, const struct old_sigaction __user *, |
44 | struct old_sigaction __user *); | 40 | struct old_sigaction __user *); |
45 | ptregscall int sys_sigaltstack(struct pt_regs *, const stack_t __user *, | 41 | int sys_sigaltstack(struct pt_regs *); |
46 | stack_t __user *); | 42 | unsigned long sys_sigreturn(struct pt_regs *); |
47 | ptregscall unsigned long sys_sigreturn(struct pt_regs *); | 43 | int sys_rt_sigreturn(struct pt_regs *); |
48 | ptregscall int sys_rt_sigreturn(struct pt_regs *); | ||
49 | 44 | ||
50 | /* kernel/ioport.c */ | 45 | /* kernel/ioport.c */ |
51 | ptregscall long sys_iopl(struct pt_regs *, unsigned int); | 46 | long sys_iopl(struct pt_regs *); |
52 | 47 | ||
53 | /* kernel/sys_i386_32.c */ | 48 | /* kernel/sys_i386_32.c */ |
54 | asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, | 49 | asmlinkage long sys_mmap2(unsigned long, unsigned long, unsigned long, |
@@ -64,8 +59,8 @@ struct oldold_utsname; | |||
64 | asmlinkage int sys_olduname(struct oldold_utsname __user *); | 59 | asmlinkage int sys_olduname(struct oldold_utsname __user *); |
65 | 60 | ||
66 | /* kernel/vm86_32.c */ | 61 | /* kernel/vm86_32.c */ |
67 | ptregscall int sys_vm86old(struct pt_regs *, struct vm86_struct __user *); | 62 | int sys_vm86old(struct pt_regs *); |
68 | ptregscall int sys_vm86(struct pt_regs *, unsigned long, unsigned long); | 63 | int 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 |
134 | ptregscall long sys_iopl(struct pt_regs *regs, unsigned int level) | 134 | long sys_iopl(struct pt_regs *regs) |
135 | { | 135 | { |
136 | unsigned int level = regs->bx; | ||
136 | struct thread_struct *t = ¤t->thread; | 137 | struct thread_struct *t = ¤t->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 | ||
606 | ptregscall int sys_fork(struct pt_regs *regs) | 606 | int 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 | ||
611 | ptregscall int sys_clone(struct pt_regs *regs, unsigned long clone_flags, | 611 | int 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 | */ |
630 | ptregscall int sys_vfork(struct pt_regs *regs) | 636 | int 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 | */ |
638 | ptregscall int sys_execve(struct pt_regs *regs, char __user *u_filename, | 644 | int 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 |
552 | ptregscall int | 552 | int sys_sigaltstack(struct pt_regs *regs) |
553 | sys_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 */ |
556 | asmlinkage long | 560 | asmlinkage long |
557 | sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss, | 561 | sys_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 |
568 | ptregscall unsigned long sys_sigreturn(struct pt_regs *regs) | 572 | unsigned 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 |
632 | ptregscall int sys_rt_sigreturn(struct pt_regs *regs) | 636 | int 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 */ |
634 | asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) | 641 | asmlinkage 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: | |||
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 | ptregscall int sys_vm86old(struct pt_regs *regs, struct vm86_struct __user *v86) | 200 | int 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 | ||
229 | ptregscall int sys_vm86(struct pt_regs *regs, unsigned long cmd, unsigned long arg) | 230 | int 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)); |