aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/process_32.c
diff options
context:
space:
mode:
authorBrian Gerst <brgerst@gmail.com>2009-02-10 09:51:46 -0500
committerIngo Molnar <mingo@elte.hu>2009-02-11 06:40:45 -0500
commit253f29a4ae9cc6cdc7b94f96517f27a93885a6ce (patch)
tree09942e565938a6bac216b1725ccf607e01d09b20 /arch/x86/kernel/process_32.c
parentaa78bcfa01dec3cdbde3cda098ce32abbd9c3bf6 (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.c35
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
606asmlinkage int sys_fork(struct pt_regs regs) 606ptregscall 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
611asmlinkage int sys_clone(struct pt_regs regs) 611ptregscall 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, &regs, 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 */
636asmlinkage int sys_vfork(struct pt_regs regs) 630ptregscall int sys_vfork(struct pt_regs *regs)
637{ 631{
638 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.sp, &regs, 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 */
644asmlinkage int sys_execve(struct pt_regs regs) 638ptregscall 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 &regs);
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);