lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1332787168-20457-3-git-send-email-vnagarnaik@google.com>
Date:	Mon, 26 Mar 2012 11:39:24 -0700
From:	Vaibhav Nagarnaik <vnagarnaik@...gle.com>
To:	Steven Rostedt <rostedt@...dmis.org>,
	Frederic Weisbecker <fweisbec@...il.com>,
	Thomas Gleixner <tglx@...utronix.de>,
	Ingo Molnar <mingo@...hat.com>
Cc:	David Sharp <dhsharp@...gle.com>,
	Justin Teravest <teravest@...gle.com>,
	Laurent Chavey <chavey@...gle.com>, x86@...nel.org,
	linux-kernel@...r.kernel.org, Michael Davidson <md@...gle.com>,
	Vaibhav Nagarnaik <vnagarnaik@...gle.com>
Subject: [PATCH 2/6] trace: add support for 32 bit compat syscalls on x86_64

From: Michael Davidson <md@...gle.com>

Add support for a set of events to trace 32 bit compat system calls
in addition to the native 64 bit system calls.

Events for compat system calls have event names of the form:
  syscalls:sys_enter_compat_<name>
  syscalls:sys_exit_compat_<name>

The ascii formatted version of trace events that can be read from
the tracing/trace file reports compat system calls as:
  compat_<name>(...)

- add CONFIG_FTRACE_COMPAT_SYSCALLS

- add a "compat" flag to the syscall_metadata struct so that we can
  distinguish between "native" and "compat" metadata at init time
  when building the system call # to metadata mapping tables

- add a COMPAT_SYSCALL_METADATAx() macro to define system call
  metadata for compat system calls

- define a set of COMPAT_SYSCALL_METADATA[0-6] macros

- modify syscall_nr_to_meta() to know about compat system calls
  and return a pointer to the correct metadata

- modify print_syscall_{enter|exit}() to find the system call metadata
  by looking in the containing ftrace_event_call struct

- add system call metadata definitions for the x86_64 32 bit compat
  system calls

Signed-off-by: Vaibhav Nagarnaik <vnagarnaik@...gle.com>
---
 arch/x86/ia32/Makefile                |    2 +
 arch/x86/ia32/ia32_syscall_metadata.c |  443 +++++++++++++++++++++++++++++++++
 fs/dcookies.c                         |    2 +-
 fs/open.c                             |    2 +-
 fs/read_write.c                       |    8 +-
 fs/sync.c                             |    8 +-
 include/linux/syscalls.h              |   24 ++-
 include/trace/syscall.h               |   18 ++-
 kernel/trace/Kconfig                  |    6 +
 kernel/trace/trace_syscalls.c         |   24 ++-
 mm/fadvise.c                          |    5 +-
 mm/filemap.c                          |    2 +-
 12 files changed, 521 insertions(+), 23 deletions(-)
 create mode 100644 arch/x86/ia32/ia32_syscall_metadata.c

diff --git a/arch/x86/ia32/Makefile b/arch/x86/ia32/Makefile
index 455646e..ba6d3c8 100644
--- a/arch/x86/ia32/Makefile
+++ b/arch/x86/ia32/Makefile
@@ -12,3 +12,5 @@ obj-$(CONFIG_IA32_AOUT) += ia32_aout.o
 
 audit-class-$(CONFIG_AUDIT) := audit.o
 obj-$(CONFIG_IA32_EMULATION) += $(audit-class-y)
+
+obj-$(CONFIG_FTRACE_COMPAT_SYSCALLS) += ia32_syscall_metadata.o
diff --git a/arch/x86/ia32/ia32_syscall_metadata.c b/arch/x86/ia32/ia32_syscall_metadata.c
new file mode 100644
index 0000000..8001794
--- /dev/null
+++ b/arch/x86/ia32/ia32_syscall_metadata.c
@@ -0,0 +1,443 @@
+#include <linux/slab.h>
+#include <linux/syscalls.h>
+#include <linux/module.h>
+#include <asm/asm-offsets.h>
+
+/*
+ * syscall metadata for 32 bit compatible system calls
+ *
+ * The metadata entries are in the same order as the system call table
+ * but this is just to make it easier to check them for completeness
+ * and correctness.
+ */
+
+COMPAT_SYSCALL_METADATA0(restart_syscall)
+COMPAT_SYSCALL_METADATA1(exit, int, error_code)
+/* fork */
+COMPAT_SYSCALL_METADATA3(read, unsigned int, fd, char __user *, buf, size_t, count)
+COMPAT_SYSCALL_METADATA3(write, unsigned int, fd, const char __user *, buf, size_t, count)
+COMPAT_SYSCALL_METADATA3(open, const char __user *, filename, int, flags, int, mode)
+COMPAT_SYSCALL_METADATA1(close, unsigned int, fd)
+COMPAT_SYSCALL_METADATA3(waitpid, compat_pid_t, pid, int __user *, stat_addr, int, options)
+COMPAT_SYSCALL_METADATA2(creat, const char __user *, pathname, int, mode)
+COMPAT_SYSCALL_METADATA2(link, const char __user *, oldname, const char __user *, newname)
+COMPAT_SYSCALL_METADATA1(unlink, const char __user *, pathname)
+/* execve */
+COMPAT_SYSCALL_METADATA1(chdir, const char __user *, filename)
+COMPAT_SYSCALL_METADATA1(time, compat_time_t __user *, tloc)
+COMPAT_SYSCALL_METADATA3(mknod, const char __user *, filename, int, mode, unsigned, dev)
+COMPAT_SYSCALL_METADATA2(chmod, const char __user *, filename, mode_t, mode)
+COMPAT_SYSCALL_METADATA3(lchown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
+/* ni */
+COMPAT_SYSCALL_METADATA2(stat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA3(lseek, unsigned int, fd, int, offset, unsigned int, whence)
+COMPAT_SYSCALL_METADATA0(getpid)
+COMPAT_SYSCALL_METADATA5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data)
+COMPAT_SYSCALL_METADATA1(oldumount, char __user *, name)
+COMPAT_SYSCALL_METADATA1(setuid16, old_uid_t, uid)
+COMPAT_SYSCALL_METADATA0(getuid16)
+COMPAT_SYSCALL_METADATA1(stime, compat_time_t __user *, tptr)
+COMPAT_SYSCALL_METADATA4(ptrace, compat_long_t, request, compat_long_t, pid, compat_long_t, addr, compat_long_t, data)
+COMPAT_SYSCALL_METADATA1(alarm, unsigned int, seconds)
+COMPAT_SYSCALL_METADATA2(fstat, unsigned int, fd, struct __old_kernel_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA0(pause)
+COMPAT_SYSCALL_METADATA2(utime, char __user *, filename, struct compat_utimbuf __user *, times)
+/* ni */
+/* ni */
+COMPAT_SYSCALL_METADATA2(access, const char __user *, filename, int, mode)
+COMPAT_SYSCALL_METADATA1(nice, int, increment)
+/* ni */
+COMPAT_SYSCALL_METADATA0(sync)
+COMPAT_SYSCALL_METADATA2(kill, int, pid, int, sig)
+COMPAT_SYSCALL_METADATA2(rename, const char __user *, oldname, const char __user *, newname)
+COMPAT_SYSCALL_METADATA2(mkdir, const char __user *, pathname, int, mode)
+COMPAT_SYSCALL_METADATA1(rmdir, const char __user *, pathname)
+COMPAT_SYSCALL_METADATA1(dup, unsigned int, fildes)
+COMPAT_SYSCALL_METADATA1(pipe, int __user *, fildes)
+COMPAT_SYSCALL_METADATA1(times, struct compat_tms __user *, tbuf)
+/* ni */
+COMPAT_SYSCALL_METADATA1(brk, unsigned long, brk)
+COMPAT_SYSCALL_METADATA1(setgid16, old_gid_t, gid)
+COMPAT_SYSCALL_METADATA0(getgid16)
+COMPAT_SYSCALL_METADATA2(signal, int, sig, __sighandler_t, handler)
+COMPAT_SYSCALL_METADATA0(geteuid16)
+COMPAT_SYSCALL_METADATA0(getegid16)
+COMPAT_SYSCALL_METADATA1(acct, const char __user *, name)
+COMPAT_SYSCALL_METADATA2(umount, char __user *, name, int, flags)
+/* ni */
+COMPAT_SYSCALL_METADATA3(ioctl, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
+/* ni */
+COMPAT_SYSCALL_METADATA2(setpgid, pid_t, pid, pid_t, pgid)
+/* ni */
+COMPAT_SYSCALL_METADATA1(olduname, struct oldold_utsname __user *, name)
+COMPAT_SYSCALL_METADATA1(umask, int, mask)
+COMPAT_SYSCALL_METADATA1(chroot, const char __user *, filename)
+COMPAT_SYSCALL_METADATA2(ustat, unsigned, dev, struct compat_ustat __user *, ubuf)
+COMPAT_SYSCALL_METADATA2(dup2, unsigned int, oldfd, unsigned int, newfd)
+COMPAT_SYSCALL_METADATA0(getppid)
+COMPAT_SYSCALL_METADATA0(getpgrp)
+COMPAT_SYSCALL_METADATA0(setsid)
+COMPAT_SYSCALL_METADATA3(sigaction, int, sig, struct old_sigaction32 __user *, act, struct old_sigaction32 __user *, oact)
+COMPAT_SYSCALL_METADATA0(sgetmask)
+COMPAT_SYSCALL_METADATA1(ssetmask, int, newmask)
+COMPAT_SYSCALL_METADATA2(setreuid16, old_uid_t, ruid, old_uid_t, euid)
+COMPAT_SYSCALL_METADATA2(setregid16, old_gid_t, rgid, old_gid_t, egid)
+COMPAT_SYSCALL_METADATA3(sigsuspend, int, history0, int, history1, old_sigset_t, mask)
+COMPAT_SYSCALL_METADATA1(sigpending, compat_old_sigset_t __user *, set)
+COMPAT_SYSCALL_METADATA2(sethostname, char __user *, name, int, len)
+COMPAT_SYSCALL_METADATA2(setrlimit, unsigned int, resource, struct compat_rlimit __user *, rlim)
+COMPAT_SYSCALL_METADATA2(old_getrlimit, unsigned int, resource, struct compat_rlimit __user *, rlim)
+COMPAT_SYSCALL_METADATA2(getrusage, int, who, struct compat_rusage __user *, ru)
+COMPAT_SYSCALL_METADATA2(gettimeofday, struct compat_timeval __user *, tv, struct timezone __user *, tz)
+COMPAT_SYSCALL_METADATA2(settimeofday, struct compat_timeval __user *, tv, struct timezone __user *, tz)
+COMPAT_SYSCALL_METADATA2(getgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
+COMPAT_SYSCALL_METADATA2(setgroups16, int, gidsetsize, old_gid_t __user *, grouplist)
+COMPAT_SYSCALL_METADATA1(old_select, struct compat_sel_arg_struct __user *, arg)
+COMPAT_SYSCALL_METADATA2(symlink, const char __user *, oldname, const char __user *, newname)
+COMPAT_SYSCALL_METADATA2(lstat, char __user *, filename, struct __old_kernel_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA3(readlink, const char __user *, path, char __user *, buf, int, bufsiz)
+COMPAT_SYSCALL_METADATA1(uselib, const char __user *, library)
+COMPAT_SYSCALL_METADATA2(swapon, const char __user *, specialfile, int, swap_flags)
+COMPAT_SYSCALL_METADATA4(reboot, int, magic1, int, magic2, unsigned int, cmd, void __user *, arg)
+COMPAT_SYSCALL_METADATA3(old_readdir, unsigned int, fd, struct compat_old_linux_dirent __user *, dirent, unsigned int, count)
+COMPAT_SYSCALL_METADATA1(mmap, struct mmap_arg_struct32 __user *, arg)
+COMPAT_SYSCALL_METADATA2(munmap, unsigned long, addr, size_t, len)
+COMPAT_SYSCALL_METADATA2(truncate, const char __user *, path, long, length)
+COMPAT_SYSCALL_METADATA2(ftruncate, unsigned int, fd, unsigned long, length)
+COMPAT_SYSCALL_METADATA2(fchmod, unsigned int, fd, mode_t, mode)
+COMPAT_SYSCALL_METADATA3(fchown16, unsigned int, fd, old_uid_t, user, old_gid_t, group)
+COMPAT_SYSCALL_METADATA2(getpriority, int, which, int, who)
+COMPAT_SYSCALL_METADATA3(setpriority, int, which, int, who, int, niceval)
+/* ni */
+COMPAT_SYSCALL_METADATA2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf)
+COMPAT_SYSCALL_METADATA2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf)
+COMPAT_SYSCALL_METADATA3(ioperm, unsigned long, from, unsigned long, num, int, turn_on)
+COMPAT_SYSCALL_METADATA2(socketcall, int, call, u32 __user *, args)
+COMPAT_SYSCALL_METADATA3(syslog, int, type, char __user *, buf, int, len)
+COMPAT_SYSCALL_METADATA3(setitimer, int, which, struct compat_itimerval __user *, in, struct compat_itimerval __user *, out)
+COMPAT_SYSCALL_METADATA2(getitimer, int, which, struct compat_itimerval __user *, it)
+COMPAT_SYSCALL_METADATA2(newstat, char __user *, filename, struct compat_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA2(newlstat, char __user *, filename, struct compat_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA2(newfstat, unsigned int, fd, struct compat_stat __user *, statbuf)
+COMPAT_SYSCALL_METADATA1(uname, struct old_utsname __user *, name)
+COMPAT_SYSCALL_METADATA1(iopl, unsigned int, level)
+COMPAT_SYSCALL_METADATA0(vhangup)
+/* ni */
+/* sys32_vm86_warning */
+COMPAT_SYSCALL_METADATA4(wait4, compat_pid_t, pid, compat_uint_t __user *, stat_addr, int, options, struct compat_rusage __user *, ru)
+COMPAT_SYSCALL_METADATA1(swapoff, const char __user *, specialfile)
+COMPAT_SYSCALL_METADATA1(sysinfo, struct compat_sysinfo __user *, info)
+COMPAT_SYSCALL_METADATA6(ipc, u32, call, int, first, int, second, int, third, compat_uptr_t, ptr, u32, fifth)
+COMPAT_SYSCALL_METADATA1(fsync, unsigned int, fd)
+/* stub32_sigreturn */
+/* stub32_clone */
+COMPAT_SYSCALL_METADATA2(setdomainname, char __user *, name, int, len)
+COMPAT_SYSCALL_METADATA1(newuname, struct new_utsname __user *, name)
+/* sys_modify_ldt */
+COMPAT_SYSCALL_METADATA1(adjtimex, struct compat_timex __user *, utp)
+COMPAT_SYSCALL_METADATA3(mprotect, unsigned long, start, size_t, len, unsigned long, prot)
+COMPAT_SYSCALL_METADATA3(sigprocmask, int, how, compat_old_sigset_t __user *, set, compat_old_sigset_t __user *, oset)
+/* ni */
+COMPAT_SYSCALL_METADATA3(init_module, void __user *, umod, unsigned long, len, const char __user *, uargs)
+COMPAT_SYSCALL_METADATA2(delete_module, const char __user *, name_user, unsigned int, flags)
+/* ni */
+COMPAT_SYSCALL_METADATA4(quotactl, unsigned int, cmd, const char __user *, special, qid_t, id, void __user *, addr)
+COMPAT_SYSCALL_METADATA1(getpgid, pid_t, pid)
+COMPAT_SYSCALL_METADATA1(fchdir, unsigned int, fd)
+/* ni */
+COMPAT_SYSCALL_METADATA3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2)
+COMPAT_SYSCALL_METADATA1(personality, u_long, personality)
+/* ni */
+COMPAT_SYSCALL_METADATA1(setfsuid16, old_uid_t, uid)
+COMPAT_SYSCALL_METADATA1(setfsgid16, old_gid_t, gid)
+COMPAT_SYSCALL_METADATA5(llseek, unsigned int, fd, unsigned long, offset_high, unsigned long, offset_low, loff_t __user *, result, unsigned int, origin)
+COMPAT_SYSCALL_METADATA3(getdents, unsigned int, fd, struct compat_linux_dirent __user *, dirent, unsigned int, count)
+COMPAT_SYSCALL_METADATA5(select, int, n, compat_ulong_t __user *, inp, compat_ulong_t __user *, outp, compat_ulong_tt __user *, exp, struct compat_timeval __user *, tvp)
+COMPAT_SYSCALL_METADATA2(flock, unsigned int, fd, unsigned int, cmd)
+COMPAT_SYSCALL_METADATA3(msync, unsigned long, start, size_t, len, int, flags)
+COMPAT_SYSCALL_METADATA3(readv, unsigned long, fd, const struct compat_iovec __user *, vec, unsigned long, vlen)
+COMPAT_SYSCALL_METADATA3(writev, unsigned long, fd, const struct compat_iovec __user *, vec, unsigned long, vlen)
+COMPAT_SYSCALL_METADATA1(getsid, pid_t, pid)
+COMPAT_SYSCALL_METADATA1(fdatasync, unsigned int, fd)
+COMPAT_SYSCALL_METADATA1(sysctl, struct compat_sysctl_args __user *, args)
+COMPAT_SYSCALL_METADATA2(mlock, unsigned long, start, size_t, len)
+COMPAT_SYSCALL_METADATA1(mlockall, int, flags)
+COMPAT_SYSCALL_METADATA2(munlock, unsigned long, start, size_t, len)
+COMPAT_SYSCALL_METADATA0(munlockall)
+COMPAT_SYSCALL_METADATA2(sched_setparam, pid_t, pid, struct sched_param __user *, param)
+COMPAT_SYSCALL_METADATA2(sched_getparam, pid_t, pid, struct sched_param __user *, param)
+COMPAT_SYSCALL_METADATA3(sched_setscheduler, pid_t, pid, int, policy, struct sched_param __user *, param)
+COMPAT_SYSCALL_METADATA1(sched_getscheduler, pid_t, pid)
+COMPAT_SYSCALL_METADATA0(sched_yield)
+COMPAT_SYSCALL_METADATA1(sched_get_priority_max, int, policy)
+COMPAT_SYSCALL_METADATA1(sched_get_priority_min, int, policy)
+COMPAT_SYSCALL_METADATA2(sched_rr_get_interval, compat_pid_t, pid, struct compat_timespec __user *, interval)
+COMPAT_SYSCALL_METADATA2(nanosleep, struct compat_timespec __user *, rqtp, struct compat_timespec __user *, rmtp)
+COMPAT_SYSCALL_METADATA5(mremap, unsigned long, addr, unsigned long, old_len, unsigned long, new_len, unsigned long, flags, unsigned long, new_addr)
+COMPAT_SYSCALL_METADATA3(setresuid16, old_uid_t, ruid, old_uid_t, euid, old_uid_t, suid)
+COMPAT_SYSCALL_METADATA3(getresuid16, old_uid_t __user *, ruid, old_uid_t __user *, euid, old_uid_t __user *, suid)
+/* sys32_vm86_warning */
+/* ni */
+COMPAT_SYSCALL_METADATA3(poll, struct pollfd __user *, ufds, unsigned int, nfds, long, timeout_msecs)
+COMPAT_SYSCALL_METADATA3(nfsservctl, int, cmd, struct compat_nfsctl_arg __user *, arg, struct compat_nfsctl_res  __user *, res)
+COMPAT_SYSCALL_METADATA3(setresgid16, old_gid_t, rgid, old_gid_t, egid, old_gid_t, sgid)
+COMPAT_SYSCALL_METADATA3(getresgid16, old_gid_t __user *, rgid, old_gid_t __user *, egid, old_gid_t __user *, sgid)
+COMPAT_SYSCALL_METADATA5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5)
+/* stub32_rt_sigreturn */
+COMPAT_SYSCALL_METADATA4(rt_sigaction, int, sig, const struct sigaction32 __user *, act, struct sigaction32 __user *, oact, unsigned int , sigsetsize)
+COMPAT_SYSCALL_METADATA4(rt_sigprocmask, int, how, compat_sigset_t __user *, set, compat_sigset_t __user *, oset, unsigned int, sigsetsize)
+COMPAT_SYSCALL_METADATA2(rt_sigpending, compat_sigset_t __user *, set, unsigned int, sigsetsize)
+COMPAT_SYSCALL_METADATA4(rt_sigtimedwait, const compat_sigset_t __user *, uthese, compat_siginfo_t __user *, uinfo, const struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
+COMPAT_SYSCALL_METADATA3(rt_sigqueueinfo, int, pid, int, sig, compat_siginfo_t __user *, uinfo)
+COMPAT_SYSCALL_METADATA2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize)
+COMPAT_SYSCALL_METADATA5(pread, unsigned int,  fd, char __user *, ubuf, u32, count, u32,  poslo, u32,  poshi)
+COMPAT_SYSCALL_METADATA5(pwrite, unsigned int,  fd, char __user *, ubuf, u32, count, u32,  poslo, u32,  poshi)
+COMPAT_SYSCALL_METADATA3(chown16, const char __user *, filename, old_uid_t, user, old_gid_t, group)
+COMPAT_SYSCALL_METADATA2(getcwd, char __user *, buf, unsigned long, size)
+COMPAT_SYSCALL_METADATA2(capget, cap_user_header_t, header, cap_user_data_t, dataptr)
+COMPAT_SYSCALL_METADATA2(capset, cap_user_header_t, header, const cap_user_data_t, data)
+COMPAT_SYSCALL_METADATA2(sigaltstack, const stack_ia32_t __user *, uss_ptr, stack_ia32_t __user *, uoss_ptr)
+COMPAT_SYSCALL_METADATA4(sendfile, int, out_fd, int, in_fd, compat_off_t __user *, offset, s32, count)
+/* ni */
+/* ni */
+/* stub32_vfork */
+COMPAT_SYSCALL_METADATA2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
+COMPAT_SYSCALL_METADATA6(mmap_pgoff, unsigned long, addr, unsigned long, len, unsigned long, prot, unsigned long, flags, unsigned long, fd, unsigned long, pgoff)
+COMPAT_SYSCALL_METADATA3(truncate64, const char __user *,  path, unsigned long, offset_lo, unsigned long, offset_high)
+COMPAT_SYSCALL_METADATA3(ftruncate64, unsigned  int, fd, unsigned long, offset_lo, unsigned long, offset_high)
+COMPAT_SYSCALL_METADATA2(stat64, char __user *, filename, struct stat64 __user *, statbuf)
+COMPAT_SYSCALL_METADATA2(lstat64, char __user *, filename, struct stat64 __user *, statbuf)
+COMPAT_SYSCALL_METADATA2(fstat64, unsigned long, fd, struct stat64 __user *, statbuf)
+COMPAT_SYSCALL_METADATA3(lchown, const char __user *, filename, uid_t, user, gid_t, group)
+COMPAT_SYSCALL_METADATA0(getuid)
+COMPAT_SYSCALL_METADATA0(getgid)
+COMPAT_SYSCALL_METADATA0(geteuid)
+COMPAT_SYSCALL_METADATA0(getegid)
+COMPAT_SYSCALL_METADATA2(setreuid, uid_t, ruid, uid_t, euid)
+COMPAT_SYSCALL_METADATA2(setregid, gid_t, rgid, gid_t, egid)
+COMPAT_SYSCALL_METADATA2(getgroups, int, gidsetsize, gid_t __user *, grouplist)
+COMPAT_SYSCALL_METADATA2(setgroups, int, gidsetsize, gid_t __user *, grouplist)
+COMPAT_SYSCALL_METADATA3(fchown, unsigned int, fd, uid_t, user, gid_t, group)
+COMPAT_SYSCALL_METADATA3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
+COMPAT_SYSCALL_METADATA3(getresuid, uid_t __user *, ruid, uid_t __user *, euid, uid_t __user *, suid)
+COMPAT_SYSCALL_METADATA3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
+COMPAT_SYSCALL_METADATA3(getresgid, gid_t __user *, rgid, gid_t __user *, egid, gid_t __user *, sgid)
+COMPAT_SYSCALL_METADATA3(chown, const char __user *, filename, uid_t, user, gid_t, group)
+COMPAT_SYSCALL_METADATA1(setuid, uid_t, uid)
+COMPAT_SYSCALL_METADATA1(setgid, gid_t, gid)
+COMPAT_SYSCALL_METADATA1(setfsuid, uid_t, uid)
+COMPAT_SYSCALL_METADATA1(setfsgid, gid_t, gid)
+COMPAT_SYSCALL_METADATA2(pivot_root, const char __user *, new_root, const char __user *, put_old)
+COMPAT_SYSCALL_METADATA3(mincore, unsigned long, start, size_t, len, unsigned char __user *, vec)
+COMPAT_SYSCALL_METADATA3(madvise, unsigned long, start, size_t, len_in, int, behavior)
+COMPAT_SYSCALL_METADATA3(getdents64, unsigned int, fd, struct linux_dirent64 __user *, dirent, unsigned int, count)
+COMPAT_SYSCALL_METADATA3(fcntl64, unsigned int, fd, unsigned int, cmd, unsigned long, arg)
+/* ni */
+/* ni */
+COMPAT_SYSCALL_METADATA0(gettid)
+COMPAT_SYSCALL_METADATA4(readahead, int, fd, unsigned, off_lo, unsigned, off_hi, size_t, count)
+COMPAT_SYSCALL_METADATA5(setxattr, const char __user *, pathname, const char __user *, name, const void __user *, value, size_t, size, int, flags)
+COMPAT_SYSCALL_METADATA5(lsetxattr, const char __user *, pathname, const char __user *, name, const void __user *, value, size_t, size, int, flags)
+COMPAT_SYSCALL_METADATA5(fsetxattr, int, fd, const char __user *, name, const void __user *,value, size_t, size, int, flags)
+COMPAT_SYSCALL_METADATA4(getxattr, const char __user *, pathname, const char __user *, name, void __user *, value, size_t, size)
+COMPAT_SYSCALL_METADATA4(fgetxattr, int, fd, const char __user *, name, void __user *, value, size_t, size)
+COMPAT_SYSCALL_METADATA4(lgetxattr, const char __user *, pathname, const char __user *, name, void __user *, value, size_t, size)
+COMPAT_SYSCALL_METADATA3(listxattr, const char __user *, pathname, char __user *, list, size_t, size)
+COMPAT_SYSCALL_METADATA3(llistxattr, const char __user *, pathname, char __user *, list, size_t, size)
+COMPAT_SYSCALL_METADATA3(flistxattr, int, fd, char __user *, list, size_t, size)
+COMPAT_SYSCALL_METADATA2(removexattr, const char __user *, pathname, const char __user *, name)
+COMPAT_SYSCALL_METADATA2(lremovexattr, const char __user *, pathname, const char __user *, name)
+COMPAT_SYSCALL_METADATA2(fremovexattr, int, fd, const char __user *, name)
+COMPAT_SYSCALL_METADATA2(tkill, pid_t, pid, int, sig)
+COMPAT_SYSCALL_METADATA4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
+COMPAT_SYSCALL_METADATA6(futex, u32 __user *, uaddr, int, op, u32, val, struct compat_timespec __user *, utime, u32 __user *, uaddr2, u32, val3)
+COMPAT_SYSCALL_METADATA3(sched_setaffinity, compat_pid_t, pid, unsigned int, len, compat_ulong_t __user *, user_mask_ptr)
+COMPAT_SYSCALL_METADATA3(sched_getaffinity, compat_pid_t, pid, unsigned int, len, compat_ulong_t __user *, user_mask_ptr)
+COMPAT_SYSCALL_METADATA1(set_thread_area, struct user_desc __user *, u_info)
+COMPAT_SYSCALL_METADATA1(get_thread_area, struct user_desc __user *, u_info)
+COMPAT_SYSCALL_METADATA2(io_setup, unsigned, nr_reqs, u32 __user *, ctxp)
+COMPAT_SYSCALL_METADATA1(io_destroy, aio_context_t, ctx)
+COMPAT_SYSCALL_METADATA5(io_getevents, aio_context_t, ctx_id, long, min_nr, long, nr, struct io_event __user *, events, struct timespec __user *, timeout)
+COMPAT_SYSCALL_METADATA3(io_submit, aio_context_t, ctx_id, long, nr, struct iocb __user * __user *, iocbpp)
+COMPAT_SYSCALL_METADATA3(io_cancel, aio_context_t, ctx_id, struct iocb __user *, iocb, struct io_event __user *, result)
+COMPAT_SYSCALL_METADATA6(fadvise64, int, fd, __u32, offset_low, __u32, offset_high, __u32, len_low, __u32, len_high, int, advice)
+/* ni */
+COMPAT_SYSCALL_METADATA1(exit_group, int, error_code)
+COMPAT_SYSCALL_METADATA3(lookup_dcookie, u64,  cookie64, char __user *,  buf, size_t, len)
+COMPAT_SYSCALL_METADATA1(epoll_create, int, size)
+COMPAT_SYSCALL_METADATA4(epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event __user *, event)
+COMPAT_SYSCALL_METADATA4(epoll_wait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout)
+COMPAT_SYSCALL_METADATA5(remap_file_pages, unsigned long, start, unsigned long, size, unsigned long, prot, unsigned long, pgoff, unsigned long, flags)
+COMPAT_SYSCALL_METADATA1(set_tid_address, int __user *, tidptr)
+COMPAT_SYSCALL_METADATA3(timer_create, const clockid_t, which_clock, struct sigevent __user *, timer_event_spec, timer_t __user *, created_timer_id)
+COMPAT_SYSCALL_METADATA4(timer_settime, timer_t, timer_id, int, flags, const struct itimerspec __user *, new_setting, struct itimerspec __user *, old_setting)
+COMPAT_SYSCALL_METADATA2(timer_gettime, timer_t, timer_id, struct itimerspec __user *, setting)
+COMPAT_SYSCALL_METADATA1(timer_getoverrun, timer_t, timer_id)
+COMPAT_SYSCALL_METADATA1(timer_delete, timer_t, timer_id)
+COMPAT_SYSCALL_METADATA2(clock_settime, const clockid_t, which_clock, const struct timespec __user *, tp)
+COMPAT_SYSCALL_METADATA2(clock_gettime, const clockid_t, which_clock, struct timespec __user *,tp)
+COMPAT_SYSCALL_METADATA2(clock_getres, const clockid_t, which_clock, struct timespec __user *, tp)
+COMPAT_SYSCALL_METADATA4(clock_nanosleep, const clockid_t, which_clock, int, flags, const struct timespec __user *, rqtp, struct timespec __user *, rmtp)
+COMPAT_SYSCALL_METADATA3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf)
+COMPAT_SYSCALL_METADATA3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf)
+COMPAT_SYSCALL_METADATA3(tgkill, pid_t, tgid, pid_t, pid, int, sig)
+COMPAT_SYSCALL_METADATA2(utimes, char __user *, filename, struct timeval __user *, utimes)
+COMPAT_SYSCALL_METADATA4(fadvise64_64, int, fd, loff_t, offset, loff_t, len, int, advice)
+/* ni */
+COMPAT_SYSCALL_METADATA6(mbind, unsigned long, start, unsigned long, len, unsigned long, mode, unsigned long __user *, nmask, unsigned long, maxnode, unsigned, flags)
+COMPAT_SYSCALL_METADATA5(get_mempolicy, int __user *, policy, unsigned long __user *, nmask, unsigned long, maxnode, unsigned long, addr, unsigned long, flags)
+COMPAT_SYSCALL_METADATA3(set_mempolicy, int, mode, unsigned long __user *, nmask, unsigned long, maxnode)
+COMPAT_SYSCALL_METADATA4(mq_open, const char __user *, u_name, int, oflag, mode_t, mode, struct mq_attr __user *, u_attr)
+COMPAT_SYSCALL_METADATA1(mq_unlink, const char __user *, u_name)
+COMPAT_SYSCALL_METADATA5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr, size_t, msg_len, unsigned int, msg_prio, const struct timespec __user *, u_abs_timeout)
+COMPAT_SYSCALL_METADATA5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr, size_t, msg_len, unsigned int __user *, u_msg_prio, const struct timespec __user *, u_abs_timeout)
+COMPAT_SYSCALL_METADATA2(mq_notify, mqd_t, mqdes, const struct sigevent __user *, u_notification)
+COMPAT_SYSCALL_METADATA3(mq_getsetattr, mqd_t, mqdes, const struct mq_attr __user *, u_mqstat, struct mq_attr __user *, u_omqstat)
+COMPAT_SYSCALL_METADATA4(kexec_load, unsigned long, entry, unsigned long, nr_segments, struct kexec_segment __user *, segments, unsigned long, flags)
+COMPAT_SYSCALL_METADATA5(waitid, int, which, pid_t, upid, struct siginfo __user *, infop, int, options, struct rusage __user *, ru)
+/* ni */
+COMPAT_SYSCALL_METADATA5(add_key, const char __user *, _type, const char __user *, _description, const void __user *, _payload, size_t, plen, key_serial_t, ringid)
+COMPAT_SYSCALL_METADATA4(request_key, const char __user *, _type, const char __user *, _description, const char __user *, _callout_info,  key_serial_t, destringid)
+COMPAT_SYSCALL_METADATA5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, unsigned long, arg4, unsigned long, arg5)
+COMPAT_SYSCALL_METADATA3(ioprio_set, int, which, int, who, int, ioprio)
+COMPAT_SYSCALL_METADATA2(ioprio_get, int, which, int, who)
+COMPAT_SYSCALL_METADATA0(inotify_init)
+COMPAT_SYSCALL_METADATA3(inotify_add_watch, int, fd, const char __user *, pathname, u32, mask)
+COMPAT_SYSCALL_METADATA2(inotify_rm_watch, int, fd, __s32, wd)
+COMPAT_SYSCALL_METADATA4(migrate_pages, pid_t, pid, unsigned long, maxnode, const unsigned long __user *, old_nodes, const unsigned long __user *, new_nodes)
+COMPAT_SYSCALL_METADATA4(openat, int, dfd, const char __user *, filename, int, flags, int, mode)
+COMPAT_SYSCALL_METADATA3(mkdirat, int, dfd, const char __user *, pathname, int, mode)
+COMPAT_SYSCALL_METADATA4(mknodat, int, dfd, const char __user *, filename, int, mode, unsigned, dev)
+COMPAT_SYSCALL_METADATA5(fchownat, int, dfd, const char __user *, filename, uid_t, user, gid_t, group, int, flag)
+COMPAT_SYSCALL_METADATA3(futimesat, int, dfd, char __user *, filename, struct timeval __user *, utimes)
+COMPAT_SYSCALL_METADATA4(fstatat, int, dfd, char __user *, filename, struct stat64 __user *, statbuf, int, flag)
+COMPAT_SYSCALL_METADATA3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
+COMPAT_SYSCALL_METADATA4(renameat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname)
+COMPAT_SYSCALL_METADATA5(linkat, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, int, flags)
+COMPAT_SYSCALL_METADATA3(symlinkat, const char __user *, oldname, int, newdfd, const char __user *, newname)
+COMPAT_SYSCALL_METADATA4(readlinkat, int, dfd, const char __user *, pathname, char __user *, buf, int, bufsiz)
+COMPAT_SYSCALL_METADATA3(fchmodat, int, dfd, const char __user *, filename, mode_t, mode)
+COMPAT_SYSCALL_METADATA3(faccessat, int, dfd, const char __user *, filename, int, mode)
+COMPAT_SYSCALL_METADATA6(pselect6, int, n, fd_set __user *, inp, fd_set __user *, outp, fd_set __user *, exp, struct timespec __user *, tsp, void __user *, sig)
+COMPAT_SYSCALL_METADATA5(ppoll, struct pollfd __user *, ufds, unsigned int, nfds, struct timespec __user *, tsp, const sigset_t __user *, sigmask, size_t, sigsetsize)
+COMPAT_SYSCALL_METADATA1(unshare, unsigned long, unshare_flags)
+COMPAT_SYSCALL_METADATA2(set_robust_list, struct robust_list_head __user *, head, compat_size_t, len)
+COMPAT_SYSCALL_METADATA3(get_robust_list, int, pid, struct robust_list_head __user * __user *, head_ptr, compat_size_t __user *, len_ptr)
+COMPAT_SYSCALL_METADATA6(splice, int, fd_in, loff_t __user *, off_in, int, fd_out, loff_t __user *, off_out, size_t, len, unsigned int, flags)
+COMPAT_SYSCALL_METADATA4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes, unsigned int, flags)
+COMPAT_SYSCALL_METADATA4(tee, int, fdin, int, fdout, size_t, len, unsigned int, flags)
+COMPAT_SYSCALL_METADATA4(vmsplice, int, fd, const struct compat_iovec __user *, iov, unsigned long, nr_segs, unsigned int, flags)
+COMPAT_SYSCALL_METADATA6(move_pages, pid_t, pid, unsigned long, nr_pages, const void __user * __user *, pages, const int __user *, nodes, int __user *, status, int, flags)
+COMPAT_SYSCALL_METADATA3(getcpu, unsigned __user *, cpup, unsigned __user *, nodep, struct getcpu_cache __user *, unused)
+COMPAT_SYSCALL_METADATA6(epoll_pwait, int, epfd, struct epoll_event __user *, events, int, maxevents, int, timeout, const sigset_t __user *, sigmask, size_t, sigsetsize)
+COMPAT_SYSCALL_METADATA4(utimensat, int, dfd, char __user *, filename, struct timespec __user *, utimes, int, flags)
+COMPAT_SYSCALL_METADATA3(signalfd, int, ufd, sigset_t __user *, user_mask, size_t, sizemask)
+COMPAT_SYSCALL_METADATA2(timerfd_create, int, clockid, int, flags)
+COMPAT_SYSCALL_METADATA1(eventfd, unsigned int, count)
+COMPAT_SYSCALL_METADATA4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
+COMPAT_SYSCALL_METADATA4(timerfd_settime, int, ufd, int, flags, const struct itimerspec __user *, utmr, struct itimerspec __user *, otmr)
+COMPAT_SYSCALL_METADATA2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr)
+COMPAT_SYSCALL_METADATA4(signalfd4, int, ufd, sigset_t __user *, user_mask, size_t, sizemask, int, flags)
+COMPAT_SYSCALL_METADATA2(eventfd2, unsigned int, count, int, flags)
+COMPAT_SYSCALL_METADATA1(epoll_create1, int, flags)
+COMPAT_SYSCALL_METADATA3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)
+COMPAT_SYSCALL_METADATA2(pipe2, int __user *, fildes, int, flags)
+COMPAT_SYSCALL_METADATA1(inotify_init1, int, flags)
+COMPAT_SYSCALL_METADATA5(preadv, unsigned long, fd, const struct compat_iovec __user *, vec, unsigned long, vlen, u32, pos_low, 32, pos_high)
+COMPAT_SYSCALL_METADATA5(pwritev, unsigned long, fd, const struct compat_iovec __user *, vec, unsigned long, vlen, u32, pos_low, u32, pos_high)
+COMPAT_SYSCALL_METADATA4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig, siginfo_t __user *, uinfo)
+COMPAT_SYSCALL_METADATA5(perf_event_open, struct perf_event_attr __user *, attr_uptr, pid_t, pid, int, cpu, int, group_fd, unsigned long, flags)
+COMPAT_SYSCALL_METADATA5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags, struct timespec __user *, timeout)
+
+
+extern long ia32_sys_call_table[];
+
+int nr_compat_syscalls;
+struct syscall_metadata **compat_syscalls_metadata;
+
+static const char *prefixes[] = { "sys32", "stub32", "compat_sys", "sys", NULL };
+
+/*
+ * This is truly horrible.
+ *
+ * There is no header file that defines a *complete* set of 32 bit system
+ * call numbers (unistd_32.h only defines ones that are currently exported
+ * to user space and omits lots of old system calls that are still implemented
+ * by the kernel.
+ *
+ * There is also no table that can be used to map a system call number into
+ * the canonical name of that system call.
+ *
+ * So we are forced to use an even more unpleasant version of the technique
+ * used by ftrace to handle the normal system call metadata ...
+ *
+ * For each entry in the 32 bit system call table:
+ *	Look up the address in the kernel symbol table
+ *	Strip off any "sys32|stub32|sys|compat" prefix
+ *	Search through all of the compat metadata entries for a matching name
+ *
+ */
+static struct syscall_metadata __init *find_compat_syscall_meta(unsigned long addr)
+{
+	struct syscall_metadata **start;
+	struct syscall_metadata **stop;
+	char str[KSYM_SYMBOL_LEN];
+	const char *name;
+	const char **p;
+	extern struct syscall_metadata *__start_syscalls_metadata[];
+	extern struct syscall_metadata *__stop_syscalls_metadata[];
+
+	start = __start_syscalls_metadata;
+	stop = __stop_syscalls_metadata;
+	kallsyms_lookup(addr, NULL, NULL, NULL, str);
+
+	/*
+	 * If there is a {sys|compat|sys32|stub32} prefix strip it off
+	 */
+	for (p = prefixes, name = str; *p; p++) {
+		int len = strlen(*p);
+		if (strncmp(name, *p, len) == 0) {
+			name += len;
+			break;
+		}
+	}
+
+	for ( ; start < stop; start++) {
+		if (!(*start)->compat)
+			continue;
+
+		/*
+		 * ignore the "compat_" prefix on the metadata name
+		 * when doing the comparison
+		 */
+		if ((*start)->name && !strcmp((*start)->name + 6, name))
+			return *start;
+	}
+	return NULL;
+}
+
+static int __init init_compat_syscall_metadata(void)
+{
+	struct syscall_metadata *meta;
+	int	i;
+
+	nr_compat_syscalls = __NR_ia32_syscall_max;
+	compat_syscalls_metadata = kzalloc(sizeof(*compat_syscalls_metadata) *
+					nr_compat_syscalls, GFP_KERNEL);
+	if (!compat_syscalls_metadata) {
+		nr_compat_syscalls = -1;
+		WARN_ON(1);
+		return -ENOMEM;
+	}
+
+	for (i = 0; i < nr_compat_syscalls; i++) {
+		if ((meta = find_compat_syscall_meta(ia32_sys_call_table[i]))) {
+			meta->syscall_nr = i;
+			compat_syscalls_metadata[i] = meta;
+		}
+	}
+
+	return 0;
+}
+
+core_initcall(init_compat_syscall_metadata);
diff --git a/fs/dcookies.c b/fs/dcookies.c
index dda0dc7..9a448c8 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -145,7 +145,7 @@ out:
 /* And here is where the userspace process can look up the cookie value
  * to retrieve the path.
  */
-SYSCALL_DEFINE(lookup_dcookie)(u64 cookie64, char __user * buf, size_t len)
+SYSCALL_DEFINE3(lookup_dcookie, u64, cookie64, char __user *, buf, size_t, len)
 {
 	unsigned long cookie = (unsigned long)cookie64;
 	int err = -EINVAL;
diff --git a/fs/open.c b/fs/open.c
index 77becc0..cc5edeb 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -269,7 +269,7 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
 	return file->f_op->fallocate(file, mode, offset, len);
 }
 
-SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
+SYSCALL_DEFINE4(fallocate, int, fd, int, mode, loff_t, offset, loff_t, len)
 {
 	struct file *file;
 	int error = -EBADF;
diff --git a/fs/read_write.c b/fs/read_write.c
index 5ad4248..72b675b 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -492,8 +492,8 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
 	return ret;
 }
 
-SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
-			size_t count, loff_t pos)
+SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
+			size_t, count, loff_t, pos)
 {
 	struct file *file;
 	ssize_t ret = -EBADF;
@@ -521,8 +521,8 @@ asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos)
 SYSCALL_ALIAS(sys_pread64, SyS_pread64);
 #endif
 
-SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
-			 size_t count, loff_t pos)
+SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
+			 size_t, count, loff_t, pos)
 {
 	struct file *file;
 	ssize_t ret = -EBADF;
diff --git a/fs/sync.c b/fs/sync.c
index f3501ef..584cbd0 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -271,8 +271,8 @@ EXPORT_SYMBOL(generic_write_sync);
  * already-instantiated disk blocks, there are no guarantees here that the data
  * will be available after a crash.
  */
-SYSCALL_DEFINE(sync_file_range)(int fd, loff_t offset, loff_t nbytes,
-				unsigned int flags)
+SYSCALL_DEFINE4(sync_file_range, int, fd, loff_t, offset, loff_t, nbytes,
+				unsigned int, flags)
 {
 	int ret;
 	struct file *file;
@@ -366,8 +366,8 @@ SYSCALL_ALIAS(sys_sync_file_range, SyS_sync_file_range);
 
 /* It would be nice if people remember that not all the world's an i386
    when they introduce new system calls */
-SYSCALL_DEFINE(sync_file_range2)(int fd, unsigned int flags,
-				 loff_t offset, loff_t nbytes)
+SYSCALL_DEFINE4(sync_file_range2, int, fd, unsigned int, flags,
+				 loff_t, offset, loff_t, nbytes)
 {
 	return sys_sync_file_range(fd, offset, nbytes, flags);
 }
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index ed0003c..a5b0cae 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -159,7 +159,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	  __attribute__((section("_ftrace_events")))			\
 	*__event_exit_##sname = &event_exit_##sname;
 
-#define SYSCALL_METADATAx(x, sname, ...)			\
+#define _SYSCALL_METADATAx(x, mname, sname, _compat, ...)	\
 	static const char *types_##sname[] = {			\
 		__SC_STR_TDECL##x(__VA_ARGS__)			\
 	};							\
@@ -170,11 +170,12 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	SYSCALL_TRACE_EXIT_EVENT(sname);			\
 	static struct syscall_metadata __used			\
 	  __syscall_meta_##sname = {				\
-		.name 		= "sys"#sname,			\
+		.name 		= mname,			\
 		.syscall_nr	= -1,	/* Filled in at boot */	\
 		.nb_args 	= x,				\
 		.types		= types_##sname,		\
 		.args		= args_##sname,			\
+		.compat		= _compat,			\
 		.enter_event	= &event_enter_##sname,		\
 		.exit_event	= &event_exit_##sname,		\
 		.enter_fields	= LIST_HEAD_INIT(__syscall_meta_##sname.enter_fields), \
@@ -182,6 +183,25 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	static struct syscall_metadata __used			\
 	  __attribute__((section("__syscalls_metadata")))	\
 	 *__p_syscall_meta_##sname = &__syscall_meta_##sname;
+
+#define SYSCALL_METADATAx(x, sname, ...)		\
+	_SYSCALL_METADATAx(x, "sys"#sname, sname, 0, __VA_ARGS__)
+
+#ifdef CONFIG_FTRACE_COMPAT_SYSCALLS
+
+#define COMPAT_SYSCALL_METADATAx(x, sname, ...)			\
+	_SYSCALL_METADATAx(x, "compat"#sname, _compat##sname, 1, __VA_ARGS__)
+
+#define COMPAT_SYSCALL_METADATA0(name, ...) COMPAT_SYSCALL_METADATAx(0, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA1(name, ...) COMPAT_SYSCALL_METADATAx(1, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA2(name, ...) COMPAT_SYSCALL_METADATAx(2, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA3(name, ...) COMPAT_SYSCALL_METADATAx(3, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA4(name, ...) COMPAT_SYSCALL_METADATAx(4, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA5(name, ...) COMPAT_SYSCALL_METADATAx(5, _##name, __VA_ARGS__)
+#define COMPAT_SYSCALL_METADATA6(name, ...) COMPAT_SYSCALL_METADATAx(6, _##name, __VA_ARGS__)
+
+#endif /* CONFIG_FTRACE_COMPAT_SYSCALLS */
+
 #else
 #define SYSCALL_METADATAx(x, name, ...)
 #endif /* CONFIG_FTRACE_SYSCALLS */
diff --git a/include/trace/syscall.h b/include/trace/syscall.h
index 31966a4..f495e55 100644
--- a/include/trace/syscall.h
+++ b/include/trace/syscall.h
@@ -21,8 +21,9 @@
  */
 struct syscall_metadata {
 	const char	*name;
-	int		syscall_nr;
-	int		nb_args;
+	u16		syscall_nr;
+	u8		nb_args;
+	u8		compat;
 	const char	**types;
 	const char	**args;
 	struct list_head enter_fields;
@@ -32,6 +33,19 @@ struct syscall_metadata {
 };
 
 #ifdef CONFIG_FTRACE_SYSCALLS
+
+#ifdef CONFIG_FTRACE_COMPAT_SYSCALLS
+
+extern int nr_compat_syscalls;
+extern struct syscall_metadata **compat_syscalls_metadata;
+
+static inline struct syscall_metadata *compat_syscall_nr_to_meta(int nr)
+{
+	return (nr < nr_compat_syscalls) ? compat_syscalls_metadata[nr]
+						  : NULL;
+}
+#endif /* CONFIG_FTRACE_COMPAT_SYSCALLS */
+
 extern unsigned long arch_syscall_addr(int nr);
 extern int init_syscall_trace(struct ftrace_event_call *call);
 
diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index cd31345..cd0954b 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -240,6 +240,12 @@ config FTRACE_SYSCALLS
 	help
 	  Basic tracer to catch the syscall entry and exit events.
 
+config FTRACE_COMPAT_SYSCALLS
+	bool "Trace 32 bit compat syscalls"
+	depends on FTRACE_SYSCALLS
+	help
+	  Trace syscall entry and exit events for 32 bit compat syscalls.
+
 config TRACE_BRANCH_PROFILING
 	bool
 	select GENERIC_TRACER
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
index cb65454..43a8685 100644
--- a/kernel/trace/trace_syscalls.c
+++ b/kernel/trace/trace_syscalls.c
@@ -5,6 +5,7 @@
 #include <linux/module.h>	/* for MODULE_NAME_LEN via KSYM_SYMBOL_LEN */
 #include <linux/ftrace.h>
 #include <linux/perf_event.h>
+#include <linux/compat.h>
 #include <asm/syscall.h>
 
 #include "trace_output.h"
@@ -90,6 +91,10 @@ find_syscall_meta(unsigned long syscall)
 		return NULL;
 
 	for ( ; start < stop; start++) {
+#ifdef CONFIG_FTRACE_COMPAT_SYSCALLS
+		if ((*start)->compat)	/* skip compat syscalls */
+			continue;
+#endif
 		if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name))
 			return *start;
 	}
@@ -98,6 +103,10 @@ find_syscall_meta(unsigned long syscall)
 
 static struct syscall_metadata *syscall_nr_to_meta(int nr)
 {
+#ifdef CONFIG_FTRACE_COMPAT_SYSCALLS
+	if (is_compat_task())
+		return compat_syscall_nr_to_meta(nr);
+#endif
 	if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
 		return NULL;
 
@@ -112,11 +121,13 @@ print_syscall_enter(struct trace_iterator *iter, int flags,
 	struct trace_entry *ent = iter->ent;
 	struct syscall_trace_enter *trace;
 	struct syscall_metadata *entry;
-	int i, ret, syscall;
+	int i, ret;
+	struct ftrace_event_call *call;
 
 	trace = (typeof(trace))ent;
-	syscall = trace->nr;
-	entry = syscall_nr_to_meta(syscall);
+	event = ftrace_find_event(ent->type);
+	call = container_of(event, struct ftrace_event_call, event);
+	entry = call->data;
 
 	if (!entry)
 		goto end;
@@ -164,13 +175,14 @@ print_syscall_exit(struct trace_iterator *iter, int flags,
 	struct trace_seq *s = &iter->seq;
 	struct trace_entry *ent = iter->ent;
 	struct syscall_trace_exit *trace;
-	int syscall;
 	struct syscall_metadata *entry;
 	int ret;
+	struct ftrace_event_call *call;
 
 	trace = (typeof(trace))ent;
-	syscall = trace->nr;
-	entry = syscall_nr_to_meta(syscall);
+	event = ftrace_find_event(ent->type);
+	call = container_of(event, struct ftrace_event_call, event);
+	entry = call->data;
 
 	if (!entry) {
 		trace_seq_printf(s, "\n");
diff --git a/mm/fadvise.c b/mm/fadvise.c
index 469491e..60d83eb 100644
--- a/mm/fadvise.c
+++ b/mm/fadvise.c
@@ -24,7 +24,8 @@
  * POSIX_FADV_WILLNEED could set PG_Referenced, and POSIX_FADV_NOREUSE could
  * deactivate the pages and clear PG_Referenced.
  */
-SYSCALL_DEFINE(fadvise64_64)(int fd, loff_t offset, loff_t len, int advice)
+SYSCALL_DEFINE4(fadvise64_64, int, fd, loff_t, offset,
+			loff_t, len, int, advice)
 {
 	struct file *file = fget(fd);
 	struct address_space *mapping;
@@ -145,7 +146,7 @@ SYSCALL_ALIAS(sys_fadvise64_64, SyS_fadvise64_64);
 
 #ifdef __ARCH_WANT_SYS_FADVISE64
 
-SYSCALL_DEFINE(fadvise64)(int fd, loff_t offset, size_t len, int advice)
+SYSCALL_DEFINE4(fadvise64, int, fd, loff_t, offset, size_t, len, int, advice)
 {
 	return sys_fadvise64_64(fd, offset, len, advice);
 }
diff --git a/mm/filemap.c b/mm/filemap.c
index cb8ee3e..6e06d27 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1499,7 +1499,7 @@ do_readahead(struct address_space *mapping, struct file *filp,
 	return 0;
 }
 
-SYSCALL_DEFINE(readahead)(int fd, loff_t offset, size_t count)
+SYSCALL_DEFINE3(readahead, int, fd, loff_t, offset, size_t, count)
 {
 	ssize_t ret;
 	struct file *file;
-- 
1.7.7.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ