Commit 6b14e419 authored by Chris Metcalf's avatar Chris Metcalf Committed by Al Viro
Browse files

arch/tile: eliminate pt_regs trampolines for syscalls



Using the new current_pt_regs() model, we can remove some trampolines
from assembly code and call directly to the C syscall implementations.
rt_sigreturn() and clone() still need some assembly wrapping, but no
longer are passed a pt_regs pointer.  sigaltstack() and the
tilepro-specific cmpxchg_badaddr() syscalls are now just straight C.

Signed-off-by: default avatarChris Metcalf <cmetcalf@tilera.com>
parent 53055065
Loading
Loading
Loading
Loading
+3 −6
Original line number Diff line number Diff line
@@ -280,10 +280,9 @@ long compat_sys_rt_sigaction(int sig, struct compat_sigaction __user *act,
			     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,
@@ -300,9 +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_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 */
+13 −6
Original line number Diff line number Diff line
@@ -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
@@ -63,15 +62,23 @@ long sys_truncate64(const char __user *path, loff_t length);
long sys_ftruncate64(unsigned int fd, loff_t length);
#endif

/* 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,
/* 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_rt_sigreturn(void);
long _sys_clone(unsigned long clone_flags, unsigned long newsp,
		void __user *parent_tid, void __user *child_tid);

#include <asm-generic/syscalls.h>

+2 −2
Original line number Diff line number Diff line
@@ -102,9 +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_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

/*
+5 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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)) ||
@@ -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;
@@ -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;
+1 −12
Original line number Diff line number Diff line
@@ -1452,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
@@ -1476,11 +1467,9 @@ STD_ENTRY_LOCAL(bad_intr)
	};                                              \
	STD_ENDPROC(_##x)

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
Loading