This patch set converts the 32-bit syscalls that need pt_regs to
match the same prototype as 64-bit, using regparm(3) and adding
the pt_regs pointer as an extra argument. This allows these
syscalls to be merged.
[PATCH 1/6] x86, 32-bit: Add new pt_regs stubs
[PATCH 2/6] x86: Merge sys_iopl
[PATCH 3/6] x86: Merge sys_execve
[PATCH 4/6] x86: Merge sys_sigaltstack
[PATCH 5/6] x86, 32-bit: Convert sys_vm86 & sys_vm86old
[PATCH 6/6] x86: Merge sys_clone
arch/x86/include/asm/syscalls.h | 32 ++++++--------------
arch/x86/kernel/entry_32.S | 61 ++++++++++++++++++++++++++++++++-------
arch/x86/kernel/ioport.c | 28 +++--------------
arch/x86/kernel/process.c | 35 ++++++++++++++++++++++
arch/x86/kernel/process_32.c | 40 -------------------------
arch/x86/kernel/process_64.c | 28 ------------------
arch/x86/kernel/signal.c | 12 +-------
arch/x86/kernel/vm86_32.c | 11 +++----
8 files changed, 106 insertions(+), 141 deletions(-)
Add new stubs which add the pt_regs pointer as the last arg, matching
64-bit. This will allow these syscalls to be easily merged.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/kernel/entry_32.S | 49 ++++++++++++++++++++++++++++++++++---------
1 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 50b9c22..34dbfa9 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -725,22 +725,49 @@ END(syscall_badsys)
/*
* System calls that need a pt_regs pointer.
*/
-#define PTREGSCALL(name) \
+#define PTREGSCALL0(name) \
ALIGN; \
ptregs_##name: \
leal 4(%esp),%eax; \
jmp sys_##name;
-PTREGSCALL(iopl)
-PTREGSCALL(fork)
-PTREGSCALL(clone)
-PTREGSCALL(vfork)
-PTREGSCALL(execve)
-PTREGSCALL(sigaltstack)
-PTREGSCALL(sigreturn)
-PTREGSCALL(rt_sigreturn)
-PTREGSCALL(vm86)
-PTREGSCALL(vm86old)
+#define PTREGSCALL1(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%edx; \
+ movl PT_EBX(%edx),%eax; \
+ jmp sys_##name;
+
+#define PTREGSCALL2(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%ecx; \
+ movl PT_ECX(%ecx),%edx; \
+ movl PT_EBX(%ecx),%eax; \
+ jmp sys_##name;
+
+#define PTREGSCALL3(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%eax; \
+ pushl %eax; \
+ movl PT_EDX(%eax),%ecx; \
+ movl PT_ECX(%eax),%edx; \
+ movl PT_EBX(%eax),%eax; \
+ call sys_##name; \
+ addl $4,%esp; \
+ ret
+
+PTREGSCALL0(iopl)
+PTREGSCALL0(fork)
+PTREGSCALL0(clone)
+PTREGSCALL0(vfork)
+PTREGSCALL0(execve)
+PTREGSCALL0(sigaltstack)
+PTREGSCALL0(sigreturn)
+PTREGSCALL0(rt_sigreturn)
+PTREGSCALL0(vm86)
+PTREGSCALL0(vm86old)
.macro FIXUP_ESPFIX_STACK
/*
--
1.6.5.2
Change 32-bit sys_iopl to PTREGSCALL1, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/include/asm/syscalls.h | 6 +-----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/ioport.c | 28 +++++-----------------------
3 files changed, 7 insertions(+), 29 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 372b76e..4b694cd 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -18,6 +18,7 @@
/* Common in X86_32 and X86_64 */
/* kernel/ioport.c */
asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
+long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/process.c */
int sys_fork(struct pt_regs *);
@@ -35,8 +36,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* X86_32 only */
#ifdef CONFIG_X86_32
-/* kernel/ioport.c */
-long sys_iopl(struct pt_regs *);
/* kernel/process_32.c */
int sys_clone(struct pt_regs *);
@@ -70,9 +69,6 @@ int sys_vm86(struct pt_regs *);
#else /* CONFIG_X86_32 */
/* X86_64 only */
-/* kernel/ioport.c */
-asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
-
/* kernel/process_64.c */
asmlinkage long sys_clone(unsigned long, unsigned long,
void __user *, void __user *,
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 34dbfa9..ab7fcef 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -758,7 +758,7 @@ ptregs_##name: \
addl $4,%esp; \
ret
-PTREGSCALL0(iopl)
+PTREGSCALL1(iopl)
PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 99c4d30..85ecc7c 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)
* on system-call entry - see also fork() and the signal handling
* code.
*/
-static int do_iopl(unsigned int level, struct pt_regs *regs)
+long sys_iopl(unsigned int level, struct pt_regs *regs)
{
unsigned int old = (regs->flags >> 12) & 3;
+ struct thread_struct *t = ¤t->thread;
if (level > 3)
return -EINVAL;
@@ -115,29 +116,10 @@ static int do_iopl(unsigned int level, struct pt_regs *regs)
return -EPERM;
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-
- return 0;
-}
-
#ifdef CONFIG_X86_32
-long sys_iopl(struct pt_regs *regs)
-{
- unsigned int level = regs->bx;
- struct thread_struct *t = ¤t->thread;
- int rc;
-
- rc = do_iopl(level, regs);
- if (rc < 0)
- goto out;
-
t->iopl = level << 12;
set_iopl_mask(t->iopl);
-out:
- return rc;
-}
-#else
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
-{
- return do_iopl(level, regs);
-}
#endif
+
+ return 0;
+}
--
1.6.5.2
Change 32-bit sys_execve to PTREGSCALL3, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/include/asm/syscalls.h | 6 ++----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/process.c | 26 ++++++++++++++++++++++++++
arch/x86/kernel/process_32.c | 25 -------------------------
arch/x86/kernel/process_64.c | 19 -------------------
5 files changed, 29 insertions(+), 49 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 4b694cd..48c48e5 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -23,6 +23,8 @@ long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/process.c */
int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
+long sys_execve(char __user *, char __user * __user *,
+ char __user * __user *, struct pt_regs *);
/* kernel/ldt.c */
asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
@@ -39,7 +41,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* kernel/process_32.c */
int sys_clone(struct pt_regs *);
-int sys_execve(struct pt_regs *);
/* kernel/signal.c */
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
@@ -73,9 +74,6 @@ int sys_vm86(struct pt_regs *);
asmlinkage long sys_clone(unsigned long, unsigned long,
void __user *, void __user *,
struct pt_regs *);
-asmlinkage long sys_execve(char __user *, char __user * __user *,
- char __user * __user *,
- struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
/* kernel/signal.c */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index ab7fcef..a96a0d8 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -762,7 +762,7 @@ PTREGSCALL1(iopl)
PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
-PTREGSCALL0(execve)
+PTREGSCALL3(execve)
PTREGSCALL0(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5e2ba63..bb17bd9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -236,6 +236,32 @@ int sys_vfork(struct pt_regs *regs)
/*
+ * sys_execve() executes a new program.
+ */
+long sys_execve(char __user *name, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
+{
+ long error;
+ char *filename;
+
+ filename = getname(name);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ return error;
+ error = do_execve(filename, argv, envp, regs);
+
+#ifdef CONFIG_X86_32
+ if (error == 0) {
+ /* Make sure we don't return using sysenter.. */
+ set_thread_flag(TIF_IRET);
+ }
+#endif
+
+ putname(filename);
+ return error;
+}
+
+/*
* Idle related variables and functions
*/
unsigned long boot_option_idle_override = 0;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 075580b..486e38e 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -451,31 +451,6 @@ int sys_clone(struct pt_regs *regs)
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}
-/*
- * sys_execve() executes a new program.
- */
-int sys_execve(struct pt_regs *regs)
-{
- int error;
- char *filename;
-
- filename = getname((char __user *) regs->bx);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename,
- (char __user * __user *) regs->cx,
- (char __user * __user *) regs->dx,
- regs);
- if (error == 0) {
- /* Make sure we don't return using sysenter.. */
- set_thread_flag(TIF_IRET);
- }
- putname(filename);
-out:
- return error;
-}
-
#define top_esp (THREAD_SIZE - sizeof(unsigned long))
#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c95c8f4..671960d 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -520,25 +520,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
return prev_p;
}
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage
-long sys_execve(char __user *name, char __user * __user *argv,
- char __user * __user *envp, struct pt_regs *regs)
-{
- long error;
- char *filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
void set_personality_64bit(void)
{
/* inherit personality from parent */
--
1.6.5.2
Change 32-bit sys_sigaltstack to PTREGSCALL2, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/include/asm/syscalls.h | 8 +++-----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/signal.c | 12 +-----------
3 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 48c48e5..94e0b61 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -31,6 +31,9 @@ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
/* kernel/signal.c */
long sys_rt_sigreturn(struct pt_regs *);
+long sys_sigaltstack(const stack_t __user *, stack_t __user *,
+ struct pt_regs *);
+
/* kernel/tls.c */
asmlinkage int sys_set_thread_area(struct user_desc __user *);
@@ -46,7 +49,6 @@ int sys_clone(struct pt_regs *);
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
struct old_sigaction __user *);
-int sys_sigaltstack(struct pt_regs *);
unsigned long sys_sigreturn(struct pt_regs *);
/* kernel/sys_i386_32.c */
@@ -76,10 +78,6 @@ asmlinkage long sys_clone(unsigned long, unsigned long,
struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
-/* kernel/signal.c */
-asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
- struct pt_regs *);
-
/* kernel/sys_x86_64.c */
struct new_utsname;
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index a96a0d8..621ef45 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -763,7 +763,7 @@ PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
PTREGSCALL3(execve)
-PTREGSCALL0(sigaltstack)
+PTREGSCALL2(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
PTREGSCALL0(vm86)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 74fe6d8..4fd173c 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,
}
#endif /* CONFIG_X86_32 */
-#ifdef CONFIG_X86_32
-int sys_sigaltstack(struct pt_regs *regs)
-{
- const stack_t __user *uss = (const stack_t __user *)regs->bx;
- stack_t __user *uoss = (stack_t __user *)regs->cx;
-
- return do_sigaltstack(uss, uoss, regs->sp);
-}
-#else /* !CONFIG_X86_32 */
-asmlinkage long
+long
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
struct pt_regs *regs)
{
return do_sigaltstack(uss, uoss, regs->sp);
}
-#endif /* CONFIG_X86_32 */
/*
* Do a signal return; undo the signal stack.
--
1.6.5.2
Convert these to new PTREGSCALL stubs.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/include/asm/syscalls.h | 4 ++--
arch/x86/kernel/entry_32.S | 4 ++--
arch/x86/kernel/vm86_32.c | 11 +++++------
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 94e0b61..df2c511 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -66,8 +66,8 @@ asmlinkage int sys_uname(struct old_utsname __user *);
asmlinkage int sys_olduname(struct oldold_utsname __user *);
/* kernel/vm86_32.c */
-int sys_vm86old(struct pt_regs *);
-int sys_vm86(struct pt_regs *);
+int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
+int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
#else /* CONFIG_X86_32 */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 621ef45..6c2f25d 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -766,8 +766,8 @@ PTREGSCALL3(execve)
PTREGSCALL2(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
-PTREGSCALL0(vm86)
-PTREGSCALL0(vm86old)
+PTREGSCALL2(vm86)
+PTREGSCALL1(vm86old)
.macro FIXUP_ESPFIX_STACK
/*
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 9c4e625..5ffb562 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -197,9 +197,8 @@ out:
static int do_vm86_irq_handling(int subfunction, int irqnumber);
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
-int sys_vm86old(struct pt_regs *regs)
+int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs)
{
- struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx;
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
* This remains on the stack until we
@@ -227,7 +226,7 @@ out:
}
-int sys_vm86(struct pt_regs *regs)
+int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs)
{
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
@@ -239,12 +238,12 @@ int sys_vm86(struct pt_regs *regs)
struct vm86plus_struct __user *v86;
tsk = current;
- switch (regs->bx) {
+ switch (cmd) {
case VM86_REQUEST_IRQ:
case VM86_FREE_IRQ:
case VM86_GET_IRQ_BITS:
case VM86_GET_AND_RESET_IRQ:
- ret = do_vm86_irq_handling(regs->bx, (int)regs->cx);
+ ret = do_vm86_irq_handling(cmd, (int)arg);
goto out;
case VM86_PLUS_INSTALL_CHECK:
/*
@@ -261,7 +260,7 @@ int sys_vm86(struct pt_regs *regs)
ret = -EPERM;
if (tsk->thread.saved_sp0)
goto out;
- v86 = (struct vm86plus_struct __user *)regs->cx;
+ v86 = (struct vm86plus_struct __user *)arg;
tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
offsetof(struct kernel_vm86_struct, regs32) -
sizeof(info.regs));
--
1.6.5.2
Change 32-bit sys_clone to new PTREGSCALL stub, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
---
arch/x86/include/asm/syscalls.h | 8 ++------
arch/x86/kernel/entry_32.S | 14 +++++++++++++-
arch/x86/kernel/process.c | 9 +++++++++
arch/x86/kernel/process_32.c | 15 ---------------
arch/x86/kernel/process_64.c | 9 ---------
5 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index df2c511..b0ce780 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -25,6 +25,8 @@ int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
long sys_execve(char __user *, char __user * __user *,
char __user * __user *, struct pt_regs *);
+long sys_clone(unsigned long, unsigned long, void __user *,
+ void __user *, struct pt_regs *);
/* kernel/ldt.c */
asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
@@ -42,9 +44,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* X86_32 only */
#ifdef CONFIG_X86_32
-/* kernel/process_32.c */
-int sys_clone(struct pt_regs *);
-
/* kernel/signal.c */
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
@@ -73,9 +72,6 @@ int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
/* X86_64 only */
/* kernel/process_64.c */
-asmlinkage long sys_clone(unsigned long, unsigned long,
- void __user *, void __user *,
- struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
/* kernel/sys_x86_64.c */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 6c2f25d..6492555 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -760,7 +760,6 @@ ptregs_##name: \
PTREGSCALL1(iopl)
PTREGSCALL0(fork)
-PTREGSCALL0(clone)
PTREGSCALL0(vfork)
PTREGSCALL3(execve)
PTREGSCALL2(sigaltstack)
@@ -769,6 +768,19 @@ PTREGSCALL0(rt_sigreturn)
PTREGSCALL2(vm86)
PTREGSCALL1(vm86old)
+/* Clone is an oddball. The 4th arg is in %edi */
+ ALIGN;
+ptregs_clone:
+ leal 4(%esp),%eax
+ pushl %eax
+ pushl PT_EDI(%eax)
+ movl PT_EDX(%eax),%ecx
+ movl PT_ECX(%eax),%edx
+ movl PT_EBX(%eax),%eax
+ call sys_clone
+ addl $8,%esp
+ ret
+
.macro FIXUP_ESPFIX_STACK
/*
* Switch back for ESPFIX stack to the normal zerobased stack
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index bb17bd9..f3c1a6b 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -234,6 +234,15 @@ int sys_vfork(struct pt_regs *regs)
NULL, NULL);
}
+long
+sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+{
+ if (!newsp)
+ newsp = regs->sp;
+ return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+}
+
/*
* sys_execve() executes a new program.
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 486e38e..506d5a7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -436,21 +436,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
return prev_p;
}
-int sys_clone(struct pt_regs *regs)
-{
- unsigned long clone_flags;
- unsigned long newsp;
- int __user *parent_tidptr, *child_tidptr;
-
- clone_flags = regs->bx;
- newsp = regs->cx;
- parent_tidptr = (int __user *)regs->dx;
- child_tidptr = (int __user *)regs->di;
- if (!newsp)
- newsp = regs->sp;
- return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
-}
-
#define top_esp (THREAD_SIZE - sizeof(unsigned long))
#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 671960d..83019f9 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -534,15 +534,6 @@ void set_personality_64bit(void)
current->personality &= ~READ_IMPLIES_EXEC;
}
-asmlinkage long
-sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
-{
- if (!newsp)
- newsp = regs->sp;
- return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
-}
-
unsigned long get_wchan(struct task_struct *p)
{
unsigned long stack;
--
1.6.5.2
On 12/09/2009 04:01 PM, Brian Gerst wrote:
> Add new stubs which add the pt_regs pointer as the last arg, matching
> 64-bit. This will allow these syscalls to be easily merged.
>
> Signed-off-by: Brian Gerst <[email protected]>
> +ptregs_##name: \
> + leal 4(%esp),%edx; \
> + movl PT_EBX(%edx),%eax; \
> + jmp sys_##name;
You're introducing a completely unnecessary pipeline serialization here.
Instead do:
movl (PT_EBX+4)(%esp),%eax;
... making the statements independent and therefore executable in parallel.
-hpa
Commit-ID: e258e4e0b495e6ecbd073d6bef1eafb62a58919a
Gitweb: http://git.kernel.org/tip/e258e4e0b495e6ecbd073d6bef1eafb62a58919a
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:51 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:27:49 -0800
x86-32: Add new pt_regs stubs
Add new stubs which add the pt_regs pointer as the last arg, matching
64-bit. This will allow these syscalls to be easily merged.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/kernel/entry_32.S | 49 ++++++++++++++++++++++++++++++++++---------
1 files changed, 38 insertions(+), 11 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 50b9c22..34dbfa9 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -725,22 +725,49 @@ END(syscall_badsys)
/*
* System calls that need a pt_regs pointer.
*/
-#define PTREGSCALL(name) \
+#define PTREGSCALL0(name) \
ALIGN; \
ptregs_##name: \
leal 4(%esp),%eax; \
jmp sys_##name;
-PTREGSCALL(iopl)
-PTREGSCALL(fork)
-PTREGSCALL(clone)
-PTREGSCALL(vfork)
-PTREGSCALL(execve)
-PTREGSCALL(sigaltstack)
-PTREGSCALL(sigreturn)
-PTREGSCALL(rt_sigreturn)
-PTREGSCALL(vm86)
-PTREGSCALL(vm86old)
+#define PTREGSCALL1(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%edx; \
+ movl PT_EBX(%edx),%eax; \
+ jmp sys_##name;
+
+#define PTREGSCALL2(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%ecx; \
+ movl PT_ECX(%ecx),%edx; \
+ movl PT_EBX(%ecx),%eax; \
+ jmp sys_##name;
+
+#define PTREGSCALL3(name) \
+ ALIGN; \
+ptregs_##name: \
+ leal 4(%esp),%eax; \
+ pushl %eax; \
+ movl PT_EDX(%eax),%ecx; \
+ movl PT_ECX(%eax),%edx; \
+ movl PT_EBX(%eax),%eax; \
+ call sys_##name; \
+ addl $4,%esp; \
+ ret
+
+PTREGSCALL0(iopl)
+PTREGSCALL0(fork)
+PTREGSCALL0(clone)
+PTREGSCALL0(vfork)
+PTREGSCALL0(execve)
+PTREGSCALL0(sigaltstack)
+PTREGSCALL0(sigreturn)
+PTREGSCALL0(rt_sigreturn)
+PTREGSCALL0(vm86)
+PTREGSCALL0(vm86old)
.macro FIXUP_ESPFIX_STACK
/*
Commit-ID: 27f59559d63375a4d59e7c720a439d9f0b47edad
Gitweb: http://git.kernel.org/tip/27f59559d63375a4d59e7c720a439d9f0b47edad
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:52 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:28:10 -0800
x86: Merge sys_iopl
Change 32-bit sys_iopl to PTREGSCALL1, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/syscalls.h | 6 +-----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/ioport.c | 28 +++++-----------------------
3 files changed, 7 insertions(+), 29 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 372b76e..4b694cd 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -18,6 +18,7 @@
/* Common in X86_32 and X86_64 */
/* kernel/ioport.c */
asmlinkage long sys_ioperm(unsigned long, unsigned long, int);
+long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/process.c */
int sys_fork(struct pt_regs *);
@@ -35,8 +36,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* X86_32 only */
#ifdef CONFIG_X86_32
-/* kernel/ioport.c */
-long sys_iopl(struct pt_regs *);
/* kernel/process_32.c */
int sys_clone(struct pt_regs *);
@@ -70,9 +69,6 @@ int sys_vm86(struct pt_regs *);
#else /* CONFIG_X86_32 */
/* X86_64 only */
-/* kernel/ioport.c */
-asmlinkage long sys_iopl(unsigned int, struct pt_regs *);
-
/* kernel/process_64.c */
asmlinkage long sys_clone(unsigned long, unsigned long,
void __user *, void __user *,
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 34dbfa9..ab7fcef 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -758,7 +758,7 @@ ptregs_##name: \
addl $4,%esp; \
ret
-PTREGSCALL0(iopl)
+PTREGSCALL1(iopl)
PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 99c4d30..85ecc7c 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)
* on system-call entry - see also fork() and the signal handling
* code.
*/
-static int do_iopl(unsigned int level, struct pt_regs *regs)
+long sys_iopl(unsigned int level, struct pt_regs *regs)
{
unsigned int old = (regs->flags >> 12) & 3;
+ struct thread_struct *t = ¤t->thread;
if (level > 3)
return -EINVAL;
@@ -115,29 +116,10 @@ static int do_iopl(unsigned int level, struct pt_regs *regs)
return -EPERM;
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-
- return 0;
-}
-
#ifdef CONFIG_X86_32
-long sys_iopl(struct pt_regs *regs)
-{
- unsigned int level = regs->bx;
- struct thread_struct *t = ¤t->thread;
- int rc;
-
- rc = do_iopl(level, regs);
- if (rc < 0)
- goto out;
-
t->iopl = level << 12;
set_iopl_mask(t->iopl);
-out:
- return rc;
-}
-#else
-asmlinkage long sys_iopl(unsigned int level, struct pt_regs *regs)
-{
- return do_iopl(level, regs);
-}
#endif
+
+ return 0;
+}
Commit-ID: 11cf88bd0b8165b65aaabaee0977e9a3ad474ab7
Gitweb: http://git.kernel.org/tip/11cf88bd0b8165b65aaabaee0977e9a3ad474ab7
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:53 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:28:34 -0800
x86: Merge sys_execve
Change 32-bit sys_execve to PTREGSCALL3, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/syscalls.h | 6 ++----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/process.c | 26 ++++++++++++++++++++++++++
arch/x86/kernel/process_32.c | 25 -------------------------
arch/x86/kernel/process_64.c | 19 -------------------
5 files changed, 29 insertions(+), 49 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 4b694cd..48c48e5 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -23,6 +23,8 @@ long sys_iopl(unsigned int, struct pt_regs *);
/* kernel/process.c */
int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
+long sys_execve(char __user *, char __user * __user *,
+ char __user * __user *, struct pt_regs *);
/* kernel/ldt.c */
asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
@@ -39,7 +41,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* kernel/process_32.c */
int sys_clone(struct pt_regs *);
-int sys_execve(struct pt_regs *);
/* kernel/signal.c */
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
@@ -73,9 +74,6 @@ int sys_vm86(struct pt_regs *);
asmlinkage long sys_clone(unsigned long, unsigned long,
void __user *, void __user *,
struct pt_regs *);
-asmlinkage long sys_execve(char __user *, char __user * __user *,
- char __user * __user *,
- struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
/* kernel/signal.c */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index ab7fcef..a96a0d8 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -762,7 +762,7 @@ PTREGSCALL1(iopl)
PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
-PTREGSCALL0(execve)
+PTREGSCALL3(execve)
PTREGSCALL0(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index 5e2ba63..bb17bd9 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -236,6 +236,32 @@ int sys_vfork(struct pt_regs *regs)
/*
+ * sys_execve() executes a new program.
+ */
+long sys_execve(char __user *name, char __user * __user *argv,
+ char __user * __user *envp, struct pt_regs *regs)
+{
+ long error;
+ char *filename;
+
+ filename = getname(name);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ return error;
+ error = do_execve(filename, argv, envp, regs);
+
+#ifdef CONFIG_X86_32
+ if (error == 0) {
+ /* Make sure we don't return using sysenter.. */
+ set_thread_flag(TIF_IRET);
+ }
+#endif
+
+ putname(filename);
+ return error;
+}
+
+/*
* Idle related variables and functions
*/
unsigned long boot_option_idle_override = 0;
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 075580b..486e38e 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -451,31 +451,6 @@ int sys_clone(struct pt_regs *regs)
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}
-/*
- * sys_execve() executes a new program.
- */
-int sys_execve(struct pt_regs *regs)
-{
- int error;
- char *filename;
-
- filename = getname((char __user *) regs->bx);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- goto out;
- error = do_execve(filename,
- (char __user * __user *) regs->cx,
- (char __user * __user *) regs->dx,
- regs);
- if (error == 0) {
- /* Make sure we don't return using sysenter.. */
- set_thread_flag(TIF_IRET);
- }
- putname(filename);
-out:
- return error;
-}
-
#define top_esp (THREAD_SIZE - sizeof(unsigned long))
#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c95c8f4..671960d 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -520,25 +520,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
return prev_p;
}
-/*
- * sys_execve() executes a new program.
- */
-asmlinkage
-long sys_execve(char __user *name, char __user * __user *argv,
- char __user * __user *envp, struct pt_regs *regs)
-{
- long error;
- char *filename;
-
- filename = getname(name);
- error = PTR_ERR(filename);
- if (IS_ERR(filename))
- return error;
- error = do_execve(filename, argv, envp, regs);
- putname(filename);
- return error;
-}
-
void set_personality_64bit(void)
{
/* inherit personality from parent */
Commit-ID: 052acad48a566a6dbcccb95e5d22e5e1b7cac8dd
Gitweb: http://git.kernel.org/tip/052acad48a566a6dbcccb95e5d22e5e1b7cac8dd
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:54 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:28:59 -0800
x86: Merge sys_sigaltstack
Change 32-bit sys_sigaltstack to PTREGSCALL2, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/syscalls.h | 8 +++-----
arch/x86/kernel/entry_32.S | 2 +-
arch/x86/kernel/signal.c | 12 +-----------
3 files changed, 5 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 48c48e5..94e0b61 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -31,6 +31,9 @@ asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
/* kernel/signal.c */
long sys_rt_sigreturn(struct pt_regs *);
+long sys_sigaltstack(const stack_t __user *, stack_t __user *,
+ struct pt_regs *);
+
/* kernel/tls.c */
asmlinkage int sys_set_thread_area(struct user_desc __user *);
@@ -46,7 +49,6 @@ int sys_clone(struct pt_regs *);
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
struct old_sigaction __user *);
-int sys_sigaltstack(struct pt_regs *);
unsigned long sys_sigreturn(struct pt_regs *);
/* kernel/sys_i386_32.c */
@@ -76,10 +78,6 @@ asmlinkage long sys_clone(unsigned long, unsigned long,
struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
-/* kernel/signal.c */
-asmlinkage long sys_sigaltstack(const stack_t __user *, stack_t __user *,
- struct pt_regs *);
-
/* kernel/sys_x86_64.c */
struct new_utsname;
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index a96a0d8..621ef45 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -763,7 +763,7 @@ PTREGSCALL0(fork)
PTREGSCALL0(clone)
PTREGSCALL0(vfork)
PTREGSCALL3(execve)
-PTREGSCALL0(sigaltstack)
+PTREGSCALL2(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
PTREGSCALL0(vm86)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index 74fe6d8..4fd173c 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,
}
#endif /* CONFIG_X86_32 */
-#ifdef CONFIG_X86_32
-int sys_sigaltstack(struct pt_regs *regs)
-{
- const stack_t __user *uss = (const stack_t __user *)regs->bx;
- stack_t __user *uoss = (stack_t __user *)regs->cx;
-
- return do_sigaltstack(uss, uoss, regs->sp);
-}
-#else /* !CONFIG_X86_32 */
-asmlinkage long
+long
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss,
struct pt_regs *regs)
{
return do_sigaltstack(uss, uoss, regs->sp);
}
-#endif /* CONFIG_X86_32 */
/*
* Do a signal return; undo the signal stack.
Commit-ID: f1382f157fb1175bba008abad0907310a1e459ce
Gitweb: http://git.kernel.org/tip/f1382f157fb1175bba008abad0907310a1e459ce
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:55 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:29:23 -0800
x86, 32-bit: Convert sys_vm86 & sys_vm86old
Convert these to new PTREGSCALL stubs.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/syscalls.h | 4 ++--
arch/x86/kernel/entry_32.S | 4 ++--
arch/x86/kernel/vm86_32.c | 11 +++++------
3 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index 94e0b61..df2c511 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -66,8 +66,8 @@ asmlinkage int sys_uname(struct old_utsname __user *);
asmlinkage int sys_olduname(struct oldold_utsname __user *);
/* kernel/vm86_32.c */
-int sys_vm86old(struct pt_regs *);
-int sys_vm86(struct pt_regs *);
+int sys_vm86old(struct vm86_struct __user *, struct pt_regs *);
+int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
#else /* CONFIG_X86_32 */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 621ef45..6c2f25d 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -766,8 +766,8 @@ PTREGSCALL3(execve)
PTREGSCALL2(sigaltstack)
PTREGSCALL0(sigreturn)
PTREGSCALL0(rt_sigreturn)
-PTREGSCALL0(vm86)
-PTREGSCALL0(vm86old)
+PTREGSCALL2(vm86)
+PTREGSCALL1(vm86old)
.macro FIXUP_ESPFIX_STACK
/*
diff --git a/arch/x86/kernel/vm86_32.c b/arch/x86/kernel/vm86_32.c
index 9c4e625..5ffb562 100644
--- a/arch/x86/kernel/vm86_32.c
+++ b/arch/x86/kernel/vm86_32.c
@@ -197,9 +197,8 @@ out:
static int do_vm86_irq_handling(int subfunction, int irqnumber);
static void do_sys_vm86(struct kernel_vm86_struct *info, struct task_struct *tsk);
-int sys_vm86old(struct pt_regs *regs)
+int sys_vm86old(struct vm86_struct __user *v86, struct pt_regs *regs)
{
- struct vm86_struct __user *v86 = (struct vm86_struct __user *)regs->bx;
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
* This remains on the stack until we
@@ -227,7 +226,7 @@ out:
}
-int sys_vm86(struct pt_regs *regs)
+int sys_vm86(unsigned long cmd, unsigned long arg, struct pt_regs *regs)
{
struct kernel_vm86_struct info; /* declare this _on top_,
* this avoids wasting of stack space.
@@ -239,12 +238,12 @@ int sys_vm86(struct pt_regs *regs)
struct vm86plus_struct __user *v86;
tsk = current;
- switch (regs->bx) {
+ switch (cmd) {
case VM86_REQUEST_IRQ:
case VM86_FREE_IRQ:
case VM86_GET_IRQ_BITS:
case VM86_GET_AND_RESET_IRQ:
- ret = do_vm86_irq_handling(regs->bx, (int)regs->cx);
+ ret = do_vm86_irq_handling(cmd, (int)arg);
goto out;
case VM86_PLUS_INSTALL_CHECK:
/*
@@ -261,7 +260,7 @@ int sys_vm86(struct pt_regs *regs)
ret = -EPERM;
if (tsk->thread.saved_sp0)
goto out;
- v86 = (struct vm86plus_struct __user *)regs->cx;
+ v86 = (struct vm86plus_struct __user *)arg;
tmp = copy_vm86_regs_from_user(&info.regs, &v86->regs,
offsetof(struct kernel_vm86_struct, regs32) -
sizeof(info.regs));
Commit-ID: f839bbc5c81b1c92ff8e81c360e9564f7b961b2e
Gitweb: http://git.kernel.org/tip/f839bbc5c81b1c92ff8e81c360e9564f7b961b2e
Author: Brian Gerst <[email protected]>
AuthorDate: Wed, 9 Dec 2009 19:01:56 -0500
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:29:42 -0800
x86: Merge sys_clone
Change 32-bit sys_clone to new PTREGSCALL stub, and merge with 64-bit.
Signed-off-by: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/syscalls.h | 8 ++------
arch/x86/kernel/entry_32.S | 14 +++++++++++++-
arch/x86/kernel/process.c | 9 +++++++++
arch/x86/kernel/process_32.c | 15 ---------------
arch/x86/kernel/process_64.c | 9 ---------
5 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/arch/x86/include/asm/syscalls.h b/arch/x86/include/asm/syscalls.h
index df2c511..b0ce780 100644
--- a/arch/x86/include/asm/syscalls.h
+++ b/arch/x86/include/asm/syscalls.h
@@ -25,6 +25,8 @@ int sys_fork(struct pt_regs *);
int sys_vfork(struct pt_regs *);
long sys_execve(char __user *, char __user * __user *,
char __user * __user *, struct pt_regs *);
+long sys_clone(unsigned long, unsigned long, void __user *,
+ void __user *, struct pt_regs *);
/* kernel/ldt.c */
asmlinkage int sys_modify_ldt(int, void __user *, unsigned long);
@@ -42,9 +44,6 @@ asmlinkage int sys_get_thread_area(struct user_desc __user *);
/* X86_32 only */
#ifdef CONFIG_X86_32
-/* kernel/process_32.c */
-int sys_clone(struct pt_regs *);
-
/* kernel/signal.c */
asmlinkage int sys_sigsuspend(int, int, old_sigset_t);
asmlinkage int sys_sigaction(int, const struct old_sigaction __user *,
@@ -73,9 +72,6 @@ int sys_vm86(unsigned long, unsigned long, struct pt_regs *);
/* X86_64 only */
/* kernel/process_64.c */
-asmlinkage long sys_clone(unsigned long, unsigned long,
- void __user *, void __user *,
- struct pt_regs *);
long sys_arch_prctl(int, unsigned long);
/* kernel/sys_x86_64.c */
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 6c2f25d..6492555 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -760,7 +760,6 @@ ptregs_##name: \
PTREGSCALL1(iopl)
PTREGSCALL0(fork)
-PTREGSCALL0(clone)
PTREGSCALL0(vfork)
PTREGSCALL3(execve)
PTREGSCALL2(sigaltstack)
@@ -769,6 +768,19 @@ PTREGSCALL0(rt_sigreturn)
PTREGSCALL2(vm86)
PTREGSCALL1(vm86old)
+/* Clone is an oddball. The 4th arg is in %edi */
+ ALIGN;
+ptregs_clone:
+ leal 4(%esp),%eax
+ pushl %eax
+ pushl PT_EDI(%eax)
+ movl PT_EDX(%eax),%ecx
+ movl PT_ECX(%eax),%edx
+ movl PT_EBX(%eax),%eax
+ call sys_clone
+ addl $8,%esp
+ ret
+
.macro FIXUP_ESPFIX_STACK
/*
* Switch back for ESPFIX stack to the normal zerobased stack
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c
index bb17bd9..f3c1a6b 100644
--- a/arch/x86/kernel/process.c
+++ b/arch/x86/kernel/process.c
@@ -234,6 +234,15 @@ int sys_vfork(struct pt_regs *regs)
NULL, NULL);
}
+long
+sys_clone(unsigned long clone_flags, unsigned long newsp,
+ void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
+{
+ if (!newsp)
+ newsp = regs->sp;
+ return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
+}
+
/*
* sys_execve() executes a new program.
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 486e38e..506d5a7 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -436,21 +436,6 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
return prev_p;
}
-int sys_clone(struct pt_regs *regs)
-{
- unsigned long clone_flags;
- unsigned long newsp;
- int __user *parent_tidptr, *child_tidptr;
-
- clone_flags = regs->bx;
- newsp = regs->cx;
- parent_tidptr = (int __user *)regs->dx;
- child_tidptr = (int __user *)regs->di;
- if (!newsp)
- newsp = regs->sp;
- return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
-}
-
#define top_esp (THREAD_SIZE - sizeof(unsigned long))
#define top_ebp (THREAD_SIZE - 2*sizeof(unsigned long))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 671960d..83019f9 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -534,15 +534,6 @@ void set_personality_64bit(void)
current->personality &= ~READ_IMPLIES_EXEC;
}
-asmlinkage long
-sys_clone(unsigned long clone_flags, unsigned long newsp,
- void __user *parent_tid, void __user *child_tid, struct pt_regs *regs)
-{
- if (!newsp)
- newsp = regs->sp;
- return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid);
-}
-
unsigned long get_wchan(struct task_struct *p)
{
unsigned long stack;
Commit-ID: ce9119ad90b1caba550447bfcc0a21850558ca49
Gitweb: http://git.kernel.org/tip/ce9119ad90b1caba550447bfcc0a21850558ca49
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 9 Dec 2009 16:33:44 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:33:44 -0800
x86-32: Avoid pipeline serialization in PTREGSCALL1 and 2
In the PTREGSCALL1 and 2 macros, we can trivially avoid an unnecessary
pipeline serialization, so do so.
In PTREGSCALLS3 this is much less clear-cut since we have to push a
new value to the stack. Leave it alone for now assuming it is as good
as it is going to be; may want to check on Atom or another in-order
x86 to see if we can do better.
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
---
arch/x86/kernel/entry_32.S | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index 6492555..cb12b9b 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -735,15 +735,15 @@ ptregs_##name: \
ALIGN; \
ptregs_##name: \
leal 4(%esp),%edx; \
- movl PT_EBX(%edx),%eax; \
+ movl (PT_EBX+4)(%esp),%eax; \
jmp sys_##name;
#define PTREGSCALL2(name) \
ALIGN; \
ptregs_##name: \
leal 4(%esp),%ecx; \
- movl PT_ECX(%ecx),%edx; \
- movl PT_EBX(%ecx),%eax; \
+ movl (PT_ECX+4)(%esp),%edx; \
+ movl (PT_EBX+4)(%esp),%eax; \
jmp sys_##name;
#define PTREGSCALL3(name) \
On 12/09/2009 04:01 PM, Brian Gerst wrote:
> This patch set converts the 32-bit syscalls that need pt_regs to
> match the same prototype as 64-bit, using regparm(3) and adding
> the pt_regs pointer as an extra argument. This allows these
> syscalls to be merged.
>
> [PATCH 1/6] x86, 32-bit: Add new pt_regs stubs
> [PATCH 2/6] x86: Merge sys_iopl
> [PATCH 3/6] x86: Merge sys_execve
> [PATCH 4/6] x86: Merge sys_sigaltstack
> [PATCH 5/6] x86, 32-bit: Convert sys_vm86 & sys_vm86old
> [PATCH 6/6] x86: Merge sys_clone
I have applied this series to tip:x86/asm with the addition of avoiding
the extra pipeline serialization; assuming it doesn't break anything we
can consider if we can push it for .33. I really like the series,
though; it is very clean and does the right thing.
-hpa
On 12/09/09 16:47, H. Peter Anvin wrote:
> I have applied this series to tip:x86/asm with the addition of avoiding
> the extra pipeline serialization; assuming it doesn't break anything we
> can consider if we can push it for .33. I really like the series,
> though; it is very clean and does the right thing.
Yep, agreed.
J
Commit-ID: fc380ceed7fe469728ea4acdbda4495ea943ee1c
Gitweb: http://git.kernel.org/tip/fc380ceed7fe469728ea4acdbda4495ea943ee1c
Author: H. Peter Anvin <[email protected]>
AuthorDate: Wed, 9 Dec 2009 16:54:08 -0800
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 9 Dec 2009 16:54:08 -0800
x86-64, paravirt: Call set_iopl_mask() on 64 bits
set_iopl_mask() is a no-op on 64 bits, but it is also a paravirt hook,
so call it even on 64 bits.
Signed-off-by: H. Peter Anvin <[email protected]>
Cc: Jeremy Fitzhardinge <[email protected]>
Cc: Brian Gerst <[email protected]>
LKML-Reference: <[email protected]>
---
arch/x86/kernel/ioport.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c
index 85ecc7c..8eec0ec 100644
--- a/arch/x86/kernel/ioport.c
+++ b/arch/x86/kernel/ioport.c
@@ -116,10 +116,8 @@ long sys_iopl(unsigned int level, struct pt_regs *regs)
return -EPERM;
}
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
-#ifdef CONFIG_X86_32
t->iopl = level << 12;
set_iopl_mask(t->iopl);
-#endif
return 0;
}