Commit de25c71c authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Broken, but working, ptregs system call conversion for x86-64


Not-yet-signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 3621644d
......@@ -284,9 +284,7 @@ __visible void do_syscall_64(unsigned long nr, struct pt_regs *regs)
nr &= __SYSCALL_MASK;
if (likely(nr < NR_syscalls)) {
nr = array_index_nospec(nr, NR_syscalls);
regs->ax = sys_call_table[nr](
regs->di, regs->si, regs->dx,
regs->r10, regs->r8, regs->r9);
regs->ax = sys_call_table[nr](regs);
}
syscall_return_slowpath(regs);
......@@ -327,10 +325,7 @@ static __always_inline void do_syscall_32_irqs_on(struct pt_regs *regs)
* the high bits are zero. Make sure we zero-extend all
* of the args.
*/
regs->ax = ia32_sys_call_table[nr](
(unsigned int)regs->bx, (unsigned int)regs->cx,
(unsigned int)regs->dx, (unsigned int)regs->si,
(unsigned int)regs->di, (unsigned int)regs->bp);
regs->ax = ia32_sys_call_table[nr](regs);
}
syscall_return_slowpath(regs);
......
......@@ -7,13 +7,13 @@
#include <asm/asm-offsets.h>
#include <asm/syscall.h>
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long) ;
#define __SYSCALL_I386(nr, sym, qual) extern asmlinkage long sym(struct pt_regs *);
#include <asm/syscalls_32.h>
#undef __SYSCALL_I386
#define __SYSCALL_I386(nr, sym, qual) [nr] = sym,
extern asmlinkage long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
extern asmlinkage long sys_ni_syscall(struct pt_regs *);
__visible const sys_call_ptr_t ia32_sys_call_table[__NR_syscall_compat_max+1] = {
/*
......
......@@ -7,13 +7,13 @@
#include <asm/asm-offsets.h>
#include <asm/syscall.h>
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(struct pt_regs *);
#include <asm/syscalls_64.h>
#undef __SYSCALL_64
#define __SYSCALL_64(nr, sym, qual) [nr] = sym,
extern long sys_ni_syscall(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long, unsigned long);
extern long sys_ni_syscall(struct pt_regs *);
asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {
/*
......
This diff is collapsed.
This diff is collapsed.
......@@ -20,9 +20,7 @@
#include <asm/thread_info.h> /* for TS_COMPAT */
#include <asm/unistd.h>
typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,
unsigned long, unsigned long,
unsigned long, unsigned long);
typedef asmlinkage long (*sys_call_ptr_t)(struct pt_regs *);
extern const sys_call_ptr_t sys_call_table[];
#if defined(CONFIG_X86_32)
......
......@@ -23,7 +23,7 @@
/*
* this changes the io permissions bitmap in the current task.
*/
asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
SYSCALL_DEFINE3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
{
struct thread_struct *t = &current->thread;
struct tss_struct *tss;
......
......@@ -25,6 +25,7 @@
#include <linux/user-return-notifier.h>
#include <linux/uprobes.h>
#include <linux/context_tracking.h>
#include <linux/syscalls.h>
#include <asm/processor.h>
#include <asm/ucontext.h>
......@@ -601,7 +602,7 @@ static int x32_setup_rt_frame(struct ksignal *ksig,
* Do a signal return; undo the signal stack.
*/
#ifdef CONFIG_X86_32
asmlinkage unsigned long sys_sigreturn(void)
SYSCALL_DEFINE0(sys_sigreturn)
{
struct pt_regs *regs = current_pt_regs();
struct sigframe __user *frame;
......@@ -633,7 +634,7 @@ asmlinkage unsigned long sys_sigreturn(void)
}
#endif /* CONFIG_X86_32 */
asmlinkage long sys_rt_sigreturn(void)
SYSCALL_DEFINE0(rt_sigreturn)
{
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;
......
......@@ -350,7 +350,7 @@ SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
* We do this by temporarily clearing all FS-related capabilities and
* switching the fsuid/fsgid around to the real ones.
*/
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
static long vfs_faccessat(int dfd, const char __user *filename, int mode)
{
const struct cred *old_cred;
struct cred *override_cred;
......@@ -426,9 +426,14 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
return res;
}
SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
{
return vfs_faccessat(dfd, filename, mode);
}
SYSCALL_DEFINE2(access, const char __user *, filename, int, mode)
{
return sys_faccessat(AT_FDCWD, filename, mode);
return vfs_faccessat(AT_FDCWD, filename, mode);
}
SYSCALL_DEFINE1(chdir, const char __user *, filename)
......@@ -554,7 +559,7 @@ SYSCALL_DEFINE2(fchmod, unsigned int, fd, umode_t, mode)
return err;
}
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
static long vfs_fchmodat(int dfd, const char __user *filename, umode_t mode)
{
struct path path;
int error;
......@@ -572,9 +577,14 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode
return error;
}
SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode)
{
return vfs_fchmodat(dfd, filename, mode);
}
SYSCALL_DEFINE2(chmod, const char __user *, filename, umode_t, mode)
{
return sys_fchmodat(AT_FDCWD, filename, mode);
return vfs_fchmodat(AT_FDCWD, filename, mode);
}
static int chown_common(const struct path *path, uid_t user, gid_t group)
......@@ -619,8 +629,7 @@ static int chown_common(const struct path *path, uid_t user, gid_t group)
return error;
}
SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
gid_t, group, int, flag)
static long vfs_fchownat(int dfd, const char __user * filename, uid_t user, gid_t group, int flag)
{
struct path path;
int error = -EINVAL;
......@@ -651,15 +660,20 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
return error;
}
SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
gid_t, group, int, flag)
{
return vfs_fchownat(dfd, filename, user, group, flag);
}
SYSCALL_DEFINE3(chown, const char __user *, filename, uid_t, user, gid_t, group)
{
return sys_fchownat(AT_FDCWD, filename, user, group, 0);
return vfs_fchownat(AT_FDCWD, filename, user, group, 0);
}
SYSCALL_DEFINE3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
{
return sys_fchownat(AT_FDCWD, filename, user, group,
AT_SYMLINK_NOFOLLOW);
return vfs_fchownat(AT_FDCWD, filename, user, group, AT_SYMLINK_NOFOLLOW);
}
SYSCALL_DEFINE3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
......@@ -1114,7 +1128,12 @@ COMPAT_SYSCALL_DEFINE4(openat, int, dfd, const char __user *, filename, int, fla
*/
SYSCALL_DEFINE2(creat, const char __user *, pathname, umode_t, mode)
{
return sys_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode);
int flags = O_CREAT | O_WRONLY | O_TRUNC;
if (force_o_largefile())
flags |= O_LARGEFILE;
return do_sys_open(AT_FDCWD, pathname, flags, mode);
}
#endif
......@@ -1150,7 +1169,7 @@ EXPORT_SYMBOL(filp_close);
* releasing the fd. This ensures that one clone task can't release
* an fd while another clone is opening it.
*/
SYSCALL_DEFINE1(close, unsigned int, fd)
long vfs_close(unsigned int fd)
{
int retval = __close_fd(current->files, fd);
......@@ -1163,7 +1182,13 @@ SYSCALL_DEFINE1(close, unsigned int, fd)
return retval;
}
EXPORT_SYMBOL(sys_close);
EXPORT_SYMBOL(vfs_close);
SYSCALL_DEFINE1(close, unsigned int, fd)
{
return vfs_close(fd);
}
/*
* This routine simulates a hangup on the tty, to arrange that users
......
......@@ -32,7 +32,7 @@
#endif
#define COMPAT_SYSCALL_DEFINE0(name) \
asmlinkage long compat_sys_##name(void)
asmlinkage long compat_sys_i86_##sname(void)
#define COMPAT_SYSCALL_DEFINE1(name, ...) \
COMPAT_SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
......@@ -56,6 +56,16 @@
{ \
return C_SYSC##name(__MAP(x,__SC_DELOUSE,__VA_ARGS__)); \
} \
asmlinkage long compat_sys_i86##name(struct pt_regs *regs) \
{ \
return compat_SyS##name(__MAP(x,__SC_ARGS \
,,(unsigned int)regs->bx \
,,(unsigned int)regs->cx \
,,(unsigned int)regs->dx \
,,(unsigned int)regs->si \
,,(unsigned int)regs->di \
,,(unsigned int)regs->bp)); \
} \
static inline long C_SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
#ifndef compat_user_stack_pointer
......
......@@ -91,7 +91,7 @@ union bpf_attr;
* for SYSCALL_DEFINE<n>/COMPAT_SYSCALL_DEFINE<n>
*/
#define __MAP0(m,...)
#define __MAP1(m,t,a) m(t,a)
#define __MAP1(m,t,a,...) m(t,a)
#define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__)
#define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__)
#define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__)
......@@ -189,8 +189,12 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
}
#endif
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
#define SYSCALL_DEFINE0(sname) \
SYSCALL_METADATA(_##sname, 0); \
asmlinkage long sys_i86_##sname(void) \
__attribute__((alias(__stringify(sys_##sname)))); \
asmlinkage long sys_x64_##sname(void) \
__attribute__((alias(__stringify(sys_##sname)))); \
asmlinkage long sys_##sname(void)
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
......@@ -211,7 +215,6 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) \
__attribute__((alias(__stringify(SyS##name)))); \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \
asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \
{ \
long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \
......@@ -219,6 +222,22 @@ static inline int is_syscall_trace_event(struct trace_event_call *tp_event)
__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \
return ret; \
} \
asmlinkage long sys_x64##name(struct pt_regs *regs) \
{ \
return SyS##name(__MAP(x,__SC_ARGS \
,,regs->di,,regs->si,,regs->dx \
,,regs->r10,,regs->r8,,regs->r9)); \
} \
asmlinkage long sys_i86##name(struct pt_regs *regs) \
{ \
return SyS##name(__MAP(x,__SC_ARGS \
,,(unsigned int)regs->bx \
,,(unsigned int)regs->cx \
,,(unsigned int)regs->dx \
,,(unsigned int)regs->si \
,,(unsigned int)regs->di \
,,(unsigned int)regs->bp)); \
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
/*
......
......@@ -4885,14 +4885,14 @@ SYSCALL_DEFINE3(sched_getaffinity, pid_t, pid, unsigned int, len,
}
/**
* sys_sched_yield - yield the current processor to other threads.
* sched_yield - yield the current processor to other threads.
*
* This function yields the current CPU to other tasks. If there are no
* other threads running on this CPU then this function will return.
*
* Return: 0.
*/
SYSCALL_DEFINE0(sched_yield)
static long sched_yield(void)
{
struct rq_flags rf;
struct rq *rq;
......@@ -4917,6 +4917,11 @@ SYSCALL_DEFINE0(sched_yield)
return 0;
}
SYSCALL_DEFINE0(sched_yield)
{
return sched_yield();
}
#ifndef CONFIG_PREEMPT
int __sched _cond_resched(void)
{
......@@ -4997,7 +5002,7 @@ EXPORT_SYMBOL(__cond_resched_softirq);
void __sched yield(void)
{
set_current_state(TASK_RUNNING);
sys_sched_yield();
sched_yield();
}
EXPORT_SYMBOL(yield);
......
......@@ -3573,9 +3573,8 @@ int __save_altstack(stack_t __user *uss, unsigned long sp)
}
#ifdef CONFIG_COMPAT
COMPAT_SYSCALL_DEFINE2(sigaltstack,
const compat_stack_t __user *, uss_ptr,
compat_stack_t __user *, uoss_ptr)
static long do_compat_sigaltstack(const compat_stack_t __user *uss_ptr,
compat_stack_t __user *uoss_ptr)
{
stack_t uss, uoss;
int ret;
......@@ -3602,9 +3601,16 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack,
return ret;
}
COMPAT_SYSCALL_DEFINE2(sigaltstack,
const compat_stack_t __user *, uss_ptr,
compat_stack_t __user *, uoss_ptr)
{
return do_compat_sigaltstack(uss_ptr, uoss_ptr);
}
int compat_restore_altstack(const compat_stack_t __user *uss)
{
int err = compat_sys_sigaltstack(uss, NULL);
int err = do_compat_sigaltstack(uss, NULL);
/* squash all but -EFAULT for now */
return err == -EFAULT ? err : 0;
}
......
......@@ -17,6 +17,10 @@ asmlinkage long sys_ni_syscall(void)
return -ENOSYS;
}
cond_syscall(sys_x64_kcmp);
cond_syscall(sys_i86_uselib);
cond_syscall(sys_i86_kcmp);
cond_syscall(sys_quotactl);
cond_syscall(sys32_quotactl);
cond_syscall(sys_acct);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment