diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2012-09-16 12:06:34 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2012-10-01 00:44:44 -0400 |
| commit | d878d6dacee2c862f02da20f7fa3e2c0e8820e71 (patch) | |
| tree | c594e7cc3d49e2af55f6fe9706a2fc618dc3f150 | |
| parent | 533e6903bea0440816a0f517b0845ccea4cc7917 (diff) | |
m68k: switch to generic sys_execve()/kernel_execve()
The tricky part here is that task_pt_regs() on m68k works *only* for
process inside do_signal(). However, we need something much simpler -
pt_regs of a process inside do_signal() may be at different offsets
from the stack bottom, depending on the way we'd entered the kernel,
but for a task inside sys_execve() it *is* at constant offset.
Moreover, for a kernel thread about to become a userland process the
same location is also fine - setting sp to that will leave the kernel
stack pointer at the very bottom of the kernel stack when we finally
switch to userland.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | arch/m68k/include/asm/ptrace.h | 2 | ||||
| -rw-r--r-- | arch/m68k/include/asm/unistd.h | 2 | ||||
| -rw-r--r-- | arch/m68k/kernel/entry.S | 5 | ||||
| -rw-r--r-- | arch/m68k/kernel/process.c | 20 | ||||
| -rw-r--r-- | arch/m68k/kernel/sys_m68k.c | 17 |
5 files changed, 9 insertions, 37 deletions
diff --git a/arch/m68k/include/asm/ptrace.h b/arch/m68k/include/asm/ptrace.h index 65322b17b6cf..5e08b597f012 100644 --- a/arch/m68k/include/asm/ptrace.h +++ b/arch/m68k/include/asm/ptrace.h | |||
| @@ -85,6 +85,8 @@ struct switch_stack { | |||
| 85 | #define user_mode(regs) (!((regs)->sr & PS_S)) | 85 | #define user_mode(regs) (!((regs)->sr & PS_S)) |
| 86 | #define instruction_pointer(regs) ((regs)->pc) | 86 | #define instruction_pointer(regs) ((regs)->pc) |
| 87 | #define profile_pc(regs) instruction_pointer(regs) | 87 | #define profile_pc(regs) instruction_pointer(regs) |
| 88 | #define current_pt_regs() \ | ||
| 89 | (struct pt_regs *)((char *)current_thread_info() + THREAD_SIZE) - 1 | ||
| 88 | 90 | ||
| 89 | #define arch_has_single_step() (1) | 91 | #define arch_has_single_step() (1) |
| 90 | 92 | ||
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h index 045cfd6a9e31..c702ad716791 100644 --- a/arch/m68k/include/asm/unistd.h +++ b/arch/m68k/include/asm/unistd.h | |||
| @@ -382,6 +382,8 @@ | |||
| 382 | #define __ARCH_WANT_SYS_SIGPROCMASK | 382 | #define __ARCH_WANT_SYS_SIGPROCMASK |
| 383 | #define __ARCH_WANT_SYS_RT_SIGACTION | 383 | #define __ARCH_WANT_SYS_RT_SIGACTION |
| 384 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | 384 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND |
| 385 | #define __ARCH_WANT_SYS_EXECVE | ||
| 386 | #define __ARCH_WANT_KERNEL_EXECVE | ||
| 385 | 387 | ||
| 386 | /* | 388 | /* |
| 387 | * "Conditional" syscalls | 389 | * "Conditional" syscalls |
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index 8a01f580a024..946cb0187751 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S | |||
| @@ -122,6 +122,11 @@ ENTRY(ret_from_kernel_thread) | |||
| 122 | movel %d0,(%sp) | 122 | movel %d0,(%sp) |
| 123 | jra sys_exit | 123 | jra sys_exit |
| 124 | 124 | ||
| 125 | ENTRY(ret_from_kernel_execve) | ||
| 126 | movel 4(%sp), %sp | ||
| 127 | GET_CURRENT(%d0) | ||
| 128 | jra ret_from_exception | ||
| 129 | |||
| 125 | #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) | 130 | #if defined(CONFIG_COLDFIRE) || !defined(CONFIG_MMU) |
| 126 | 131 | ||
| 127 | #ifdef TRAP_DBG_INTERRUPT | 132 | #ifdef TRAP_DBG_INTERRUPT |
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c index b3d4760c9750..4e54b4c03081 100644 --- a/arch/m68k/kernel/process.c +++ b/arch/m68k/kernel/process.c | |||
| @@ -298,26 +298,6 @@ int dump_fpu (struct pt_regs *regs, struct user_m68kfp_struct *fpu) | |||
| 298 | EXPORT_SYMBOL(dump_fpu); | 298 | EXPORT_SYMBOL(dump_fpu); |
| 299 | #endif /* CONFIG_FPU */ | 299 | #endif /* CONFIG_FPU */ |
| 300 | 300 | ||
| 301 | /* | ||
| 302 | * sys_execve() executes a new program. | ||
| 303 | */ | ||
| 304 | asmlinkage int sys_execve(const char __user *name, | ||
| 305 | const char __user *const __user *argv, | ||
| 306 | const char __user *const __user *envp) | ||
| 307 | { | ||
| 308 | int error; | ||
| 309 | char * filename; | ||
| 310 | struct pt_regs *regs = (struct pt_regs *) &name; | ||
| 311 | |||
| 312 | filename = getname(name); | ||
| 313 | error = PTR_ERR(filename); | ||
| 314 | if (IS_ERR(filename)) | ||
| 315 | return error; | ||
| 316 | error = do_execve(filename, argv, envp, regs); | ||
| 317 | putname(filename); | ||
| 318 | return error; | ||
| 319 | } | ||
| 320 | |||
| 321 | unsigned long get_wchan(struct task_struct *p) | 301 | unsigned long get_wchan(struct task_struct *p) |
| 322 | { | 302 | { |
| 323 | unsigned long fp, pc; | 303 | unsigned long fp, pc; |
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 9a5932ec3689..3a480b3df0d6 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
| @@ -549,23 +549,6 @@ asmlinkage int sys_getpagesize(void) | |||
| 549 | return PAGE_SIZE; | 549 | return PAGE_SIZE; |
| 550 | } | 550 | } |
| 551 | 551 | ||
| 552 | /* | ||
| 553 | * Do a system call from kernel instead of calling sys_execve so we | ||
| 554 | * end up with proper pt_regs. | ||
| 555 | */ | ||
| 556 | int kernel_execve(const char *filename, | ||
| 557 | const char *const argv[], | ||
| 558 | const char *const envp[]) | ||
| 559 | { | ||
| 560 | register long __res asm ("%d0") = __NR_execve; | ||
| 561 | register long __a asm ("%d1") = (long)(filename); | ||
| 562 | register long __b asm ("%d2") = (long)(argv); | ||
| 563 | register long __c asm ("%d3") = (long)(envp); | ||
| 564 | asm volatile ("trap #0" : "+d" (__res) | ||
| 565 | : "d" (__a), "d" (__b), "d" (__c)); | ||
| 566 | return __res; | ||
| 567 | } | ||
| 568 | |||
| 569 | asmlinkage unsigned long sys_get_thread_area(void) | 552 | asmlinkage unsigned long sys_get_thread_area(void) |
| 570 | { | 553 | { |
| 571 | return current_thread_info()->tp_value; | 554 | return current_thread_info()->tp_value; |
