diff options
author | Brian Gerst <brgerst@gmail.com> | 2009-02-10 09:51:46 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-02-11 06:40:45 -0500 |
commit | 253f29a4ae9cc6cdc7b94f96517f27a93885a6ce (patch) | |
tree | 09942e565938a6bac216b1725ccf607e01d09b20 /arch/x86/kernel/process_32.c | |
parent | aa78bcfa01dec3cdbde3cda098ce32abbd9c3bf6 (diff) |
x86: pass in pt_regs pointer for syscalls that need it
Some syscalls need to access the pt_regs structure, either to copy
user register state or to modifiy it. This patch adds stubs to load
the address of the pt_regs struct into the %eax register, and changes
the syscalls to regparm(1) to receive the pt_regs pointer as the
first argument.
Signed-off-by: Brian Gerst <brgerst@gmail.com>
Acked-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/process_32.c')
-rw-r--r-- | arch/x86/kernel/process_32.c | 35 |
1 files changed, 14 insertions, 21 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index b50604bb1e41..5a9dcfb01f71 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
@@ -603,24 +603,18 @@ __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 | asmlinkage int sys_fork(struct pt_regs regs) | 606 | ptregscall int sys_fork(struct pt_regs *regs) |
607 | { | 607 | { |
608 | return do_fork(SIGCHLD, regs.sp, ®s, 0, NULL, NULL); | 608 | return do_fork(SIGCHLD, regs->sp, regs, 0, NULL, NULL); |
609 | } | 609 | } |
610 | 610 | ||
611 | asmlinkage int sys_clone(struct pt_regs regs) | 611 | ptregscall int sys_clone(struct pt_regs *regs, unsigned long clone_flags, |
612 | unsigned long newsp, int __user *parent_tidptr, | ||
613 | unsigned long unused, int __user *child_tidptr) | ||
612 | { | 614 | { |
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; | ||
621 | if (!newsp) | 615 | if (!newsp) |
622 | newsp = regs.sp; | 616 | newsp = regs->sp; |
623 | return do_fork(clone_flags, newsp, ®s, 0, parent_tidptr, child_tidptr); | 617 | return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr); |
624 | } | 618 | } |
625 | 619 | ||
626 | /* | 620 | /* |
@@ -633,27 +627,26 @@ asmlinkage int sys_clone(struct pt_regs regs) | |||
633 | * do not have enough call-clobbered registers to hold all | 627 | * do not have enough call-clobbered registers to hold all |
634 | * the information you need. | 628 | * the information you need. |
635 | */ | 629 | */ |
636 | asmlinkage int sys_vfork(struct pt_regs regs) | 630 | ptregscall int sys_vfork(struct pt_regs *regs) |
637 | { | 631 | { |
638 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, ®s, 0, NULL, NULL); | 632 | return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL); |
639 | } | 633 | } |
640 | 634 | ||
641 | /* | 635 | /* |
642 | * sys_execve() executes a new program. | 636 | * sys_execve() executes a new program. |
643 | */ | 637 | */ |
644 | asmlinkage int sys_execve(struct pt_regs regs) | 638 | ptregscall int sys_execve(struct pt_regs *regs, char __user *u_filename, |
639 | char __user * __user *argv, | ||
640 | char __user * __user *envp) | ||
645 | { | 641 | { |
646 | int error; | 642 | int error; |
647 | char *filename; | 643 | char *filename; |
648 | 644 | ||
649 | filename = getname((char __user *) regs.bx); | 645 | filename = getname(u_filename); |
650 | error = PTR_ERR(filename); | 646 | error = PTR_ERR(filename); |
651 | if (IS_ERR(filename)) | 647 | if (IS_ERR(filename)) |
652 | goto out; | 648 | goto out; |
653 | error = do_execve(filename, | 649 | error = do_execve(filename, argv, envp, regs); |
654 | (char __user * __user *) regs.cx, | ||
655 | (char __user * __user *) regs.dx, | ||
656 | ®s); | ||
657 | if (error == 0) { | 650 | if (error == 0) { |
658 | /* Make sure we don't return using sysenter.. */ | 651 | /* Make sure we don't return using sysenter.. */ |
659 | set_thread_flag(TIF_IRET); | 652 | set_thread_flag(TIF_IRET); |