Skip to content

Commit

Permalink
Merge branches 'no-rebases', 'arch-avr32', 'arch-blackfin', 'arch-cri…
Browse files Browse the repository at this point in the history
…s', 'arch-h8300', 'arch-m32r', 'arch-mn10300', 'arch-score', 'arch-sh' and 'arch-powerpc' into for-next
  • Loading branch information
Al Viro committed Nov 29, 2012
11 parents d212504 + a2b6dfa + 5fd0b58 + 999121a + 1703a21 + 71915d2 + 8eae10e + ddf23e8 + 1ffbed7 + 80b249b + ab75819 commit f409132
Show file tree
Hide file tree
Showing 165 changed files with 982 additions and 2,781 deletions.
2 changes: 2 additions & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ config ARM64
select GENERIC_IOMAP
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_KERNEL_EXECVE
select GENERIC_KERNEL_THREAD
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select HARDIRQS_SW_RESEND
Expand Down
5 changes: 0 additions & 5 deletions arch/arm64/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,6 @@ unsigned long get_wchan(struct task_struct *p);
extern struct task_struct *cpu_switch_to(struct task_struct *prev,
struct task_struct *next);

/*
* Create a new kernel thread
*/
extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);

#define task_pt_regs(p) \
((struct pt_regs *)(THREAD_START_SP + task_stack_page(p)) - 1)

Expand Down
14 changes: 6 additions & 8 deletions arch/arm64/include/asm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,16 @@
/*
* System call wrappers implemented in kernel/entry.S.
*/
asmlinkage long sys_execve_wrapper(const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp);
asmlinkage long sys_clone_wrapper(unsigned long clone_flags,
unsigned long newsp,
void __user *parent_tid,
unsigned long tls_val,
void __user *child_tid);
asmlinkage long sys_rt_sigreturn_wrapper(void);
asmlinkage long sys_sigaltstack_wrapper(const stack_t __user *uss,
stack_t __user *uoss);

/*
* AArch64 sys_clone implementation has a different prototype than the generic
* one (additional TLS value argument).
*/
#define sys_clone sys_clone

#include <asm-generic/syscalls.h>

#endif /* __ASM_SYSCALLS_H */
1 change: 1 addition & 0 deletions arch/arm64/include/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@
#define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
#define __ARCH_WANT_COMPAT_SYS_SENDFILE
#endif
#define __ARCH_WANT_SYS_EXECVE
#include <uapi/asm/unistd.h>
8 changes: 4 additions & 4 deletions arch/arm64/include/asm/unistd32.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

__SYSCALL(0, sys_restart_syscall)
__SYSCALL(1, sys_exit)
__SYSCALL(2, compat_sys_fork_wrapper)
__SYSCALL(2, compat_sys_fork)
__SYSCALL(3, sys_read)
__SYSCALL(4, sys_write)
__SYSCALL(5, compat_sys_open)
Expand All @@ -32,7 +32,7 @@ __SYSCALL(7, sys_ni_syscall) /* 7 was sys_waitpid */
__SYSCALL(8, sys_creat)
__SYSCALL(9, sys_link)
__SYSCALL(10, sys_unlink)
__SYSCALL(11, compat_sys_execve_wrapper)
__SYSCALL(11, compat_sys_execve)
__SYSCALL(12, sys_chdir)
__SYSCALL(13, sys_ni_syscall) /* 13 was sys_time */
__SYSCALL(14, sys_mknod)
Expand Down Expand Up @@ -141,7 +141,7 @@ __SYSCALL(116, compat_sys_sysinfo)
__SYSCALL(117, sys_ni_syscall) /* 117 was sys_ipc */
__SYSCALL(118, sys_fsync)
__SYSCALL(119, compat_sys_sigreturn_wrapper)
__SYSCALL(120, compat_sys_clone_wrapper)
__SYSCALL(120, sys_clone)
__SYSCALL(121, sys_setdomainname)
__SYSCALL(122, sys_newuname)
__SYSCALL(123, sys_ni_syscall) /* 123 was sys_modify_ldt */
Expand Down Expand Up @@ -211,7 +211,7 @@ __SYSCALL(186, compat_sys_sigaltstack_wrapper)
__SYSCALL(187, compat_sys_sendfile)
__SYSCALL(188, sys_ni_syscall) /* 188 reserved */
__SYSCALL(189, sys_ni_syscall) /* 189 reserved */
__SYSCALL(190, compat_sys_vfork_wrapper)
__SYSCALL(190, compat_sys_vfork)
__SYSCALL(191, compat_sys_getrlimit) /* SuS compliant getrlimit */
__SYSCALL(192, sys_mmap_pgoff)
__SYSCALL(193, compat_sys_truncate64_wrapper)
Expand Down
17 changes: 5 additions & 12 deletions arch/arm64/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,7 @@ work_resched:
/*
* "slow" syscall return path.
*/
ENTRY(ret_to_user)
ret_to_user:
disable_irq // disable interrupts
ldr x1, [tsk, #TI_FLAGS]
and x2, x1, #_TIF_WORK_MASK
Expand All @@ -611,7 +611,10 @@ ENDPROC(ret_to_user)
*/
ENTRY(ret_from_fork)
bl schedule_tail
get_thread_info tsk
cbz x19, 1f // not a kernel thread
mov x0, x20
blr x19
1: get_thread_info tsk
b ret_to_user
ENDPROC(ret_from_fork)

Expand Down Expand Up @@ -673,16 +676,6 @@ __sys_trace_return:
/*
* Special system call wrappers.
*/
ENTRY(sys_execve_wrapper)
mov x3, sp
b sys_execve
ENDPROC(sys_execve_wrapper)

ENTRY(sys_clone_wrapper)
mov x5, sp
b sys_clone
ENDPROC(sys_clone_wrapper)

ENTRY(sys_rt_sigreturn_wrapper)
mov x0, sp
b sys_rt_sigreturn
Expand Down
83 changes: 30 additions & 53 deletions arch/arm64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,27 +240,41 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start,
struct pt_regs *childregs = task_pt_regs(p);
unsigned long tls = p->thread.tp_value;

*childregs = *regs;
childregs->regs[0] = 0;
memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));

if (is_compat_thread(task_thread_info(p)))
childregs->compat_sp = stack_start;
else {
if (likely(regs)) {
*childregs = *regs;
childregs->regs[0] = 0;
if (is_compat_thread(task_thread_info(p))) {
if (stack_start)
childregs->compat_sp = stack_start;
} else {
/*
* Read the current TLS pointer from tpidr_el0 as it may be
* out-of-sync with the saved value.
*/
asm("mrs %0, tpidr_el0" : "=r" (tls));
if (stack_start) {
/* 16-byte aligned stack mandatory on AArch64 */
if (stack_start & 15)
return -EINVAL;
childregs->sp = stack_start;
}
}
/*
* Read the current TLS pointer from tpidr_el0 as it may be
* out-of-sync with the saved value.
* If a TLS pointer was passed to clone (4th argument), use it
* for the new thread.
*/
asm("mrs %0, tpidr_el0" : "=r" (tls));
childregs->sp = stack_start;
if (clone_flags & CLONE_SETTLS)
tls = regs->regs[3];
} else {
memset(childregs, 0, sizeof(struct pt_regs));
childregs->pstate = PSR_MODE_EL1h;
p->thread.cpu_context.x19 = stack_start;
p->thread.cpu_context.x20 = stk_sz;
}

memset(&p->thread.cpu_context, 0, sizeof(struct cpu_context));
p->thread.cpu_context.sp = (unsigned long)childregs;
p->thread.cpu_context.pc = (unsigned long)ret_from_fork;

/* If a TLS pointer was passed to clone, use that for the new thread. */
if (clone_flags & CLONE_SETTLS)
tls = regs->regs[3];
p->thread.cpu_context.sp = (unsigned long)childregs;
p->thread.tp_value = tls;

ptrace_hw_copy_thread(p);
Expand Down Expand Up @@ -309,43 +323,6 @@ struct task_struct *__switch_to(struct task_struct *prev,
return last;
}

/*
* Shuffle the argument into the correct register before calling the
* thread function. x1 is the thread argument, x2 is the pointer to
* the thread function, and x3 points to the exit function.
*/
extern void kernel_thread_helper(void);
asm( ".section .text\n"
" .align\n"
" .type kernel_thread_helper, #function\n"
"kernel_thread_helper:\n"
" mov x0, x1\n"
" mov x30, x3\n"
" br x2\n"
" .size kernel_thread_helper, . - kernel_thread_helper\n"
" .previous");

#define kernel_thread_exit do_exit

/*
* Create a kernel thread.
*/
pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
{
struct pt_regs regs;

memset(&regs, 0, sizeof(regs));

regs.regs[1] = (unsigned long)arg;
regs.regs[2] = (unsigned long)fn;
regs.regs[3] = (unsigned long)kernel_thread_exit;
regs.pc = (unsigned long)kernel_thread_helper;
regs.pstate = PSR_MODE_EL1h;

return do_fork(flags|CLONE_VM|CLONE_UNTRACED, 0, &regs, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);

unsigned long get_wchan(struct task_struct *p)
{
struct stackframe frame;
Expand Down
76 changes: 3 additions & 73 deletions arch/arm64/kernel/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,79 +31,11 @@
*/
asmlinkage long sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, unsigned long tls_val,
int __user *child_tidptr, struct pt_regs *regs)
int __user *child_tidptr)
{
if (!newsp)
newsp = regs->sp;
/* 16-byte aligned stack mandatory on AArch64 */
if (newsp & 15)
return -EINVAL;
return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}

/*
* sys_execve() executes a new program.
*/
asmlinkage long sys_execve(const char __user *filenamei,
const char __user *const __user *argv,
const char __user *const __user *envp,
struct pt_regs *regs)
{
long error;
struct filename *filename;

filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = do_execve(filename->name, argv, envp, regs);
putname(filename);
out:
return error;
}

int kernel_execve(const char *filename,
const char *const argv[],
const char *const envp[])
{
struct pt_regs regs;
int ret;

memset(&regs, 0, sizeof(struct pt_regs));
ret = do_execve(filename,
(const char __user *const __user *)argv,
(const char __user *const __user *)envp, &regs);
if (ret < 0)
goto out;

/*
* Save argc to the register structure for userspace.
*/
regs.regs[0] = ret;

/*
* We were successful. We won't be returning to our caller, but
* instead to user space by manipulating the kernel stack.
*/
asm( "add x0, %0, %1\n\t"
"mov x1, %2\n\t"
"mov x2, %3\n\t"
"bl memmove\n\t" /* copy regs to top of stack */
"mov x27, #0\n\t" /* not a syscall */
"mov x28, %0\n\t" /* thread structure */
"mov sp, x0\n\t" /* reposition stack pointer */
"b ret_to_user"
:
: "r" (current_thread_info()),
"Ir" (THREAD_START_SP - sizeof(regs)),
"r" (&regs),
"Ir" (sizeof(regs))
: "x0", "x1", "x2", "x27", "x28", "x30", "memory");

out:
return ret;
return do_fork(clone_flags, newsp, current_pt_regs(), 0,
parent_tidptr, child_tidptr);
}
EXPORT_SYMBOL(kernel_execve);

asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags,
Expand All @@ -118,8 +50,6 @@ asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
/*
* Wrappers to pass the pt_regs argument.
*/
#define sys_execve sys_execve_wrapper
#define sys_clone sys_clone_wrapper
#define sys_rt_sigreturn sys_rt_sigreturn_wrapper
#define sys_sigaltstack sys_sigaltstack_wrapper

Expand Down
19 changes: 0 additions & 19 deletions arch/arm64/kernel/sys32.S
Original file line number Diff line number Diff line change
Expand Up @@ -26,25 +26,6 @@
/*
* System call wrappers for the AArch32 compatibility layer.
*/
compat_sys_fork_wrapper:
mov x0, sp
b compat_sys_fork
ENDPROC(compat_sys_fork_wrapper)

compat_sys_vfork_wrapper:
mov x0, sp
b compat_sys_vfork
ENDPROC(compat_sys_vfork_wrapper)

compat_sys_execve_wrapper:
mov x3, sp
b compat_sys_execve
ENDPROC(compat_sys_execve_wrapper)

compat_sys_clone_wrapper:
mov x5, sp
b compat_sys_clone
ENDPROC(compat_sys_clone_wrapper)

compat_sys_sigreturn_wrapper:
mov x0, sp
Expand Down
38 changes: 5 additions & 33 deletions arch/arm64/kernel/sys_compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,15 @@
#include <asm/cacheflush.h>
#include <asm/unistd32.h>

asmlinkage int compat_sys_fork(struct pt_regs *regs)
asmlinkage int compat_sys_fork(void)
{
return do_fork(SIGCHLD, regs->compat_sp, regs, 0, NULL, NULL);
return do_fork(SIGCHLD, 0, current_pt_regs(), 0, NULL, NULL);
}

asmlinkage int compat_sys_clone(unsigned long clone_flags, unsigned long newsp,
int __user *parent_tidptr, int tls_val,
int __user *child_tidptr, struct pt_regs *regs)
asmlinkage int compat_sys_vfork(void)
{
if (!newsp)
newsp = regs->compat_sp;

return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, child_tidptr);
}

asmlinkage int compat_sys_vfork(struct pt_regs *regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->compat_sp,
regs, 0, NULL, NULL);
}

asmlinkage int compat_sys_execve(const char __user *filenamei,
compat_uptr_t argv, compat_uptr_t envp,
struct pt_regs *regs)
{
int error;
struct filename *filename;

filename = getname(filenamei);
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
error = compat_do_execve(filename->name, compat_ptr(argv),
compat_ptr(envp), regs);
putname(filename);
out:
return error;
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0,
current_pt_regs(), 0, NULL, NULL);
}

asmlinkage int compat_sys_sched_rr_get_interval(compat_pid_t pid,
Expand Down
Loading

0 comments on commit f409132

Please sign in to comment.