Skip to content

Commit

Permalink
Merge branch 'arch-tile' into no-rebases
Browse files Browse the repository at this point in the history
  • Loading branch information
Al Viro committed Nov 17, 2012
2 parents 2482f84 + 008f179 commit 94b237b
Show file tree
Hide file tree
Showing 17 changed files with 128 additions and 200 deletions.
2 changes: 2 additions & 0 deletions arch/tile/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ config TILE
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
select MODULES_USE_ELF_RELA
select GENERIC_KERNEL_THREAD
select GENERIC_KERNEL_EXECVE

# FIXME: investigate whether we need/want these options.
# select HAVE_IOREMAP_PROT
Expand Down
15 changes: 3 additions & 12 deletions arch/tile/include/asm/compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,18 +275,14 @@ extern int compat_setup_rt_frame(int sig, struct k_sigaction *ka,
struct compat_sigaction;
struct compat_siginfo;
struct compat_sigaltstack;
long compat_sys_execve(const char __user *path,
compat_uptr_t __user *argv,
compat_uptr_t __user *envp, struct pt_regs *);
long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
struct compat_sigaction __user *oact,
size_t sigsetsize);
long compat_sys_rt_sigqueueinfo(int pid, int sig,
struct compat_siginfo __user *uinfo);
long compat_sys_rt_sigreturn(struct pt_regs *);
long compat_sys_rt_sigreturn(void);
long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr,
struct pt_regs *);
struct compat_sigaltstack __user *uoss_ptr);
long compat_sys_truncate64(char __user *filename, u32 dummy, u32 low, u32 high);
long compat_sys_ftruncate64(unsigned int fd, u32 dummy, u32 low, u32 high);
long compat_sys_pread64(unsigned int fd, char __user *ubuf, size_t count,
Expand All @@ -303,12 +299,7 @@ long compat_sys_fallocate(int fd, int mode,
long compat_sys_sched_rr_get_interval(compat_pid_t pid,
struct compat_timespec __user *interval);

/* These are the intvec_64.S trampolines. */
long _compat_sys_execve(const char __user *path,
const compat_uptr_t __user *argv,
const compat_uptr_t __user *envp);
long _compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr);
/* Assembly trampoline to avoid clobbering r0. */
long _compat_sys_rt_sigreturn(void);

#endif /* _ASM_TILE_COMPAT_H */
1 change: 1 addition & 0 deletions arch/tile/include/asm/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
#define compat_start_thread(regs, ip, usp) do { \
regs->pc = ptr_to_compat_reg((void *)(ip)); \
regs->sp = ptr_to_compat_reg((void *)(usp)); \
single_step_execve(); \
} while (0)

/*
Expand Down
4 changes: 4 additions & 0 deletions arch/tile/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ static inline void start_thread(struct pt_regs *regs,
{
regs->pc = pc;
regs->sp = usp;
single_step_execve();
}

/* Free all resources held by a thread. */
Expand Down Expand Up @@ -239,6 +240,9 @@ unsigned long get_wchan(struct task_struct *p);
#define KSTK_TOP(task) (task_ksp0(task) - STACK_TOP_DELTA)
#define task_pt_regs(task) \
((struct pt_regs *)(task_ksp0(task) - KSTK_PTREGS_GAP) - 1)
#define current_pt_regs() \
((struct pt_regs *)((stack_pointer | (THREAD_SIZE - 1)) - \
(KSTK_PTREGS_GAP - 1)) - 1)
#define task_sp(task) (task_pt_regs(task)->sp)
#define task_pc(task) (task_pt_regs(task)->pc)
/* Aliases for pc and sp (used in fs/proc/array.c) */
Expand Down
5 changes: 4 additions & 1 deletion arch/tile/include/asm/switch_to.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ extern unsigned long get_switch_to_pc(void);
/* Support function for forking a new task. */
void ret_from_fork(void);

/* Called from ret_from_fork() when a new process starts up. */
/* Support function for forking a new kernel thread. */
void ret_from_kernel_thread(void *fn, void *arg);

/* Called from ret_from_xxx() when a new process starts up. */
struct task_struct *sim_notify_fork(struct task_struct *prev);

#endif /* !__ASSEMBLY__ */
Expand Down
20 changes: 14 additions & 6 deletions arch/tile/include/asm/syscalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@ long sys_cacheflush(unsigned long addr, unsigned long len,

#ifndef __tilegx__
/* mm/fault.c */
long sys_cmpxchg_badaddr(unsigned long address, struct pt_regs *);
long _sys_cmpxchg_badaddr(unsigned long address);
long sys_cmpxchg_badaddr(unsigned long address);
#endif

#ifdef CONFIG_COMPAT
Expand All @@ -63,14 +62,23 @@ long sys_truncate64(const char __user *path, loff_t length);
long sys_ftruncate64(unsigned int fd, loff_t length);
#endif

/* Provide versions of standard syscalls that use current_pt_regs(). */
long sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid);
long sys_execve(const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp);
long sys_rt_sigreturn(void);
long sys_sigaltstack(const stack_t __user *, stack_t __user *);
#define sys_clone sys_clone
#define sys_execve sys_execve
#define sys_rt_sigreturn sys_rt_sigreturn
#define sys_sigaltstack sys_sigaltstack

/* These are the intvec*.S trampolines. */
long _sys_sigaltstack(const stack_t __user *, stack_t __user *);
long _sys_rt_sigreturn(void);
long _sys_clone(unsigned long clone_flags, unsigned long newsp,
void __user *parent_tid, void __user *child_tid);
long _sys_execve(const char __user *filename,
const char __user *const __user *argv,
const char __user *const __user *envp);

#include <asm-generic/syscalls.h>

Expand Down
1 change: 1 addition & 0 deletions arch/tile/include/asm/unistd.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@
#define __ARCH_WANT_SYS_LLSEEK
#endif
#define __ARCH_WANT_SYS_NEWFSTATAT
#define __ARCH_WANT_SYS_EXECVE
#include <uapi/asm/unistd.h>
5 changes: 2 additions & 3 deletions arch/tile/kernel/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,9 @@ long compat_sys_sched_rr_get_interval(compat_pid_t pid,
#define compat_sys_fadvise64_64 sys32_fadvise64_64
#define compat_sys_readahead sys32_readahead

/* Call the trampolines to manage pt_regs where necessary. */
#define compat_sys_execve _compat_sys_execve
#define compat_sys_sigaltstack _compat_sys_sigaltstack
/* Call the assembly trampolines where necessary. */
#define compat_sys_rt_sigreturn _compat_sys_rt_sigreturn
#undef sys_clone
#define sys_clone _sys_clone

/*
Expand Down
10 changes: 5 additions & 5 deletions arch/tile/kernel/compat_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,8 +197,7 @@ int copy_siginfo_from_user32(siginfo_t *to, struct compat_siginfo __user *from)
}

long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
struct compat_sigaltstack __user *uoss_ptr,
struct pt_regs *regs)
struct compat_sigaltstack __user *uoss_ptr)
{
stack_t uss, uoss;
int ret;
Expand All @@ -219,7 +218,7 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
set_fs(KERNEL_DS);
ret = do_sigaltstack(uss_ptr ? (stack_t __user __force *)&uss : NULL,
(stack_t __user __force *)&uoss,
(unsigned long)compat_ptr(regs->sp));
(unsigned long)compat_ptr(current_pt_regs()->sp));
set_fs(seg);
if (ret >= 0 && uoss_ptr) {
if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(*uoss_ptr)) ||
Expand All @@ -232,8 +231,9 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr,
}

/* The assembly shim for this function arranges to ignore the return value. */
long compat_sys_rt_sigreturn(struct pt_regs *regs)
long compat_sys_rt_sigreturn(void)
{
struct pt_regs *regs = current_pt_regs();
struct compat_rt_sigframe __user *frame =
(struct compat_rt_sigframe __user *) compat_ptr(regs->sp);
sigset_t set;
Expand All @@ -248,7 +248,7 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs)
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
goto badframe;

if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0)
if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL) != 0)
goto badframe;

return 0;
Expand Down
11 changes: 0 additions & 11 deletions arch/tile/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,6 @@ STD_ENTRY(current_text_addr)
{ move r0, lr; jrp lr }
STD_ENDPROC(current_text_addr)

/*
* Implement execve(). The i386 code has a note that forking from kernel
* space results in no copy on write until the execve, so we should be
* careful not to write to the stack here.
*/
STD_ENTRY(kernel_execve)
moveli TREG_SYSCALL_NR_NAME, __NR_execve
swint1
jrp lr
STD_ENDPROC(kernel_execve)

/*
* We don't run this function directly, but instead copy it to a page
* we map into every user process. See vdso_setup().
Expand Down
29 changes: 16 additions & 13 deletions arch/tile/kernel/intvec_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -1291,6 +1291,21 @@ STD_ENTRY(ret_from_fork)
}
STD_ENDPROC(ret_from_fork)

STD_ENTRY(ret_from_kernel_thread)
jal sim_notify_fork
jal schedule_tail
FEEDBACK_REENTER(ret_from_fork)
{
move r0, r31
jalr r30
}
FEEDBACK_REENTER(ret_from_kernel_thread)
{
movei r30, 0 /* not an NMI */
j .Lresume_userspace /* jump into middle of interrupt_return */
}
STD_ENDPROC(ret_from_kernel_thread)

/*
* Code for ill interrupt.
*/
Expand Down Expand Up @@ -1437,15 +1452,6 @@ STD_ENTRY_LOCAL(bad_intr)
panic "Unhandled interrupt %#x: PC %#lx"
STD_ENDPROC(bad_intr)

/* Put address of pt_regs in reg and jump. */
#define PTREGS_SYSCALL(x, reg) \
STD_ENTRY(_##x); \
{ \
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
j x \
}; \
STD_ENDPROC(_##x)

/*
* Special-case sigreturn to not write r0 to the stack on return.
* This is technically more efficient, but it also avoids difficulties
Expand All @@ -1461,12 +1467,9 @@ STD_ENTRY_LOCAL(bad_intr)
}; \
STD_ENDPROC(_##x)

PTREGS_SYSCALL(sys_execve, r3)
PTREGS_SYSCALL(sys_sigaltstack, r2)
PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1)

/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
/* Save additional callee-saves to pt_regs and jump to standard function. */
STD_ENTRY(_sys_clone)
push_extra_callee_saves r4
j sys_clone
Expand Down
30 changes: 16 additions & 14 deletions arch/tile/kernel/intvec_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,21 @@ STD_ENTRY(ret_from_fork)
}
STD_ENDPROC(ret_from_fork)

STD_ENTRY(ret_from_kernel_thread)
jal sim_notify_fork
jal schedule_tail
FEEDBACK_REENTER(ret_from_fork)
{
move r0, r31
jalr r30
}
FEEDBACK_REENTER(ret_from_kernel_thread)
{
movei r30, 0 /* not an NMI */
j .Lresume_userspace /* jump into middle of interrupt_return */
}
STD_ENDPROC(ret_from_kernel_thread)

/* Various stub interrupt handlers and syscall handlers */

STD_ENTRY_LOCAL(_kernel_double_fault)
Expand All @@ -1166,15 +1181,6 @@ STD_ENTRY_LOCAL(bad_intr)
panic "Unhandled interrupt %#x: PC %#lx"
STD_ENDPROC(bad_intr)

/* Put address of pt_regs in reg and jump. */
#define PTREGS_SYSCALL(x, reg) \
STD_ENTRY(_##x); \
{ \
PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \
j x \
}; \
STD_ENDPROC(_##x)

/*
* Special-case sigreturn to not write r0 to the stack on return.
* This is technically more efficient, but it also avoids difficulties
Expand All @@ -1190,16 +1196,12 @@ STD_ENTRY_LOCAL(bad_intr)
}; \
STD_ENDPROC(_##x)

PTREGS_SYSCALL(sys_execve, r3)
PTREGS_SYSCALL(sys_sigaltstack, r2)
PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0)
#ifdef CONFIG_COMPAT
PTREGS_SYSCALL(compat_sys_execve, r3)
PTREGS_SYSCALL(compat_sys_sigaltstack, r2)
PTREGS_SYSCALL_SIGRETURN(compat_sys_rt_sigreturn, r0)
#endif

/* Save additional callee-saves to pt_regs, put address in r4 and jump. */
/* Save additional callee-saves to pt_regs and jump to standard function. */
STD_ENTRY(_sys_clone)
push_extra_callee_saves r4
j sys_clone
Expand Down
Loading

0 comments on commit 94b237b

Please sign in to comment.