diff --git a/arch/ia64/Kconfig.debug b/arch/ia64/Kconfig.debug
index de9d507ba0fd466d8b466f54d1143a46d20caaa0..4763887ba3682112f5fe5020622391c81c830d73 100644
--- a/arch/ia64/Kconfig.debug
+++ b/arch/ia64/Kconfig.debug
@@ -56,9 +56,4 @@ config IA64_DEBUG_IRQ
 	  and restore instructions.  It's useful for tracking down spinlock
 	  problems, but slow!  If you're unsure, select N.
 
-config SYSVIPC_COMPAT
-	bool
-	depends on COMPAT && SYSVIPC
-	default y
-
 endmenu
diff --git a/fs/utimes.c b/fs/utimes.c
index 6571d8c848a04054e7517f7ad29b55d5b9022232..51edb9f9507c409269dd8722a6c49303ef926f84 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -22,7 +22,7 @@
  */
 SYSCALL_DEFINE2(utime, char __user *, filename, struct utimbuf __user *, times)
 {
-	struct timespec tv[2];
+	struct timespec64 tv[2];
 
 	if (times) {
 		if (get_user(tv[0].tv_sec, &times->actime) ||
@@ -44,7 +44,7 @@ static bool nsec_valid(long nsec)
 	return nsec >= 0 && nsec <= 999999999;
 }
 
-static int utimes_common(const struct path *path, struct timespec *times)
+static int utimes_common(const struct path *path, struct timespec64 *times)
 {
 	int error;
 	struct iattr newattrs;
@@ -115,7 +115,7 @@ static int utimes_common(const struct path *path, struct timespec *times)
  * must be owner or have write permission.
  * Else, update from *times, must be owner or super user.
  */
-long do_utimes(int dfd, const char __user *filename, struct timespec *times,
+long do_utimes(int dfd, const char __user *filename, struct timespec64 *times,
 	       int flags)
 {
 	int error = -EINVAL;
@@ -167,10 +167,11 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
 SYSCALL_DEFINE4(utimensat, int, dfd, const char __user *, filename,
 		struct timespec __user *, utimes, int, flags)
 {
-	struct timespec tstimes[2];
+	struct timespec64 tstimes[2];
 
 	if (utimes) {
-		if (copy_from_user(&tstimes, utimes, sizeof(tstimes)))
+		if ((get_timespec64(&tstimes[0], &utimes[0]) ||
+			get_timespec64(&tstimes[1], &utimes[1])))
 			return -EFAULT;
 
 		/* Nothing to do, we must not even check the path.  */
@@ -186,7 +187,7 @@ SYSCALL_DEFINE3(futimesat, int, dfd, const char __user *, filename,
 		struct timeval __user *, utimes)
 {
 	struct timeval times[2];
-	struct timespec tstimes[2];
+	struct timespec64 tstimes[2];
 
 	if (utimes) {
 		if (copy_from_user(&times, utimes, sizeof(times)))
@@ -224,7 +225,7 @@ SYSCALL_DEFINE2(utimes, char __user *, filename,
 COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
 		       struct compat_utimbuf __user *, t)
 {
-	struct timespec tv[2];
+	struct timespec64 tv[2];
 
 	if (t) {
 		if (get_user(tv[0].tv_sec, &t->actime) ||
@@ -238,11 +239,11 @@ COMPAT_SYSCALL_DEFINE2(utime, const char __user *, filename,
 
 COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filename, struct compat_timespec __user *, t, int, flags)
 {
-	struct timespec tv[2];
+	struct timespec64 tv[2];
 
 	if  (t) {
-		if (compat_get_timespec(&tv[0], &t[0]) ||
-		    compat_get_timespec(&tv[1], &t[1]))
+		if (compat_get_timespec64(&tv[0], &t[0]) ||
+		    compat_get_timespec64(&tv[1], &t[1]))
 			return -EFAULT;
 
 		if (tv[0].tv_nsec == UTIME_OMIT && tv[1].tv_nsec == UTIME_OMIT)
@@ -253,7 +254,7 @@ COMPAT_SYSCALL_DEFINE4(utimensat, unsigned int, dfd, const char __user *, filena
 
 COMPAT_SYSCALL_DEFINE3(futimesat, unsigned int, dfd, const char __user *, filename, struct compat_timeval __user *, t)
 {
-	struct timespec tv[2];
+	struct timespec64 tv[2];
 
 	if (t) {
 		if (get_user(tv[0].tv_sec, &t[0].tv_sec) ||
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 2150bdccfbab2953c33cd56d6d64eb798ca180ea..74d4d4e8e3db9f173611dc169a20955a7c89dc45 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -351,7 +351,7 @@ extern int __audit_socketcall(int nargs, unsigned long *args);
 extern int __audit_sockaddr(int len, void *addr);
 extern void __audit_fd_pair(int fd1, int fd2);
 extern void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr);
-extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout);
+extern void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout);
 extern void __audit_mq_notify(mqd_t mqdes, const struct sigevent *notification);
 extern void __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
 extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
@@ -412,7 +412,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
 	if (unlikely(!audit_dummy_context()))
 		__audit_mq_open(oflag, mode, attr);
 }
-static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec *abs_timeout)
+static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio, const struct timespec64 *abs_timeout)
 {
 	if (unlikely(!audit_dummy_context()))
 		__audit_mq_sendrecv(mqdes, msg_len, msg_prio, abs_timeout);
@@ -549,7 +549,7 @@ static inline void audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
 { }
 static inline void audit_mq_sendrecv(mqd_t mqdes, size_t msg_len,
 				     unsigned int msg_prio,
-				     const struct timespec *abs_timeout)
+				     const struct timespec64 *abs_timeout)
 { }
 static inline void audit_mq_notify(mqd_t mqdes,
 				   const struct sigevent *notification)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 3fc433303d7ac90267c5dfda215a299cfee36a41..a5619de3437d9b1691b0e707bb2577b075592822 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -171,15 +171,6 @@ extern int get_compat_itimerspec64(struct itimerspec64 *its,
 extern int put_compat_itimerspec64(const struct itimerspec64 *its,
 			struct compat_itimerspec __user *uits);
 
-/*
- * This function convert a timespec if necessary and returns a *user
- * space* pointer.  If no conversion is necessary, it returns the
- * initial pointer.  NULL is a legitimate argument and will always
- * output NULL.
- */
-extern int compat_convert_timespec(struct timespec __user **,
-				   const void __user *);
-
 struct compat_iovec {
 	compat_uptr_t	iov_base;
 	compat_size_t	iov_len;
diff --git a/include/linux/msg.h b/include/linux/msg.h
index a001305f5a79959a5e4f816320f3c4276e308e12..81263fe3f9dc9dee1d3341fa5c7eda322df415c0 100644
--- a/include/linux/msg.h
+++ b/include/linux/msg.h
@@ -2,6 +2,7 @@
 #define _LINUX_MSG_H
 
 #include <linux/list.h>
+#include <linux/time64.h>
 #include <uapi/linux/msg.h>
 
 /* one msg_msg structure for each message */
@@ -17,9 +18,9 @@ struct msg_msg {
 /* one msq_queue structure for each present queue on the system */
 struct msg_queue {
 	struct kern_ipc_perm q_perm;
-	time_t q_stime;			/* last msgsnd time */
-	time_t q_rtime;			/* last msgrcv time */
-	time_t q_ctime;			/* last change time */
+	time64_t q_stime;		/* last msgsnd time */
+	time64_t q_rtime;		/* last msgrcv time */
+	time64_t q_ctime;		/* last change time */
 	unsigned long q_cbytes;		/* current number of bytes on queue */
 	unsigned long q_qnum;		/* number of messages in queue */
 	unsigned long q_qbytes;		/* max number of bytes on queue */
@@ -31,12 +32,4 @@ struct msg_queue {
 	struct list_head q_senders;
 } __randomize_layout;
 
-/* Helper routines for sys_msgsnd and sys_msgrcv */
-extern long do_msgsnd(int msqid, long mtype, void __user *mtext,
-			size_t msgsz, int msgflg);
-extern long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp,
-		      int msgflg,
-		      long (*msg_fill)(void __user *, struct msg_msg *,
-				       size_t));
-
 #endif /* _LINUX_MSG_H */
diff --git a/include/linux/sem.h b/include/linux/sem.h
index de2deb8676bd6c39c55a439b5df98715915eb9c9..0083128318f6da53dc1d29cecb3145096bd22a9a 100644
--- a/include/linux/sem.h
+++ b/include/linux/sem.h
@@ -4,6 +4,7 @@
 #include <linux/atomic.h>
 #include <linux/rcupdate.h>
 #include <linux/cache.h>
+#include <linux/time64.h>
 #include <uapi/linux/sem.h>
 
 struct task_struct;
@@ -30,7 +31,7 @@ struct sem {
 /* One sem_array data structure for each set of semaphores in the system. */
 struct sem_array {
 	struct kern_ipc_perm	sem_perm;	/* permissions .. see ipc.h */
-	time_t			sem_ctime;	/* create/last semctl() time */
+	time64_t		sem_ctime;	/* create/last semctl() time */
 	struct list_head	pending_alter;	/* pending operations */
 						/* that alter the array */
 	struct list_head	pending_const;	/* pending complex operations */
diff --git a/include/linux/shm.h b/include/linux/shm.h
index 21a5e6c43385c648502272134616cf5cece46feb..74a4b3b64352ec29e9e613b8d8bc41a1ad54a491 100644
--- a/include/linux/shm.h
+++ b/include/linux/shm.h
@@ -12,9 +12,9 @@ struct shmid_kernel /* private to the kernel */
 	struct file		*shm_file;
 	unsigned long		shm_nattch;
 	unsigned long		shm_segsz;
-	time_t			shm_atim;
-	time_t			shm_dtim;
-	time_t			shm_ctim;
+	time64_t		shm_atim;
+	time64_t		shm_dtim;
+	time64_t		shm_ctim;
 	pid_t			shm_cprid;
 	pid_t			shm_lprid;
 	struct user_struct	*mlock_user;
diff --git a/include/linux/time.h b/include/linux/time.h
index 3877136bbdf8381fed3b2998644e9f62aba8b643..9bc1f945777cdefb2ce787eacf59abc1dd42e796 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -178,7 +178,7 @@ extern int do_setitimer(int which, struct itimerval *value,
 			struct itimerval *ovalue);
 extern int do_getitimer(int which, struct itimerval *value);
 
-extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags);
+extern long do_utimes(int dfd, const char __user *filename, struct timespec64 *times, int flags);
 
 /*
  * Similar to the struct tm in userspace <time.h>, but it needs to be here so
diff --git a/init/initramfs.c b/init/initramfs.c
index 8a532050043f5f804f06ddbf980e54965c9055de..e64bf7b4c1ca470d0eec8cd2003d14d2df4ed075 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -110,7 +110,7 @@ static void __init free_hash(void)
 
 static long __init do_utime(char *filename, time_t mtime)
 {
-	struct timespec t[2];
+	struct timespec64 t[2];
 
 	t[0].tv_sec = mtime;
 	t[0].tv_nsec = 0;
diff --git a/ipc/compat.c b/ipc/compat.c
index 9b3c85f8a53825330b99015e34af9d2117393f06..b17bf93d7b49a0a4eff445ab3977041b7221c168 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -34,724 +34,48 @@
 
 #include "util.h"
 
-struct compat_msgbuf {
-	compat_long_t mtype;
-	char mtext[1];
-};
-
-struct compat_ipc_perm {
-	key_t key;
-	__compat_uid_t uid;
-	__compat_gid_t gid;
-	__compat_uid_t cuid;
-	__compat_gid_t cgid;
-	compat_mode_t mode;
-	unsigned short seq;
-};
-
-struct compat_semid_ds {
-	struct compat_ipc_perm sem_perm;
-	compat_time_t sem_otime;
-	compat_time_t sem_ctime;
-	compat_uptr_t sem_base;
-	compat_uptr_t sem_pending;
-	compat_uptr_t sem_pending_last;
-	compat_uptr_t undo;
-	unsigned short sem_nsems;
-};
-
-struct compat_msqid_ds {
-	struct compat_ipc_perm msg_perm;
-	compat_uptr_t msg_first;
-	compat_uptr_t msg_last;
-	compat_time_t msg_stime;
-	compat_time_t msg_rtime;
-	compat_time_t msg_ctime;
-	compat_ulong_t msg_lcbytes;
-	compat_ulong_t msg_lqbytes;
-	unsigned short msg_cbytes;
-	unsigned short msg_qnum;
-	unsigned short msg_qbytes;
-	compat_ipc_pid_t msg_lspid;
-	compat_ipc_pid_t msg_lrpid;
-};
-
-struct compat_shmid_ds {
-	struct compat_ipc_perm shm_perm;
-	int shm_segsz;
-	compat_time_t shm_atime;
-	compat_time_t shm_dtime;
-	compat_time_t shm_ctime;
-	compat_ipc_pid_t shm_cpid;
-	compat_ipc_pid_t shm_lpid;
-	unsigned short shm_nattch;
-	unsigned short shm_unused;
-	compat_uptr_t shm_unused2;
-	compat_uptr_t shm_unused3;
-};
-
-struct compat_ipc_kludge {
-	compat_uptr_t msgp;
-	compat_long_t msgtyp;
-};
-
-struct compat_shminfo64 {
-	compat_ulong_t shmmax;
-	compat_ulong_t shmmin;
-	compat_ulong_t shmmni;
-	compat_ulong_t shmseg;
-	compat_ulong_t shmall;
-	compat_ulong_t __unused1;
-	compat_ulong_t __unused2;
-	compat_ulong_t __unused3;
-	compat_ulong_t __unused4;
-};
-
-struct compat_shm_info {
-	compat_int_t used_ids;
-	compat_ulong_t shm_tot, shm_rss, shm_swp;
-	compat_ulong_t swap_attempts, swap_successes;
-};
-
-static inline int compat_ipc_parse_version(int *cmd)
-{
-#ifdef	CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
-	int version = *cmd & IPC_64;
-
-	/* this is tricky: architectures that have support for the old
-	 * ipc structures in 64 bit binaries need to have IPC_64 set
-	 * in cmd, the others need to have it cleared */
-#ifndef ipc_parse_version
-	*cmd |= IPC_64;
-#else
-	*cmd &= ~IPC_64;
-#endif
-	return version;
-#else
-	/* With the asm-generic APIs, we always use the 64-bit versions. */
-	return IPC_64;
-#endif
-}
-
-static inline int __get_compat_ipc64_perm(struct ipc64_perm *p64,
-					  struct compat_ipc64_perm __user *up64)
-{
-	int err;
-
-	err  = __get_user(p64->uid, &up64->uid);
-	err |= __get_user(p64->gid, &up64->gid);
-	err |= __get_user(p64->mode, &up64->mode);
-	return err;
-}
-
-static inline int __get_compat_ipc_perm(struct ipc64_perm *p,
-					struct compat_ipc_perm __user *up)
-{
-	int err;
-
-	err  = __get_user(p->uid, &up->uid);
-	err |= __get_user(p->gid, &up->gid);
-	err |= __get_user(p->mode, &up->mode);
-	return err;
-}
-
-static inline int __put_compat_ipc64_perm(struct ipc64_perm *p64,
-					  struct compat_ipc64_perm __user *up64)
+int get_compat_ipc64_perm(struct ipc64_perm *to,
+			  struct compat_ipc64_perm __user *from)
 {
-	int err;
-
-	err  = __put_user(p64->key, &up64->key);
-	err |= __put_user(p64->uid, &up64->uid);
-	err |= __put_user(p64->gid, &up64->gid);
-	err |= __put_user(p64->cuid, &up64->cuid);
-	err |= __put_user(p64->cgid, &up64->cgid);
-	err |= __put_user(p64->mode, &up64->mode);
-	err |= __put_user(p64->seq, &up64->seq);
-	return err;
-}
-
-static inline int __put_compat_ipc_perm(struct ipc64_perm *p,
-					struct compat_ipc_perm __user *uip)
-{
-	int err;
-	__compat_uid_t u;
-	__compat_gid_t g;
-
-	err  = __put_user(p->key, &uip->key);
-	SET_UID(u, p->uid);
-	err |= __put_user(u, &uip->uid);
-	SET_GID(g, p->gid);
-	err |= __put_user(g, &uip->gid);
-	SET_UID(u, p->cuid);
-	err |= __put_user(u, &uip->cuid);
-	SET_GID(g, p->cgid);
-	err |= __put_user(g, &uip->cgid);
-	err |= __put_user(p->mode, &uip->mode);
-	err |= __put_user(p->seq, &uip->seq);
-	return err;
-}
-
-static inline int get_compat_semid64_ds(struct semid64_ds *sem64,
-					struct compat_semid64_ds __user *up64)
-{
-	if (!access_ok(VERIFY_READ, up64, sizeof(*up64)))
-		return -EFAULT;
-	return __get_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm);
-}
-
-static inline int get_compat_semid_ds(struct semid64_ds *s,
-				      struct compat_semid_ds __user *up)
-{
-	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
+	struct compat_ipc64_perm v;
+	if (copy_from_user(&v, from, sizeof(v)))
 		return -EFAULT;
-	return __get_compat_ipc_perm(&s->sem_perm, &up->sem_perm);
+	to->uid = v.uid;
+	to->gid = v.gid;
+	to->mode = v.mode;
+	return 0;
 }
 
-static inline int put_compat_semid64_ds(struct semid64_ds *sem64,
-					struct compat_semid64_ds __user *up64)
+int get_compat_ipc_perm(struct ipc64_perm *to,
+			struct compat_ipc_perm __user *from)
 {
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
+	struct compat_ipc_perm v;
+	if (copy_from_user(&v, from, sizeof(v)))
 		return -EFAULT;
-	err  = __put_compat_ipc64_perm(&sem64->sem_perm, &up64->sem_perm);
-	err |= __put_user(sem64->sem_otime, &up64->sem_otime);
-	err |= __put_user(sem64->sem_ctime, &up64->sem_ctime);
-	err |= __put_user(sem64->sem_nsems, &up64->sem_nsems);
-	return err;
+	to->uid = v.uid;
+	to->gid = v.gid;
+	to->mode = v.mode;
+	return 0;
 }
 
-static inline int put_compat_semid_ds(struct semid64_ds *s,
-				      struct compat_semid_ds __user *up)
+void to_compat_ipc64_perm(struct compat_ipc64_perm *to, struct ipc64_perm *from)
 {
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
-		return -EFAULT;
-	err  = __put_compat_ipc_perm(&s->sem_perm, &up->sem_perm);
-	err |= __put_user(s->sem_otime, &up->sem_otime);
-	err |= __put_user(s->sem_ctime, &up->sem_ctime);
-	err |= __put_user(s->sem_nsems, &up->sem_nsems);
-	return err;
+	to->key = from->key;
+	to->uid = from->uid;
+	to->gid = from->gid;
+	to->cuid = from->cuid;
+	to->cgid = from->cgid;
+	to->mode = from->mode;
+	to->seq = from->seq;
 }
 
-static long do_compat_semctl(int first, int second, int third, u32 pad)
+void to_compat_ipc_perm(struct compat_ipc_perm *to, struct ipc64_perm *from)
 {
-	unsigned long fourth;
-	int err, err2;
-	struct semid64_ds sem64;
-	struct semid64_ds __user *up64;
-	int version = compat_ipc_parse_version(&third);
-
-	memset(&sem64, 0, sizeof(sem64));
-
-	if ((third & (~IPC_64)) == SETVAL)
-#ifdef __BIG_ENDIAN
-		fourth = (unsigned long)pad << 32;
-#else
-		fourth = pad;
-#endif
-	else
-		fourth = (unsigned long)compat_ptr(pad);
-	switch (third & (~IPC_64)) {
-	case IPC_INFO:
-	case IPC_RMID:
-	case SEM_INFO:
-	case GETVAL:
-	case GETPID:
-	case GETNCNT:
-	case GETZCNT:
-	case GETALL:
-	case SETVAL:
-	case SETALL:
-		err = sys_semctl(first, second, third, fourth);
-		break;
-
-	case IPC_STAT:
-	case SEM_STAT:
-		up64 = compat_alloc_user_space(sizeof(sem64));
-		fourth = (unsigned long)up64;
-		err = sys_semctl(first, second, third, fourth);
-		if (err < 0)
-			break;
-		if (copy_from_user(&sem64, up64, sizeof(sem64)))
-			err2 = -EFAULT;
-		else if (version == IPC_64)
-			err2 = put_compat_semid64_ds(&sem64, compat_ptr(pad));
-		else
-			err2 = put_compat_semid_ds(&sem64, compat_ptr(pad));
-		if (err2)
-			err = -EFAULT;
-		break;
-
-	case IPC_SET:
-		if (version == IPC_64)
-			err = get_compat_semid64_ds(&sem64, compat_ptr(pad));
-		else
-			err = get_compat_semid_ds(&sem64, compat_ptr(pad));
-
-		up64 = compat_alloc_user_space(sizeof(sem64));
-		if (copy_to_user(up64, &sem64, sizeof(sem64)))
-			err = -EFAULT;
-		if (err)
-			break;
-
-		fourth = (unsigned long)up64;
-		err = sys_semctl(first, second, third, fourth);
-		break;
-
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
-static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
-{
-	struct compat_msgbuf __user *msgp = dest;
-	size_t msgsz;
-
-	if (put_user(msg->m_type, &msgp->mtype))
-		return -EFAULT;
-
-	msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
-	if (store_msg(msgp->mtext, msg, msgsz))
-		return -EFAULT;
-	return msgsz;
-}
-
-#ifndef COMPAT_SHMLBA
-#define COMPAT_SHMLBA	SHMLBA
-#endif
-
-#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
-COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
-	u32, third, compat_uptr_t, ptr, u32, fifth)
-{
-	int version;
-	u32 pad;
-
-	version = call >> 16; /* hack for backward compatibility */
-	call &= 0xffff;
-
-	switch (call) {
-	case SEMOP:
-		/* struct sembuf is the same on 32 and 64bit :)) */
-		return sys_semtimedop(first, compat_ptr(ptr), second, NULL);
-	case SEMTIMEDOP:
-		return compat_sys_semtimedop(first, compat_ptr(ptr), second,
-						compat_ptr(fifth));
-	case SEMGET:
-		return sys_semget(first, second, third);
-	case SEMCTL:
-		if (!ptr)
-			return -EINVAL;
-		if (get_user(pad, (u32 __user *) compat_ptr(ptr)))
-			return -EFAULT;
-		return do_compat_semctl(first, second, third, pad);
-
-	case MSGSND: {
-		struct compat_msgbuf __user *up = compat_ptr(ptr);
-		compat_long_t type;
-
-		if (first < 0 || second < 0)
-			return -EINVAL;
-
-		if (get_user(type, &up->mtype))
-			return -EFAULT;
-
-		return do_msgsnd(first, type, up->mtext, second, third);
-	}
-	case MSGRCV: {
-		void __user *uptr = compat_ptr(ptr);
-
-		if (first < 0 || second < 0)
-			return -EINVAL;
-
-		if (!version) {
-			struct compat_ipc_kludge ipck;
-			if (!uptr)
-				return -EINVAL;
-			if (copy_from_user(&ipck, uptr, sizeof(ipck)))
-				return -EFAULT;
-			uptr = compat_ptr(ipck.msgp);
-			fifth = ipck.msgtyp;
-		}
-		return do_msgrcv(first, uptr, second, (s32)fifth, third,
-				 compat_do_msg_fill);
-	}
-	case MSGGET:
-		return sys_msgget(first, second);
-	case MSGCTL:
-		return compat_sys_msgctl(first, second, compat_ptr(ptr));
-
-	case SHMAT: {
-		int err;
-		unsigned long raddr;
-
-		if (version == 1)
-			return -EINVAL;
-		err = do_shmat(first, compat_ptr(ptr), second, &raddr,
-			       COMPAT_SHMLBA);
-		if (err < 0)
-			return err;
-		return put_user(raddr, (compat_ulong_t *)compat_ptr(third));
-	}
-	case SHMDT:
-		return sys_shmdt(compat_ptr(ptr));
-	case SHMGET:
-		return sys_shmget(first, (unsigned)second, third);
-	case SHMCTL:
-		return compat_sys_shmctl(first, second, compat_ptr(ptr));
-	}
-
-	return -ENOSYS;
-}
-#endif
-
-COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
-{
-	return do_compat_semctl(semid, semnum, cmd, arg);
-}
-
-COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
-		       compat_ssize_t, msgsz, int, msgflg)
-{
-	struct compat_msgbuf __user *up = compat_ptr(msgp);
-	compat_long_t mtype;
-
-	if (get_user(mtype, &up->mtype))
-		return -EFAULT;
-	return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
-}
-
-COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
-		       compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
-{
-	return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
-			 msgflg, compat_do_msg_fill);
-}
-
-static inline int get_compat_msqid64(struct msqid64_ds *m64,
-				     struct compat_msqid64_ds __user *up64)
-{
-	int err;
-
-	if (!access_ok(VERIFY_READ, up64, sizeof(*up64)))
-		return -EFAULT;
-	err  = __get_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm);
-	err |= __get_user(m64->msg_qbytes, &up64->msg_qbytes);
-	return err;
-}
-
-static inline int get_compat_msqid(struct msqid64_ds *m,
-				   struct compat_msqid_ds __user *up)
-{
-	int err;
-
-	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
-		return -EFAULT;
-	err  = __get_compat_ipc_perm(&m->msg_perm, &up->msg_perm);
-	err |= __get_user(m->msg_qbytes, &up->msg_qbytes);
-	return err;
-}
-
-static inline int put_compat_msqid64_ds(struct msqid64_ds *m64,
-				 struct compat_msqid64_ds __user *up64)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
-		return -EFAULT;
-	err  = __put_compat_ipc64_perm(&m64->msg_perm, &up64->msg_perm);
-	err |= __put_user(m64->msg_stime, &up64->msg_stime);
-	err |= __put_user(m64->msg_rtime, &up64->msg_rtime);
-	err |= __put_user(m64->msg_ctime, &up64->msg_ctime);
-	err |= __put_user(m64->msg_cbytes, &up64->msg_cbytes);
-	err |= __put_user(m64->msg_qnum, &up64->msg_qnum);
-	err |= __put_user(m64->msg_qbytes, &up64->msg_qbytes);
-	err |= __put_user(m64->msg_lspid, &up64->msg_lspid);
-	err |= __put_user(m64->msg_lrpid, &up64->msg_lrpid);
-	return err;
-}
-
-static inline int put_compat_msqid_ds(struct msqid64_ds *m,
-				      struct compat_msqid_ds __user *up)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
-		return -EFAULT;
-	err  = __put_compat_ipc_perm(&m->msg_perm, &up->msg_perm);
-	err |= __put_user(m->msg_stime, &up->msg_stime);
-	err |= __put_user(m->msg_rtime, &up->msg_rtime);
-	err |= __put_user(m->msg_ctime, &up->msg_ctime);
-	err |= __put_user(m->msg_cbytes, &up->msg_cbytes);
-	err |= __put_user(m->msg_qnum, &up->msg_qnum);
-	err |= __put_user(m->msg_qbytes, &up->msg_qbytes);
-	err |= __put_user(m->msg_lspid, &up->msg_lspid);
-	err |= __put_user(m->msg_lrpid, &up->msg_lrpid);
-	return err;
-}
-
-COMPAT_SYSCALL_DEFINE3(msgctl, int, first, int, second, void __user *, uptr)
-{
-	int err, err2;
-	struct msqid64_ds m64;
-	int version = compat_ipc_parse_version(&second);
-	void __user *p;
-
-	memset(&m64, 0, sizeof(m64));
-
-	switch (second & (~IPC_64)) {
-	case IPC_INFO:
-	case IPC_RMID:
-	case MSG_INFO:
-		err = sys_msgctl(first, second, uptr);
-		break;
-
-	case IPC_SET:
-		if (version == IPC_64)
-			err = get_compat_msqid64(&m64, uptr);
-		else
-			err = get_compat_msqid(&m64, uptr);
-
-		if (err)
-			break;
-		p = compat_alloc_user_space(sizeof(m64));
-		if (copy_to_user(p, &m64, sizeof(m64)))
-			err = -EFAULT;
-		else
-			err = sys_msgctl(first, second, p);
-		break;
-
-	case IPC_STAT:
-	case MSG_STAT:
-		p = compat_alloc_user_space(sizeof(m64));
-		err = sys_msgctl(first, second, p);
-		if (err < 0)
-			break;
-		if (copy_from_user(&m64, p, sizeof(m64)))
-			err2 = -EFAULT;
-		else if (version == IPC_64)
-			err2 = put_compat_msqid64_ds(&m64, uptr);
-		else
-			err2 = put_compat_msqid_ds(&m64, uptr);
-		if (err2)
-			err = -EFAULT;
-		break;
-
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
-COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
-{
-	unsigned long ret;
-	long err;
-
-	err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA);
-	if (err)
-		return err;
-	force_successful_syscall_return();
-	return (long)ret;
-}
-
-static inline int get_compat_shmid64_ds(struct shmid64_ds *sem64,
-					struct compat_shmid64_ds __user *up64)
-{
-	if (!access_ok(VERIFY_READ, up64, sizeof(*up64)))
-		return -EFAULT;
-	return __get_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm);
-}
-
-static inline int get_compat_shmid_ds(struct shmid64_ds *s,
-				      struct compat_shmid_ds __user *up)
-{
-	if (!access_ok(VERIFY_READ, up, sizeof(*up)))
-		return -EFAULT;
-	return __get_compat_ipc_perm(&s->shm_perm, &up->shm_perm);
-}
-
-static inline int put_compat_shmid64_ds(struct shmid64_ds *sem64,
-					struct compat_shmid64_ds __user *up64)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
-		return -EFAULT;
-	err  = __put_compat_ipc64_perm(&sem64->shm_perm, &up64->shm_perm);
-	err |= __put_user(sem64->shm_atime, &up64->shm_atime);
-	err |= __put_user(sem64->shm_dtime, &up64->shm_dtime);
-	err |= __put_user(sem64->shm_ctime, &up64->shm_ctime);
-	err |= __put_user(sem64->shm_segsz, &up64->shm_segsz);
-	err |= __put_user(sem64->shm_nattch, &up64->shm_nattch);
-	err |= __put_user(sem64->shm_cpid, &up64->shm_cpid);
-	err |= __put_user(sem64->shm_lpid, &up64->shm_lpid);
-	return err;
-}
-
-static inline int put_compat_shmid_ds(struct shmid64_ds *s,
-				      struct compat_shmid_ds __user *up)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
-		return -EFAULT;
-	err  = __put_compat_ipc_perm(&s->shm_perm, &up->shm_perm);
-	err |= __put_user(s->shm_atime, &up->shm_atime);
-	err |= __put_user(s->shm_dtime, &up->shm_dtime);
-	err |= __put_user(s->shm_ctime, &up->shm_ctime);
-	err |= __put_user(s->shm_segsz, &up->shm_segsz);
-	err |= __put_user(s->shm_nattch, &up->shm_nattch);
-	err |= __put_user(s->shm_cpid, &up->shm_cpid);
-	err |= __put_user(s->shm_lpid, &up->shm_lpid);
-	return err;
-}
-
-static inline int put_compat_shminfo64(struct shminfo64 *smi,
-				       struct compat_shminfo64 __user *up64)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64)))
-		return -EFAULT;
-	if (smi->shmmax > INT_MAX)
-		smi->shmmax = INT_MAX;
-	err  = __put_user(smi->shmmax, &up64->shmmax);
-	err |= __put_user(smi->shmmin, &up64->shmmin);
-	err |= __put_user(smi->shmmni, &up64->shmmni);
-	err |= __put_user(smi->shmseg, &up64->shmseg);
-	err |= __put_user(smi->shmall, &up64->shmall);
-	return err;
-}
-
-static inline int put_compat_shminfo(struct shminfo64 *smi,
-				     struct shminfo __user *up)
-{
-	int err;
-
-	if (!access_ok(VERIFY_WRITE, up, sizeof(*up)))
-		return -EFAULT;
-	if (smi->shmmax > INT_MAX)
-		smi->shmmax = INT_MAX;
-	err  = __put_user(smi->shmmax, &up->shmmax);
-	err |= __put_user(smi->shmmin, &up->shmmin);
-	err |= __put_user(smi->shmmni, &up->shmmni);
-	err |= __put_user(smi->shmseg, &up->shmseg);
-	err |= __put_user(smi->shmall, &up->shmall);
-	return err;
-}
-
-static inline int put_compat_shm_info(struct shm_info __user *ip,
-				      struct compat_shm_info __user *uip)
-{
-	int err;
-	struct shm_info si;
-
-	if (!access_ok(VERIFY_WRITE, uip, sizeof(*uip)) ||
-	    copy_from_user(&si, ip, sizeof(si)))
-		return -EFAULT;
-	err  = __put_user(si.used_ids, &uip->used_ids);
-	err |= __put_user(si.shm_tot, &uip->shm_tot);
-	err |= __put_user(si.shm_rss, &uip->shm_rss);
-	err |= __put_user(si.shm_swp, &uip->shm_swp);
-	err |= __put_user(si.swap_attempts, &uip->swap_attempts);
-	err |= __put_user(si.swap_successes, &uip->swap_successes);
-	return err;
-}
-
-COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr)
-{
-	void __user *p;
-	struct shmid64_ds sem64;
-	struct shminfo64 smi;
-	int err, err2;
-	int version = compat_ipc_parse_version(&second);
-
-	memset(&sem64, 0, sizeof(sem64));
-
-	switch (second & (~IPC_64)) {
-	case IPC_RMID:
-	case SHM_LOCK:
-	case SHM_UNLOCK:
-		err = sys_shmctl(first, second, uptr);
-		break;
-
-	case IPC_INFO:
-		p = compat_alloc_user_space(sizeof(smi));
-		err = sys_shmctl(first, second, p);
-		if (err < 0)
-			break;
-		if (copy_from_user(&smi, p, sizeof(smi)))
-			err2 = -EFAULT;
-		else if (version == IPC_64)
-			err2 = put_compat_shminfo64(&smi, uptr);
-		else
-			err2 = put_compat_shminfo(&smi, uptr);
-		if (err2)
-			err = -EFAULT;
-		break;
-
-
-	case IPC_SET:
-		if (version == IPC_64)
-			err = get_compat_shmid64_ds(&sem64, uptr);
-		else
-			err = get_compat_shmid_ds(&sem64, uptr);
-
-		if (err)
-			break;
-		p = compat_alloc_user_space(sizeof(sem64));
-		if (copy_to_user(p, &sem64, sizeof(sem64)))
-			err = -EFAULT;
-		else
-			err = sys_shmctl(first, second, p);
-		break;
-
-	case IPC_STAT:
-	case SHM_STAT:
-		p = compat_alloc_user_space(sizeof(sem64));
-		err = sys_shmctl(first, second, p);
-		if (err < 0)
-			break;
-		if (copy_from_user(&sem64, p, sizeof(sem64)))
-			err2 = -EFAULT;
-		else if (version == IPC_64)
-			err2 = put_compat_shmid64_ds(&sem64, uptr);
-		else
-			err2 = put_compat_shmid_ds(&sem64, uptr);
-		if (err2)
-			err = -EFAULT;
-		break;
-
-	case SHM_INFO:
-		p = compat_alloc_user_space(sizeof(struct shm_info));
-		err = sys_shmctl(first, second, p);
-		if (err < 0)
-			break;
-		err2 = put_compat_shm_info(p, uptr);
-		if (err2)
-			err = -EFAULT;
-		break;
-
-	default:
-		err = -EINVAL;
-		break;
-	}
-	return err;
-}
-
-COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
-		       unsigned, nsops,
-		       const struct compat_timespec __user *, timeout)
-{
-	struct timespec __user *ts64;
-	if (compat_convert_timespec(&ts64, timeout))
-		return -EFAULT;
-	return sys_semtimedop(semid, tsems, nsops, ts64);
+	to->key = from->key;
+	SET_UID(to->uid, from->uid);
+	SET_GID(to->gid, from->gid);
+	SET_UID(to->cuid, from->cuid);
+	SET_GID(to->cgid, from->cgid);
+	to->mode = from->mode;
+	to->seq = from->seq;
 }
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index eb1391b52c6f84fe75dec4e8366d858341ac665a..d240256263103f89972ab5e62201549a7074a829 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -668,11 +668,11 @@ static void __do_notify(struct mqueue_inode_info *info)
 }
 
 static int prepare_timeout(const struct timespec __user *u_abs_timeout,
-			   struct timespec *ts)
+			   struct timespec64 *ts)
 {
-	if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec)))
+	if (get_timespec64(ts, u_abs_timeout))
 		return -EFAULT;
-	if (!timespec_valid(ts))
+	if (!timespec64_valid(ts))
 		return -EINVAL;
 	return 0;
 }
@@ -962,7 +962,7 @@ static inline void pipelined_receive(struct wake_q_head *wake_q,
 
 static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
 		size_t msg_len, unsigned int msg_prio,
-		struct timespec *ts)
+		struct timespec64 *ts)
 {
 	struct fd f;
 	struct inode *inode;
@@ -979,7 +979,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
 		return -EINVAL;
 
 	if (ts) {
-		expires = timespec_to_ktime(*ts);
+		expires = timespec64_to_ktime(*ts);
 		timeout = &expires;
 	}
 
@@ -1080,7 +1080,7 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
 
 static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
 		size_t msg_len, unsigned int __user *u_msg_prio,
-		struct timespec *ts)
+		struct timespec64 *ts)
 {
 	ssize_t ret;
 	struct msg_msg *msg_ptr;
@@ -1092,7 +1092,7 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
 	struct posix_msg_tree_node *new_leaf = NULL;
 
 	if (ts) {
-		expires = timespec_to_ktime(*ts);
+		expires = timespec64_to_ktime(*ts);
 		timeout = &expires;
 	}
 
@@ -1184,7 +1184,7 @@ SYSCALL_DEFINE5(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)
 {
-	struct timespec ts, *p = NULL;
+	struct timespec64 ts, *p = NULL;
 	if (u_abs_timeout) {
 		int res = prepare_timeout(u_abs_timeout, &ts);
 		if (res)
@@ -1198,7 +1198,7 @@ SYSCALL_DEFINE5(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)
 {
-	struct timespec ts, *p = NULL;
+	struct timespec64 ts, *p = NULL;
 	if (u_abs_timeout) {
 		int res = prepare_timeout(u_abs_timeout, &ts);
 		if (res)
@@ -1475,11 +1475,11 @@ COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name,
 }
 
 static int compat_prepare_timeout(const struct compat_timespec __user *p,
-				   struct timespec *ts)
+				   struct timespec64 *ts)
 {
-	if (compat_get_timespec(ts, p))
+	if (compat_get_timespec64(ts, p))
 		return -EFAULT;
-	if (!timespec_valid(ts))
+	if (!timespec64_valid(ts))
 		return -EINVAL;
 	return 0;
 }
@@ -1489,7 +1489,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
 		       compat_size_t, msg_len, unsigned int, msg_prio,
 		       const struct compat_timespec __user *, u_abs_timeout)
 {
-	struct timespec ts, *p = NULL;
+	struct timespec64 ts, *p = NULL;
 	if (u_abs_timeout) {
 		int res = compat_prepare_timeout(u_abs_timeout, &ts);
 		if (res)
@@ -1504,7 +1504,7 @@ COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
 		       compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
 		       const struct compat_timespec __user *, u_abs_timeout)
 {
-	struct timespec ts, *p = NULL;
+	struct timespec64 ts, *p = NULL;
 	if (u_abs_timeout) {
 		int res = compat_prepare_timeout(u_abs_timeout, &ts);
 		if (res)
diff --git a/ipc/msg.c b/ipc/msg.c
index df82bc9a5531632da7763dbf5a1f08712788c44b..06be5a9adfa41c39fd155f4ebc13ada0142b1bca 100644
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -133,7 +133,7 @@ static int newque(struct ipc_namespace *ns, struct ipc_params *params)
 	}
 
 	msq->q_stime = msq->q_rtime = 0;
-	msq->q_ctime = get_seconds();
+	msq->q_ctime = ktime_get_real_seconds();
 	msq->q_cbytes = msq->q_qnum = 0;
 	msq->q_qbytes = ns->msg_ctlmnb;
 	msq->q_lspid = msq->q_lrpid = 0;
@@ -361,23 +361,17 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
  * NOTE: no locks must be held, the rwsem is taken inside this function.
  */
 static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
-		       struct msqid_ds __user *buf, int version)
+			struct msqid64_ds *msqid64)
 {
 	struct kern_ipc_perm *ipcp;
-	struct msqid64_ds uninitialized_var(msqid64);
 	struct msg_queue *msq;
 	int err;
 
-	if (cmd == IPC_SET) {
-		if (copy_msqid_from_user(&msqid64, buf, version))
-			return -EFAULT;
-	}
-
 	down_write(&msg_ids(ns).rwsem);
 	rcu_read_lock();
 
 	ipcp = ipcctl_pre_down_nolock(ns, &msg_ids(ns), msqid, cmd,
-				      &msqid64.msg_perm, msqid64.msg_qbytes);
+				      &msqid64->msg_perm, msqid64->msg_qbytes);
 	if (IS_ERR(ipcp)) {
 		err = PTR_ERR(ipcp);
 		goto out_unlock1;
@@ -399,20 +393,20 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 	{
 		DEFINE_WAKE_Q(wake_q);
 
-		if (msqid64.msg_qbytes > ns->msg_ctlmnb &&
+		if (msqid64->msg_qbytes > ns->msg_ctlmnb &&
 		    !capable(CAP_SYS_RESOURCE)) {
 			err = -EPERM;
 			goto out_unlock1;
 		}
 
 		ipc_lock_object(&msq->q_perm);
-		err = ipc_update_perm(&msqid64.msg_perm, ipcp);
+		err = ipc_update_perm(&msqid64->msg_perm, ipcp);
 		if (err)
 			goto out_unlock0;
 
-		msq->q_qbytes = msqid64.msg_qbytes;
+		msq->q_qbytes = msqid64->msg_qbytes;
 
-		msq->q_ctime = get_seconds();
+		msq->q_ctime = ktime_get_real_seconds();
 		/*
 		 * Sleeping receivers might be excluded by
 		 * stricter permissions.
@@ -442,111 +436,89 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
 	return err;
 }
 
-static int msgctl_nolock(struct ipc_namespace *ns, int msqid,
-			 int cmd, int version, void __user *buf)
+static int msgctl_info(struct ipc_namespace *ns, int msqid,
+			 int cmd, struct msginfo *msginfo)
 {
 	int err;
-	struct msg_queue *msq;
-
-	switch (cmd) {
-	case IPC_INFO:
-	case MSG_INFO:
-	{
-		struct msginfo msginfo;
-		int max_id;
-
-		if (!buf)
-			return -EFAULT;
-
-		/*
-		 * We must not return kernel stack data.
-		 * due to padding, it's not enough
-		 * to set all member fields.
-		 */
-		err = security_msg_queue_msgctl(NULL, cmd);
-		if (err)
-			return err;
+	int max_id;
 
-		memset(&msginfo, 0, sizeof(msginfo));
-		msginfo.msgmni = ns->msg_ctlmni;
-		msginfo.msgmax = ns->msg_ctlmax;
-		msginfo.msgmnb = ns->msg_ctlmnb;
-		msginfo.msgssz = MSGSSZ;
-		msginfo.msgseg = MSGSEG;
-		down_read(&msg_ids(ns).rwsem);
-		if (cmd == MSG_INFO) {
-			msginfo.msgpool = msg_ids(ns).in_use;
-			msginfo.msgmap = atomic_read(&ns->msg_hdrs);
-			msginfo.msgtql = atomic_read(&ns->msg_bytes);
-		} else {
-			msginfo.msgmap = MSGMAP;
-			msginfo.msgpool = MSGPOOL;
-			msginfo.msgtql = MSGTQL;
-		}
-		max_id = ipc_get_maxid(&msg_ids(ns));
-		up_read(&msg_ids(ns).rwsem);
-		if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
-			return -EFAULT;
-		return (max_id < 0) ? 0 : max_id;
+	/*
+	 * We must not return kernel stack data.
+	 * due to padding, it's not enough
+	 * to set all member fields.
+	 */
+	err = security_msg_queue_msgctl(NULL, cmd);
+	if (err)
+		return err;
+
+	memset(msginfo, 0, sizeof(*msginfo));
+	msginfo->msgmni = ns->msg_ctlmni;
+	msginfo->msgmax = ns->msg_ctlmax;
+	msginfo->msgmnb = ns->msg_ctlmnb;
+	msginfo->msgssz = MSGSSZ;
+	msginfo->msgseg = MSGSEG;
+	down_read(&msg_ids(ns).rwsem);
+	if (cmd == MSG_INFO) {
+		msginfo->msgpool = msg_ids(ns).in_use;
+		msginfo->msgmap = atomic_read(&ns->msg_hdrs);
+		msginfo->msgtql = atomic_read(&ns->msg_bytes);
+	} else {
+		msginfo->msgmap = MSGMAP;
+		msginfo->msgpool = MSGPOOL;
+		msginfo->msgtql = MSGTQL;
 	}
+	max_id = ipc_get_maxid(&msg_ids(ns));
+	up_read(&msg_ids(ns).rwsem);
+	return (max_id < 0) ? 0 : max_id;
+}
 
-	case MSG_STAT:
-	case IPC_STAT:
-	{
-		struct msqid64_ds tbuf;
-		int success_return;
-
-		if (!buf)
-			return -EFAULT;
-
-		memset(&tbuf, 0, sizeof(tbuf));
+static int msgctl_stat(struct ipc_namespace *ns, int msqid,
+			 int cmd, struct msqid64_ds *p)
+{
+	int err;
+	struct msg_queue *msq;
+	int success_return;
 
-		rcu_read_lock();
-		if (cmd == MSG_STAT) {
-			msq = msq_obtain_object(ns, msqid);
-			if (IS_ERR(msq)) {
-				err = PTR_ERR(msq);
-				goto out_unlock;
-			}
-			success_return = msq->q_perm.id;
-		} else {
-			msq = msq_obtain_object_check(ns, msqid);
-			if (IS_ERR(msq)) {
-				err = PTR_ERR(msq);
-				goto out_unlock;
-			}
-			success_return = 0;
-		}
+	memset(p, 0, sizeof(*p));
 
-		err = -EACCES;
-		if (ipcperms(ns, &msq->q_perm, S_IRUGO))
+	rcu_read_lock();
+	if (cmd == MSG_STAT) {
+		msq = msq_obtain_object(ns, msqid);
+		if (IS_ERR(msq)) {
+			err = PTR_ERR(msq);
 			goto out_unlock;
-
-		err = security_msg_queue_msgctl(msq, cmd);
-		if (err)
+		}
+		success_return = msq->q_perm.id;
+	} else {
+		msq = msq_obtain_object_check(ns, msqid);
+		if (IS_ERR(msq)) {
+			err = PTR_ERR(msq);
 			goto out_unlock;
+		}
+		success_return = 0;
+	}
 
-		kernel_to_ipc64_perm(&msq->q_perm, &tbuf.msg_perm);
-		tbuf.msg_stime  = msq->q_stime;
-		tbuf.msg_rtime  = msq->q_rtime;
-		tbuf.msg_ctime  = msq->q_ctime;
-		tbuf.msg_cbytes = msq->q_cbytes;
-		tbuf.msg_qnum   = msq->q_qnum;
-		tbuf.msg_qbytes = msq->q_qbytes;
-		tbuf.msg_lspid  = msq->q_lspid;
-		tbuf.msg_lrpid  = msq->q_lrpid;
-		rcu_read_unlock();
+	err = -EACCES;
+	if (ipcperms(ns, &msq->q_perm, S_IRUGO))
+		goto out_unlock;
 
-		if (copy_msqid_to_user(buf, &tbuf, version))
-			return -EFAULT;
-		return success_return;
-	}
+	err = security_msg_queue_msgctl(msq, cmd);
+	if (err)
+		goto out_unlock;
+
+	kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm);
+	p->msg_stime  = msq->q_stime;
+	p->msg_rtime  = msq->q_rtime;
+	p->msg_ctime  = msq->q_ctime;
+	p->msg_cbytes = msq->q_cbytes;
+	p->msg_qnum   = msq->q_qnum;
+	p->msg_qbytes = msq->q_qbytes;
+	p->msg_lspid  = msq->q_lspid;
+	p->msg_lrpid  = msq->q_lrpid;
+	rcu_read_unlock();
 
-	default:
-		return -EINVAL;
-	}
+	return success_return;
 
-	return err;
 out_unlock:
 	rcu_read_unlock();
 	return err;
@@ -556,6 +528,8 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
 {
 	int version;
 	struct ipc_namespace *ns;
+	struct msqid64_ds msqid64;
+	int err;
 
 	if (msqid < 0 || cmd < 0)
 		return -EINVAL;
@@ -565,18 +539,147 @@ SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, struct msqid_ds __user *, buf)
 
 	switch (cmd) {
 	case IPC_INFO:
-	case MSG_INFO:
+	case MSG_INFO: {
+		struct msginfo msginfo;
+		err = msgctl_info(ns, msqid, cmd, &msginfo);
+		if (err < 0)
+			return err;
+		if (copy_to_user(buf, &msginfo, sizeof(struct msginfo)))
+			err = -EFAULT;
+		return err;
+	}
 	case MSG_STAT:	/* msqid is an index rather than a msg queue id */
 	case IPC_STAT:
-		return msgctl_nolock(ns, msqid, cmd, version, buf);
+		err = msgctl_stat(ns, msqid, cmd, &msqid64);
+		if (err < 0)
+			return err;
+		if (copy_msqid_to_user(buf, &msqid64, version))
+			err = -EFAULT;
+		return err;
 	case IPC_SET:
+		if (copy_msqid_from_user(&msqid64, buf, version))
+			return -EFAULT;
+		/* fallthru */
 	case IPC_RMID:
-		return msgctl_down(ns, msqid, cmd, buf, version);
+		return msgctl_down(ns, msqid, cmd, &msqid64);
 	default:
 		return  -EINVAL;
 	}
 }
 
+#ifdef CONFIG_COMPAT
+
+struct compat_msqid_ds {
+	struct compat_ipc_perm msg_perm;
+	compat_uptr_t msg_first;
+	compat_uptr_t msg_last;
+	compat_time_t msg_stime;
+	compat_time_t msg_rtime;
+	compat_time_t msg_ctime;
+	compat_ulong_t msg_lcbytes;
+	compat_ulong_t msg_lqbytes;
+	unsigned short msg_cbytes;
+	unsigned short msg_qnum;
+	unsigned short msg_qbytes;
+	compat_ipc_pid_t msg_lspid;
+	compat_ipc_pid_t msg_lrpid;
+};
+
+static int copy_compat_msqid_from_user(struct msqid64_ds *out, void __user *buf,
+					int version)
+{
+	memset(out, 0, sizeof(*out));
+	if (version == IPC_64) {
+		struct compat_msqid64_ds *p = buf;
+		if (get_compat_ipc64_perm(&out->msg_perm, &p->msg_perm))
+			return -EFAULT;
+		if (get_user(out->msg_qbytes, &p->msg_qbytes))
+			return -EFAULT;
+	} else {
+		struct compat_msqid_ds *p = buf;
+		if (get_compat_ipc_perm(&out->msg_perm, &p->msg_perm))
+			return -EFAULT;
+		if (get_user(out->msg_qbytes, &p->msg_qbytes))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+static int copy_compat_msqid_to_user(void __user *buf, struct msqid64_ds *in,
+					int version)
+{
+	if (version == IPC_64) {
+		struct compat_msqid64_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc64_perm(&v.msg_perm, &in->msg_perm);
+		v.msg_stime = in->msg_stime;
+		v.msg_rtime = in->msg_rtime;
+		v.msg_ctime = in->msg_ctime;
+		v.msg_cbytes = in->msg_cbytes;
+		v.msg_qnum = in->msg_qnum;
+		v.msg_qbytes = in->msg_qbytes;
+		v.msg_lspid = in->msg_lspid;
+		v.msg_lrpid = in->msg_lrpid;
+		return copy_to_user(buf, &v, sizeof(v));
+	} else {
+		struct compat_msqid_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc_perm(&v.msg_perm, &in->msg_perm);
+		v.msg_stime = in->msg_stime;
+		v.msg_rtime = in->msg_rtime;
+		v.msg_ctime = in->msg_ctime;
+		v.msg_cbytes = in->msg_cbytes;
+		v.msg_qnum = in->msg_qnum;
+		v.msg_qbytes = in->msg_qbytes;
+		v.msg_lspid = in->msg_lspid;
+		v.msg_lrpid = in->msg_lrpid;
+		return copy_to_user(buf, &v, sizeof(v));
+	}
+}
+
+COMPAT_SYSCALL_DEFINE3(msgctl, int, msqid, int, cmd, void __user *, uptr)
+{
+	struct ipc_namespace *ns;
+	int err;
+	struct msqid64_ds msqid64;
+	int version = compat_ipc_parse_version(&cmd);
+
+	ns = current->nsproxy->ipc_ns;
+
+	if (msqid < 0 || cmd < 0)
+		return -EINVAL;
+
+	switch (cmd & (~IPC_64)) {
+	case IPC_INFO:
+	case MSG_INFO: {
+		struct msginfo msginfo;
+		err = msgctl_info(ns, msqid, cmd, &msginfo);
+		if (err < 0)
+			return err;
+		if (copy_to_user(uptr, &msginfo, sizeof(struct msginfo)))
+			err = -EFAULT;
+		return err;
+	}
+	case IPC_STAT:
+	case MSG_STAT:
+		err = msgctl_stat(ns, msqid, cmd, &msqid64);
+		if (err < 0)
+			return err;
+		if (copy_compat_msqid_to_user(uptr, &msqid64, version))
+			err = -EFAULT;
+		return err;
+	case IPC_SET:
+		if (copy_compat_msqid_from_user(&msqid64, uptr, version))
+			return -EFAULT;
+		/* fallthru */
+	case IPC_RMID:
+		return msgctl_down(ns, msqid, cmd, &msqid64);
+	default:
+		return -EINVAL;
+	}
+}
+#endif
+
 static int testmsg(struct msg_msg *msg, long type, int mode)
 {
 	switch (mode) {
@@ -627,7 +730,7 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
 	return 0;
 }
 
-long do_msgsnd(int msqid, long mtype, void __user *mtext,
+static long do_msgsnd(int msqid, long mtype, void __user *mtext,
 		size_t msgsz, int msgflg)
 {
 	struct msg_queue *msq;
@@ -750,6 +853,25 @@ SYSCALL_DEFINE4(msgsnd, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
 	return do_msgsnd(msqid, mtype, msgp->mtext, msgsz, msgflg);
 }
 
+#ifdef CONFIG_COMPAT
+
+struct compat_msgbuf {
+	compat_long_t mtype;
+	char mtext[1];
+};
+
+COMPAT_SYSCALL_DEFINE4(msgsnd, int, msqid, compat_uptr_t, msgp,
+		       compat_ssize_t, msgsz, int, msgflg)
+{
+	struct compat_msgbuf __user *up = compat_ptr(msgp);
+	compat_long_t mtype;
+
+	if (get_user(mtype, &up->mtype))
+		return -EFAULT;
+	return do_msgsnd(msqid, mtype, up->mtext, (ssize_t)msgsz, msgflg);
+}
+#endif
+
 static inline int convert_mode(long *msgtyp, int msgflg)
 {
 	if (msgflg & MSG_COPY)
@@ -846,7 +968,7 @@ static struct msg_msg *find_msg(struct msg_queue *msq, long *msgtyp, int mode)
 	return found ?: ERR_PTR(-EAGAIN);
 }
 
-long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
+static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, int msgflg,
 	       long (*msg_handler)(void __user *, struct msg_msg *, size_t))
 {
 	int mode;
@@ -1010,6 +1132,28 @@ SYSCALL_DEFINE5(msgrcv, int, msqid, struct msgbuf __user *, msgp, size_t, msgsz,
 	return do_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg, do_msg_fill);
 }
 
+#ifdef CONFIG_COMPAT
+static long compat_do_msg_fill(void __user *dest, struct msg_msg *msg, size_t bufsz)
+{
+	struct compat_msgbuf __user *msgp = dest;
+	size_t msgsz;
+
+	if (put_user(msg->m_type, &msgp->mtype))
+		return -EFAULT;
+
+	msgsz = (bufsz > msg->m_ts) ? msg->m_ts : bufsz;
+	if (store_msg(msgp->mtext, msg, msgsz))
+		return -EFAULT;
+	return msgsz;
+}
+
+COMPAT_SYSCALL_DEFINE5(msgrcv, int, msqid, compat_uptr_t, msgp,
+		       compat_ssize_t, msgsz, compat_long_t, msgtyp, int, msgflg)
+{
+	return do_msgrcv(msqid, compat_ptr(msgp), (ssize_t)msgsz, (long)msgtyp,
+			 msgflg, compat_do_msg_fill);
+}
+#endif
 
 int msg_init_ns(struct ipc_namespace *ns)
 {
@@ -1039,7 +1183,7 @@ static int sysvipc_msg_proc_show(struct seq_file *s, void *it)
 	struct msg_queue *msq = container_of(ipcp, struct msg_queue, q_perm);
 
 	seq_printf(s,
-		   "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10lu %10lu %10lu\n",
+		   "%10d %10d  %4o  %10lu %10lu %5u %5u %5u %5u %5u %5u %10llu %10llu %10llu\n",
 		   msq->q_perm.key,
 		   msq->q_perm.id,
 		   msq->q_perm.mode,
diff --git a/ipc/sem.c b/ipc/sem.c
index 013c7981f3c74ce96369a1ee5835270b4cad6924..f7385bce5fd3bd00a9d3a42b7b61c7e96f5184f3 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -512,7 +512,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 	INIT_LIST_HEAD(&sma->pending_const);
 	INIT_LIST_HEAD(&sma->list_id);
 	sma->sem_nsems = nsems;
-	sma->sem_ctime = get_seconds();
+	sma->sem_ctime = ktime_get_real_seconds();
 
 	retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
 	if (retval < 0) {
@@ -1163,14 +1163,14 @@ static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in,
 	}
 }
 
-static time_t get_semotime(struct sem_array *sma)
+static time64_t get_semotime(struct sem_array *sma)
 {
 	int i;
-	time_t res;
+	time64_t res;
 
 	res = sma->sems[0].sem_otime;
 	for (i = 1; i < sma->sem_nsems; i++) {
-		time_t to = sma->sems[i].sem_otime;
+		time64_t to = sma->sems[i].sem_otime;
 
 		if (to > res)
 			res = to;
@@ -1178,112 +1178,95 @@ static time_t get_semotime(struct sem_array *sma)
 	return res;
 }
 
-static int semctl_nolock(struct ipc_namespace *ns, int semid,
-			 int cmd, int version, void __user *p)
+static int semctl_stat(struct ipc_namespace *ns, int semid,
+			 int cmd, struct semid64_ds *semid64)
 {
-	int err;
 	struct sem_array *sma;
+	int id = 0;
+	int err;
 
-	switch (cmd) {
-	case IPC_INFO:
-	case SEM_INFO:
-	{
-		struct seminfo seminfo;
-		int max_id;
-
-		err = security_sem_semctl(NULL, cmd);
-		if (err)
-			return err;
+	memset(semid64, 0, sizeof(*semid64));
 
-		memset(&seminfo, 0, sizeof(seminfo));
-		seminfo.semmni = ns->sc_semmni;
-		seminfo.semmns = ns->sc_semmns;
-		seminfo.semmsl = ns->sc_semmsl;
-		seminfo.semopm = ns->sc_semopm;
-		seminfo.semvmx = SEMVMX;
-		seminfo.semmnu = SEMMNU;
-		seminfo.semmap = SEMMAP;
-		seminfo.semume = SEMUME;
-		down_read(&sem_ids(ns).rwsem);
-		if (cmd == SEM_INFO) {
-			seminfo.semusz = sem_ids(ns).in_use;
-			seminfo.semaem = ns->used_sems;
-		} else {
-			seminfo.semusz = SEMUSZ;
-			seminfo.semaem = SEMAEM;
+	rcu_read_lock();
+	if (cmd == SEM_STAT) {
+		sma = sem_obtain_object(ns, semid);
+		if (IS_ERR(sma)) {
+			err = PTR_ERR(sma);
+			goto out_unlock;
+		}
+		id = sma->sem_perm.id;
+	} else {
+		sma = sem_obtain_object_check(ns, semid);
+		if (IS_ERR(sma)) {
+			err = PTR_ERR(sma);
+			goto out_unlock;
 		}
-		max_id = ipc_get_maxid(&sem_ids(ns));
-		up_read(&sem_ids(ns).rwsem);
-		if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
-			return -EFAULT;
-		return (max_id < 0) ? 0 : max_id;
 	}
-	case IPC_STAT:
-	case SEM_STAT:
-	{
-		struct semid64_ds tbuf;
-		int id = 0;
-
-		memset(&tbuf, 0, sizeof(tbuf));
 
-		rcu_read_lock();
-		if (cmd == SEM_STAT) {
-			sma = sem_obtain_object(ns, semid);
-			if (IS_ERR(sma)) {
-				err = PTR_ERR(sma);
-				goto out_unlock;
-			}
-			id = sma->sem_perm.id;
-		} else {
-			sma = sem_obtain_object_check(ns, semid);
-			if (IS_ERR(sma)) {
-				err = PTR_ERR(sma);
-				goto out_unlock;
-			}
-		}
+	err = -EACCES;
+	if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
+		goto out_unlock;
 
-		err = -EACCES;
-		if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
-			goto out_unlock;
+	err = security_sem_semctl(sma, cmd);
+	if (err)
+		goto out_unlock;
 
-		err = security_sem_semctl(sma, cmd);
-		if (err)
-			goto out_unlock;
+	kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
+	semid64->sem_otime = get_semotime(sma);
+	semid64->sem_ctime = sma->sem_ctime;
+	semid64->sem_nsems = sma->sem_nsems;
+	rcu_read_unlock();
+	return id;
 
-		kernel_to_ipc64_perm(&sma->sem_perm, &tbuf.sem_perm);
-		tbuf.sem_otime = get_semotime(sma);
-		tbuf.sem_ctime = sma->sem_ctime;
-		tbuf.sem_nsems = sma->sem_nsems;
-		rcu_read_unlock();
-		if (copy_semid_to_user(p, &tbuf, version))
-			return -EFAULT;
-		return id;
-	}
-	default:
-		return -EINVAL;
-	}
 out_unlock:
 	rcu_read_unlock();
 	return err;
 }
 
+static int semctl_info(struct ipc_namespace *ns, int semid,
+			 int cmd, void __user *p)
+{
+	struct seminfo seminfo;
+	int max_id;
+	int err;
+
+	err = security_sem_semctl(NULL, cmd);
+	if (err)
+		return err;
+
+	memset(&seminfo, 0, sizeof(seminfo));
+	seminfo.semmni = ns->sc_semmni;
+	seminfo.semmns = ns->sc_semmns;
+	seminfo.semmsl = ns->sc_semmsl;
+	seminfo.semopm = ns->sc_semopm;
+	seminfo.semvmx = SEMVMX;
+	seminfo.semmnu = SEMMNU;
+	seminfo.semmap = SEMMAP;
+	seminfo.semume = SEMUME;
+	down_read(&sem_ids(ns).rwsem);
+	if (cmd == SEM_INFO) {
+		seminfo.semusz = sem_ids(ns).in_use;
+		seminfo.semaem = ns->used_sems;
+	} else {
+		seminfo.semusz = SEMUSZ;
+		seminfo.semaem = SEMAEM;
+	}
+	max_id = ipc_get_maxid(&sem_ids(ns));
+	up_read(&sem_ids(ns).rwsem);
+	if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
+		return -EFAULT;
+	return (max_id < 0) ? 0 : max_id;
+}
+
 static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
-		unsigned long arg)
+		int val)
 {
 	struct sem_undo *un;
 	struct sem_array *sma;
 	struct sem *curr;
-	int err, val;
+	int err;
 	DEFINE_WAKE_Q(wake_q);
 
-#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
-	/* big-endian 64bit */
-	val = arg >> 32;
-#else
-	/* 32bit or little-endian 64bit */
-	val = arg;
-#endif
-
 	if (val > SEMVMX || val < 0)
 		return -ERANGE;
 
@@ -1327,7 +1310,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
 
 	curr->semval = val;
 	curr->sempid = task_tgid_vnr(current);
-	sma->sem_ctime = get_seconds();
+	sma->sem_ctime = ktime_get_real_seconds();
 	/* maybe some queued-up processes were waiting for this */
 	do_smart_update(sma, NULL, 0, 0, &wake_q);
 	sem_unlock(sma, -1);
@@ -1455,7 +1438,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
 			for (i = 0; i < nsems; i++)
 				un->semadj[i] = 0;
 		}
-		sma->sem_ctime = get_seconds();
+		sma->sem_ctime = ktime_get_real_seconds();
 		/* maybe some queued-up processes were waiting for this */
 		do_smart_update(sma, NULL, 0, 0, &wake_q);
 		err = 0;
@@ -1532,23 +1515,17 @@ copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
  * NOTE: no locks must be held, the rwsem is taken inside this function.
  */
 static int semctl_down(struct ipc_namespace *ns, int semid,
-		       int cmd, int version, void __user *p)
+		       int cmd, struct semid64_ds *semid64)
 {
 	struct sem_array *sma;
 	int err;
-	struct semid64_ds semid64;
 	struct kern_ipc_perm *ipcp;
 
-	if (cmd == IPC_SET) {
-		if (copy_semid_from_user(&semid64, p, version))
-			return -EFAULT;
-	}
-
 	down_write(&sem_ids(ns).rwsem);
 	rcu_read_lock();
 
 	ipcp = ipcctl_pre_down_nolock(ns, &sem_ids(ns), semid, cmd,
-				      &semid64.sem_perm, 0);
+				      &semid64->sem_perm, 0);
 	if (IS_ERR(ipcp)) {
 		err = PTR_ERR(ipcp);
 		goto out_unlock1;
@@ -1568,10 +1545,10 @@ static int semctl_down(struct ipc_namespace *ns, int semid,
 		goto out_up;
 	case IPC_SET:
 		sem_lock(sma, NULL, -1);
-		err = ipc_update_perm(&semid64.sem_perm, ipcp);
+		err = ipc_update_perm(&semid64->sem_perm, ipcp);
 		if (err)
 			goto out_unlock0;
-		sma->sem_ctime = get_seconds();
+		sma->sem_ctime = ktime_get_real_seconds();
 		break;
 	default:
 		err = -EINVAL;
@@ -1592,6 +1569,8 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
 	int version;
 	struct ipc_namespace *ns;
 	void __user *p = (void __user *)arg;
+	struct semid64_ds semid64;
+	int err;
 
 	if (semid < 0)
 		return -EINVAL;
@@ -1602,25 +1581,136 @@ SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
 	switch (cmd) {
 	case IPC_INFO:
 	case SEM_INFO:
+		return semctl_info(ns, semid, cmd, p);
 	case IPC_STAT:
 	case SEM_STAT:
-		return semctl_nolock(ns, semid, cmd, version, p);
+		err = semctl_stat(ns, semid, cmd, &semid64);
+		if (err < 0)
+			return err;
+		if (copy_semid_to_user(p, &semid64, version))
+			err = -EFAULT;
+		return err;
 	case GETALL:
 	case GETVAL:
 	case GETPID:
 	case GETNCNT:
 	case GETZCNT:
+	case SETALL:
+		return semctl_main(ns, semid, semnum, cmd, p);
+	case SETVAL: {
+		int val;
+#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
+		/* big-endian 64bit */
+		val = arg >> 32;
+#else
+		/* 32bit or little-endian 64bit */
+		val = arg;
+#endif
+		return semctl_setval(ns, semid, semnum, val);
+	}
+	case IPC_SET:
+		if (copy_semid_from_user(&semid64, p, version))
+			return -EFAULT;
+	case IPC_RMID:
+		return semctl_down(ns, semid, cmd, &semid64);
+	default:
+		return -EINVAL;
+	}
+}
+
+#ifdef CONFIG_COMPAT
+
+struct compat_semid_ds {
+	struct compat_ipc_perm sem_perm;
+	compat_time_t sem_otime;
+	compat_time_t sem_ctime;
+	compat_uptr_t sem_base;
+	compat_uptr_t sem_pending;
+	compat_uptr_t sem_pending_last;
+	compat_uptr_t undo;
+	unsigned short sem_nsems;
+};
+
+static int copy_compat_semid_from_user(struct semid64_ds *out, void __user *buf,
+					int version)
+{
+	memset(out, 0, sizeof(*out));
+	if (version == IPC_64) {
+		struct compat_semid64_ds *p = buf;
+		return get_compat_ipc64_perm(&out->sem_perm, &p->sem_perm);
+	} else {
+		struct compat_semid_ds *p = buf;
+		return get_compat_ipc_perm(&out->sem_perm, &p->sem_perm);
+	}
+}
+
+static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in,
+					int version)
+{
+	if (version == IPC_64) {
+		struct compat_semid64_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm);
+		v.sem_otime = in->sem_otime;
+		v.sem_ctime = in->sem_ctime;
+		v.sem_nsems = in->sem_nsems;
+		return copy_to_user(buf, &v, sizeof(v));
+	} else {
+		struct compat_semid_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc_perm(&v.sem_perm, &in->sem_perm);
+		v.sem_otime = in->sem_otime;
+		v.sem_ctime = in->sem_ctime;
+		v.sem_nsems = in->sem_nsems;
+		return copy_to_user(buf, &v, sizeof(v));
+	}
+}
+
+COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
+{
+	void __user *p = compat_ptr(arg);
+	struct ipc_namespace *ns;
+	struct semid64_ds semid64;
+	int version = compat_ipc_parse_version(&cmd);
+	int err;
+
+	ns = current->nsproxy->ipc_ns;
+
+	if (semid < 0)
+		return -EINVAL;
+
+	switch (cmd & (~IPC_64)) {
+	case IPC_INFO:
+	case SEM_INFO:
+		return semctl_info(ns, semid, cmd, p);
+	case IPC_STAT:
+	case SEM_STAT:
+		err = semctl_stat(ns, semid, cmd, &semid64);
+		if (err < 0)
+			return err;
+		if (copy_compat_semid_to_user(p, &semid64, version))
+			err = -EFAULT;
+		return err;
+	case GETVAL:
+	case GETPID:
+	case GETNCNT:
+	case GETZCNT:
+	case GETALL:
 	case SETALL:
 		return semctl_main(ns, semid, semnum, cmd, p);
 	case SETVAL:
 		return semctl_setval(ns, semid, semnum, arg);
-	case IPC_RMID:
 	case IPC_SET:
-		return semctl_down(ns, semid, cmd, version, p);
+		if (copy_compat_semid_from_user(&semid64, p, version))
+			return -EFAULT;
+		/* fallthru */
+	case IPC_RMID:
+		return semctl_down(ns, semid, cmd, &semid64);
 	default:
 		return -EINVAL;
 	}
 }
+#endif
 
 /* If the task doesn't already have a undo_list, then allocate one
  * here.  We guarantee there is only one thread using this undo list,
@@ -1766,8 +1856,8 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
 	return un;
 }
 
-SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
-		unsigned, nsops, const struct timespec __user *, timeout)
+static long do_semtimedop(int semid, struct sembuf __user *tsops,
+		unsigned nsops, const struct timespec64 *timeout)
 {
 	int error = -EINVAL;
 	struct sem_array *sma;
@@ -1798,17 +1888,12 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 	}
 
 	if (timeout) {
-		struct timespec _timeout;
-		if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
-			error = -EFAULT;
-			goto out_free;
-		}
-		if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
-			_timeout.tv_nsec >= 1000000000L) {
+		if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
+			timeout->tv_nsec >= 1000000000L) {
 			error = -EINVAL;
 			goto out_free;
 		}
-		jiffies_left = timespec_to_jiffies(&_timeout);
+		jiffies_left = timespec64_to_jiffies(timeout);
 	}
 
 	max = 0;
@@ -2023,10 +2108,37 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
 	return error;
 }
 
+SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
+		unsigned, nsops, const struct timespec __user *, timeout)
+{
+	if (timeout) {
+		struct timespec64 ts;
+		if (get_timespec64(&ts, timeout))
+			return -EFAULT;
+		return do_semtimedop(semid, tsops, nsops, &ts);
+	}
+	return do_semtimedop(semid, tsops, nsops, NULL);
+}
+
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
+		       unsigned, nsops,
+		       const struct compat_timespec __user *, timeout)
+{
+	if (timeout) {
+		struct timespec64 ts;
+		if (compat_get_timespec64(&ts, timeout))
+			return -EFAULT;
+		return do_semtimedop(semid, tsems, nsops, &ts);
+	}
+	return do_semtimedop(semid, tsems, nsops, NULL);
+}
+#endif
+
 SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
 		unsigned, nsops)
 {
-	return sys_semtimedop(semid, tsops, nsops, NULL);
+	return do_semtimedop(semid, tsops, nsops, NULL);
 }
 
 /* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
@@ -2183,7 +2295,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
 	struct user_namespace *user_ns = seq_user_ns(s);
 	struct kern_ipc_perm *ipcp = it;
 	struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm);
-	time_t sem_otime;
+	time64_t sem_otime;
 
 	/*
 	 * The proc interface isn't aware of sem_lock(), it calls
@@ -2196,7 +2308,7 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
 	sem_otime = get_semotime(sma);
 
 	seq_printf(s,
-		   "%10d %10d  %4o %10u %5u %5u %5u %5u %10lu %10lu\n",
+		   "%10d %10d  %4o %10u %5u %5u %5u %5u %10llu %10llu\n",
 		   sma->sem_perm.key,
 		   sma->sem_perm.id,
 		   sma->sem_perm.mode,
diff --git a/ipc/shm.c b/ipc/shm.c
index 8fc97beb52348a4c0fb140b7b3377d3c4fa38b2f..1b3adfe3c60e259e7366aa76a23b14e7c1a173b5 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -202,7 +202,7 @@ static int __shm_open(struct vm_area_struct *vma)
 	if (IS_ERR(shp))
 		return PTR_ERR(shp);
 
-	shp->shm_atim = get_seconds();
+	shp->shm_atim = ktime_get_real_seconds();
 	shp->shm_lprid = task_tgid_vnr(current);
 	shp->shm_nattch++;
 	shm_unlock(shp);
@@ -289,7 +289,7 @@ static void shm_close(struct vm_area_struct *vma)
 		goto done; /* no-op */
 
 	shp->shm_lprid = task_tgid_vnr(current);
-	shp->shm_dtim = get_seconds();
+	shp->shm_dtim = ktime_get_real_seconds();
 	shp->shm_nattch--;
 	if (shm_may_destroy(ns, shp))
 		shm_destroy(ns, shp);
@@ -594,7 +594,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
 	shp->shm_cprid = task_tgid_vnr(current);
 	shp->shm_lprid = 0;
 	shp->shm_atim = shp->shm_dtim = 0;
-	shp->shm_ctim = get_seconds();
+	shp->shm_ctim = ktime_get_real_seconds();
 	shp->shm_segsz = size;
 	shp->shm_nattch = 0;
 	shp->shm_file = file;
@@ -815,23 +815,17 @@ static void shm_get_stat(struct ipc_namespace *ns, unsigned long *rss,
  * NOTE: no locks must be held, the rwsem is taken inside this function.
  */
 static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
-		       struct shmid_ds __user *buf, int version)
+		       struct shmid64_ds *shmid64)
 {
 	struct kern_ipc_perm *ipcp;
-	struct shmid64_ds shmid64;
 	struct shmid_kernel *shp;
 	int err;
 
-	if (cmd == IPC_SET) {
-		if (copy_shmid_from_user(&shmid64, buf, version))
-			return -EFAULT;
-	}
-
 	down_write(&shm_ids(ns).rwsem);
 	rcu_read_lock();
 
 	ipcp = ipcctl_pre_down_nolock(ns, &shm_ids(ns), shmid, cmd,
-				      &shmid64.shm_perm, 0);
+				      &shmid64->shm_perm, 0);
 	if (IS_ERR(ipcp)) {
 		err = PTR_ERR(ipcp);
 		goto out_unlock1;
@@ -851,10 +845,10 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
 		goto out_up;
 	case IPC_SET:
 		ipc_lock_object(&shp->shm_perm);
-		err = ipc_update_perm(&shmid64.shm_perm, ipcp);
+		err = ipc_update_perm(&shmid64->shm_perm, ipcp);
 		if (err)
 			goto out_unlock0;
-		shp->shm_ctim = get_seconds();
+		shp->shm_ctim = ktime_get_real_seconds();
 		break;
 	default:
 		err = -EINVAL;
@@ -870,125 +864,175 @@ static int shmctl_down(struct ipc_namespace *ns, int shmid, int cmd,
 	return err;
 }
 
-static int shmctl_nolock(struct ipc_namespace *ns, int shmid,
-			 int cmd, int version, void __user *buf)
+static int shmctl_ipc_info(struct ipc_namespace *ns,
+			   struct shminfo64 *shminfo)
 {
-	int err;
-	struct shmid_kernel *shp;
-
-	/* preliminary security checks for *_INFO */
-	if (cmd == IPC_INFO || cmd == SHM_INFO) {
-		err = security_shm_shmctl(NULL, cmd);
-		if (err)
-			return err;
-	}
-
-	switch (cmd) {
-	case IPC_INFO:
-	{
-		struct shminfo64 shminfo;
-
-		memset(&shminfo, 0, sizeof(shminfo));
-		shminfo.shmmni = shminfo.shmseg = ns->shm_ctlmni;
-		shminfo.shmmax = ns->shm_ctlmax;
-		shminfo.shmall = ns->shm_ctlall;
-
-		shminfo.shmmin = SHMMIN;
-		if (copy_shminfo_to_user(buf, &shminfo, version))
-			return -EFAULT;
-
+	int err = security_shm_shmctl(NULL, IPC_INFO);
+	if (!err) {
+		memset(shminfo, 0, sizeof(*shminfo));
+		shminfo->shmmni = shminfo->shmseg = ns->shm_ctlmni;
+		shminfo->shmmax = ns->shm_ctlmax;
+		shminfo->shmall = ns->shm_ctlall;
+		shminfo->shmmin = SHMMIN;
 		down_read(&shm_ids(ns).rwsem);
 		err = ipc_get_maxid(&shm_ids(ns));
 		up_read(&shm_ids(ns).rwsem);
-
 		if (err < 0)
 			err = 0;
-		goto out;
 	}
-	case SHM_INFO:
-	{
-		struct shm_info shm_info;
+	return err;
+}
 
-		memset(&shm_info, 0, sizeof(shm_info));
+static int shmctl_shm_info(struct ipc_namespace *ns,
+			   struct shm_info *shm_info)
+{
+	int err = security_shm_shmctl(NULL, SHM_INFO);
+	if (!err) {
+		memset(shm_info, 0, sizeof(*shm_info));
 		down_read(&shm_ids(ns).rwsem);
-		shm_info.used_ids = shm_ids(ns).in_use;
-		shm_get_stat(ns, &shm_info.shm_rss, &shm_info.shm_swp);
-		shm_info.shm_tot = ns->shm_tot;
-		shm_info.swap_attempts = 0;
-		shm_info.swap_successes = 0;
+		shm_info->used_ids = shm_ids(ns).in_use;
+		shm_get_stat(ns, &shm_info->shm_rss, &shm_info->shm_swp);
+		shm_info->shm_tot = ns->shm_tot;
+		shm_info->swap_attempts = 0;
+		shm_info->swap_successes = 0;
 		err = ipc_get_maxid(&shm_ids(ns));
 		up_read(&shm_ids(ns).rwsem);
-		if (copy_to_user(buf, &shm_info, sizeof(shm_info))) {
-			err = -EFAULT;
-			goto out;
+		if (err < 0)
+			err = 0;
+	}
+	return err;
+}
+
+static int shmctl_stat(struct ipc_namespace *ns, int shmid,
+			int cmd, struct shmid64_ds *tbuf)
+{
+	struct shmid_kernel *shp;
+	int result;
+	int err;
+
+	rcu_read_lock();
+	if (cmd == SHM_STAT) {
+		shp = shm_obtain_object(ns, shmid);
+		if (IS_ERR(shp)) {
+			err = PTR_ERR(shp);
+			goto out_unlock;
+		}
+		result = shp->shm_perm.id;
+	} else {
+		shp = shm_obtain_object_check(ns, shmid);
+		if (IS_ERR(shp)) {
+			err = PTR_ERR(shp);
+			goto out_unlock;
 		}
+		result = 0;
+	}
 
-		err = err < 0 ? 0 : err;
-		goto out;
+	err = -EACCES;
+	if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
+		goto out_unlock;
+
+	err = security_shm_shmctl(shp, cmd);
+	if (err)
+		goto out_unlock;
+
+	memset(tbuf, 0, sizeof(*tbuf));
+	kernel_to_ipc64_perm(&shp->shm_perm, &tbuf->shm_perm);
+	tbuf->shm_segsz	= shp->shm_segsz;
+	tbuf->shm_atime	= shp->shm_atim;
+	tbuf->shm_dtime	= shp->shm_dtim;
+	tbuf->shm_ctime	= shp->shm_ctim;
+	tbuf->shm_cpid	= shp->shm_cprid;
+	tbuf->shm_lpid	= shp->shm_lprid;
+	tbuf->shm_nattch = shp->shm_nattch;
+	rcu_read_unlock();
+	return result;
+
+out_unlock:
+	rcu_read_unlock();
+	return err;
+}
+
+static int shmctl_do_lock(struct ipc_namespace *ns, int shmid, int cmd)
+{
+	struct shmid_kernel *shp;
+	struct file *shm_file;
+	int err;
+
+	rcu_read_lock();
+	shp = shm_obtain_object_check(ns, shmid);
+	if (IS_ERR(shp)) {
+		err = PTR_ERR(shp);
+		goto out_unlock1;
 	}
-	case SHM_STAT:
-	case IPC_STAT:
-	{
-		struct shmid64_ds tbuf;
-		int result;
-
-		rcu_read_lock();
-		if (cmd == SHM_STAT) {
-			shp = shm_obtain_object(ns, shmid);
-			if (IS_ERR(shp)) {
-				err = PTR_ERR(shp);
-				goto out_unlock;
-			}
-			result = shp->shm_perm.id;
-		} else {
-			shp = shm_obtain_object_check(ns, shmid);
-			if (IS_ERR(shp)) {
-				err = PTR_ERR(shp);
-				goto out_unlock;
-			}
-			result = 0;
-		}
 
-		err = -EACCES;
-		if (ipcperms(ns, &shp->shm_perm, S_IRUGO))
-			goto out_unlock;
+	audit_ipc_obj(&(shp->shm_perm));
+	err = security_shm_shmctl(shp, cmd);
+	if (err)
+		goto out_unlock1;
 
-		err = security_shm_shmctl(shp, cmd);
-		if (err)
-			goto out_unlock;
+	ipc_lock_object(&shp->shm_perm);
 
-		memset(&tbuf, 0, sizeof(tbuf));
-		kernel_to_ipc64_perm(&shp->shm_perm, &tbuf.shm_perm);
-		tbuf.shm_segsz	= shp->shm_segsz;
-		tbuf.shm_atime	= shp->shm_atim;
-		tbuf.shm_dtime	= shp->shm_dtim;
-		tbuf.shm_ctime	= shp->shm_ctim;
-		tbuf.shm_cpid	= shp->shm_cprid;
-		tbuf.shm_lpid	= shp->shm_lprid;
-		tbuf.shm_nattch	= shp->shm_nattch;
-		rcu_read_unlock();
-
-		if (copy_shmid_to_user(buf, &tbuf, version))
-			err = -EFAULT;
-		else
-			err = result;
-		goto out;
+	/* check if shm_destroy() is tearing down shp */
+	if (!ipc_valid_object(&shp->shm_perm)) {
+		err = -EIDRM;
+		goto out_unlock0;
 	}
-	default:
-		return -EINVAL;
+
+	if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
+		kuid_t euid = current_euid();
+
+		if (!uid_eq(euid, shp->shm_perm.uid) &&
+		    !uid_eq(euid, shp->shm_perm.cuid)) {
+			err = -EPERM;
+			goto out_unlock0;
+		}
+		if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) {
+			err = -EPERM;
+			goto out_unlock0;
+		}
 	}
 
-out_unlock:
+	shm_file = shp->shm_file;
+	if (is_file_hugepages(shm_file))
+		goto out_unlock0;
+
+	if (cmd == SHM_LOCK) {
+		struct user_struct *user = current_user();
+
+		err = shmem_lock(shm_file, 1, user);
+		if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) {
+			shp->shm_perm.mode |= SHM_LOCKED;
+			shp->mlock_user = user;
+		}
+		goto out_unlock0;
+	}
+
+	/* SHM_UNLOCK */
+	if (!(shp->shm_perm.mode & SHM_LOCKED))
+		goto out_unlock0;
+	shmem_lock(shm_file, 0, shp->mlock_user);
+	shp->shm_perm.mode &= ~SHM_LOCKED;
+	shp->mlock_user = NULL;
+	get_file(shm_file);
+	ipc_unlock_object(&shp->shm_perm);
+	rcu_read_unlock();
+	shmem_unlock_mapping(shm_file->f_mapping);
+
+	fput(shm_file);
+	return err;
+
+out_unlock0:
+	ipc_unlock_object(&shp->shm_perm);
+out_unlock1:
 	rcu_read_unlock();
-out:
 	return err;
 }
 
 SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
 {
-	struct shmid_kernel *shp;
 	int err, version;
 	struct ipc_namespace *ns;
+	struct shmid64_ds sem64;
 
 	if (cmd < 0 || shmid < 0)
 		return -EINVAL;
@@ -997,92 +1041,222 @@ SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, struct shmid_ds __user *, buf)
 	ns = current->nsproxy->ipc_ns;
 
 	switch (cmd) {
-	case IPC_INFO:
-	case SHM_INFO:
+	case IPC_INFO: {
+		struct shminfo64 shminfo;
+		err = shmctl_ipc_info(ns, &shminfo);
+		if (err < 0)
+			return err;
+		if (copy_shminfo_to_user(buf, &shminfo, version))
+			err = -EFAULT;
+		return err;
+	}
+	case SHM_INFO: {
+		struct shm_info shm_info;
+		err = shmctl_shm_info(ns, &shm_info);
+		if (err < 0)
+			return err;
+		if (copy_to_user(buf, &shm_info, sizeof(shm_info)))
+			err = -EFAULT;
+		return err;
+	}
 	case SHM_STAT:
-	case IPC_STAT:
-		return shmctl_nolock(ns, shmid, cmd, version, buf);
-	case IPC_RMID:
+	case IPC_STAT: {
+		err = shmctl_stat(ns, shmid, cmd, &sem64);
+		if (err < 0)
+			return err;
+		if (copy_shmid_to_user(buf, &sem64, version))
+			err = -EFAULT;
+		return err;
+	}
 	case IPC_SET:
-		return shmctl_down(ns, shmid, cmd, buf, version);
+		if (copy_shmid_from_user(&sem64, buf, version))
+			return -EFAULT;
+		/* fallthru */
+	case IPC_RMID:
+		return shmctl_down(ns, shmid, cmd, &sem64);
 	case SHM_LOCK:
 	case SHM_UNLOCK:
-	{
-		struct file *shm_file;
+		return shmctl_do_lock(ns, shmid, cmd);
+	default:
+		return -EINVAL;
+	}
+}
 
-		rcu_read_lock();
-		shp = shm_obtain_object_check(ns, shmid);
-		if (IS_ERR(shp)) {
-			err = PTR_ERR(shp);
-			goto out_unlock1;
-		}
+#ifdef CONFIG_COMPAT
+
+struct compat_shmid_ds {
+	struct compat_ipc_perm shm_perm;
+	int shm_segsz;
+	compat_time_t shm_atime;
+	compat_time_t shm_dtime;
+	compat_time_t shm_ctime;
+	compat_ipc_pid_t shm_cpid;
+	compat_ipc_pid_t shm_lpid;
+	unsigned short shm_nattch;
+	unsigned short shm_unused;
+	compat_uptr_t shm_unused2;
+	compat_uptr_t shm_unused3;
+};
 
-		audit_ipc_obj(&(shp->shm_perm));
-		err = security_shm_shmctl(shp, cmd);
-		if (err)
-			goto out_unlock1;
+struct compat_shminfo64 {
+	compat_ulong_t shmmax;
+	compat_ulong_t shmmin;
+	compat_ulong_t shmmni;
+	compat_ulong_t shmseg;
+	compat_ulong_t shmall;
+	compat_ulong_t __unused1;
+	compat_ulong_t __unused2;
+	compat_ulong_t __unused3;
+	compat_ulong_t __unused4;
+};
 
-		ipc_lock_object(&shp->shm_perm);
+struct compat_shm_info {
+	compat_int_t used_ids;
+	compat_ulong_t shm_tot, shm_rss, shm_swp;
+	compat_ulong_t swap_attempts, swap_successes;
+};
 
-		/* check if shm_destroy() is tearing down shp */
-		if (!ipc_valid_object(&shp->shm_perm)) {
-			err = -EIDRM;
-			goto out_unlock0;
-		}
+static int copy_compat_shminfo_to_user(void __user *buf, struct shminfo64 *in,
+					int version)
+{
+	if (in->shmmax > INT_MAX)
+		in->shmmax = INT_MAX;
+	if (version == IPC_64) {
+		struct compat_shminfo64 info;
+		memset(&info, 0, sizeof(info));
+		info.shmmax = in->shmmax;
+		info.shmmin = in->shmmin;
+		info.shmmni = in->shmmni;
+		info.shmseg = in->shmseg;
+		info.shmall = in->shmall;
+		return copy_to_user(buf, &info, sizeof(info));
+	} else {
+		struct shminfo info;
+		memset(&info, 0, sizeof(info));
+		info.shmmax = in->shmmax;
+		info.shmmin = in->shmmin;
+		info.shmmni = in->shmmni;
+		info.shmseg = in->shmseg;
+		info.shmall = in->shmall;
+		return copy_to_user(buf, &info, sizeof(info));
+	}
+}
 
-		if (!ns_capable(ns->user_ns, CAP_IPC_LOCK)) {
-			kuid_t euid = current_euid();
-
-			if (!uid_eq(euid, shp->shm_perm.uid) &&
-			    !uid_eq(euid, shp->shm_perm.cuid)) {
-				err = -EPERM;
-				goto out_unlock0;
-			}
-			if (cmd == SHM_LOCK && !rlimit(RLIMIT_MEMLOCK)) {
-				err = -EPERM;
-				goto out_unlock0;
-			}
-		}
+static int put_compat_shm_info(struct shm_info *ip,
+				struct compat_shm_info __user *uip)
+{
+	struct compat_shm_info info;
+
+	memset(&info, 0, sizeof(info));
+	info.used_ids = ip->used_ids;
+	info.shm_tot = ip->shm_tot;
+	info.shm_rss = ip->shm_rss;
+	info.shm_swp = ip->shm_swp;
+	info.swap_attempts = ip->swap_attempts;
+	info.swap_successes = ip->swap_successes;
+	return copy_to_user(up, &info, sizeof(info));
+}
 
-		shm_file = shp->shm_file;
-		if (is_file_hugepages(shm_file))
-			goto out_unlock0;
+static int copy_compat_shmid_to_user(void __user *buf, struct shmid64_ds *in,
+					int version)
+{
+	if (version == IPC_64) {
+		struct compat_shmid64_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc64_perm(&v.shm_perm, &in->shm_perm);
+		v.shm_atime = in->shm_atime;
+		v.shm_dtime = in->shm_dtime;
+		v.shm_ctime = in->shm_ctime;
+		v.shm_segsz = in->shm_segsz;
+		v.shm_nattch = in->shm_nattch;
+		v.shm_cpid = in->shm_cpid;
+		v.shm_lpid = in->shm_lpid;
+		return copy_to_user(buf, &v, sizeof(v));
+	} else {
+		struct compat_shmid_ds v;
+		memset(&v, 0, sizeof(v));
+		to_compat_ipc_perm(&v.shm_perm, &in->shm_perm);
+		v.shm_perm.key = in->shm_perm.key;
+		v.shm_atime = in->shm_atime;
+		v.shm_dtime = in->shm_dtime;
+		v.shm_ctime = in->shm_ctime;
+		v.shm_segsz = in->shm_segsz;
+		v.shm_nattch = in->shm_nattch;
+		v.shm_cpid = in->shm_cpid;
+		v.shm_lpid = in->shm_lpid;
+		return copy_to_user(buf, &v, sizeof(v));
+	}
+}
 
-		if (cmd == SHM_LOCK) {
-			struct user_struct *user = current_user();
+static int copy_compat_shmid_from_user(struct shmid64_ds *out, void __user *buf,
+					int version)
+{
+	memset(out, 0, sizeof(*out));
+	if (version == IPC_64) {
+		struct compat_shmid64_ds *p = buf;
+		return get_compat_ipc64_perm(&out->shm_perm, &p->shm_perm);
+	} else {
+		struct compat_shmid_ds *p = buf;
+		return get_compat_ipc_perm(&out->shm_perm, &p->shm_perm);
+	}
+}
 
-			err = shmem_lock(shm_file, 1, user);
-			if (!err && !(shp->shm_perm.mode & SHM_LOCKED)) {
-				shp->shm_perm.mode |= SHM_LOCKED;
-				shp->mlock_user = user;
-			}
-			goto out_unlock0;
-		}
+COMPAT_SYSCALL_DEFINE3(shmctl, int, shmid, int, cmd, void __user *, uptr)
+{
+	struct ipc_namespace *ns;
+	struct shmid64_ds sem64;
+	int version = compat_ipc_parse_version(&cmd);
+	int err;
 
-		/* SHM_UNLOCK */
-		if (!(shp->shm_perm.mode & SHM_LOCKED))
-			goto out_unlock0;
-		shmem_lock(shm_file, 0, shp->mlock_user);
-		shp->shm_perm.mode &= ~SHM_LOCKED;
-		shp->mlock_user = NULL;
-		get_file(shm_file);
-		ipc_unlock_object(&shp->shm_perm);
-		rcu_read_unlock();
-		shmem_unlock_mapping(shm_file->f_mapping);
+	ns = current->nsproxy->ipc_ns;
+
+	if (cmd < 0 || shmid < 0)
+		return -EINVAL;
 
-		fput(shm_file);
+	switch (cmd) {
+	case IPC_INFO: {
+		struct shminfo64 shminfo;
+		err = shmctl_ipc_info(ns, &shminfo);
+		if (err < 0)
+			return err;
+		if (copy_compat_shminfo_to_user(uptr, &shminfo, version))
+			err = -EFAULT;
+		return err;
+	}
+	case SHM_INFO: {
+		struct shm_info shm_info;
+		err = shmctl_shm_info(ns, &shm_info);
+		if (err < 0)
+			return err;
+		if (put_compat_shm_info(&shm_info, uptr))
+			err = -EFAULT;
 		return err;
 	}
+	case IPC_STAT:
+	case SHM_STAT:
+		err = shmctl_stat(ns, shmid, cmd, &sem64);
+		if (err < 0)
+			return err;
+		if (copy_compat_shmid_to_user(&sem64, uptr, version))
+			err = -EFAULT;
+		return err;
+
+	case IPC_SET:
+		if (copy_compat_shmid_from_user(&sem64, uptr, version))
+			return -EFAULT;
+		/* fallthru */
+	case IPC_RMID:
+		return shmctl_down(ns, shmid, cmd, &sem64);
+	case SHM_LOCK:
+	case SHM_UNLOCK:
+		return shmctl_do_lock(ns, shmid, cmd);
+		break;
 	default:
 		return -EINVAL;
 	}
-
-out_unlock0:
-	ipc_unlock_object(&shp->shm_perm);
-out_unlock1:
-	rcu_read_unlock();
 	return err;
 }
+#endif
 
 /*
  * Fix shmaddr, allocate descriptor, map shm, add attach descriptor to lists.
@@ -1267,6 +1441,25 @@ SYSCALL_DEFINE3(shmat, int, shmid, char __user *, shmaddr, int, shmflg)
 	return (long)ret;
 }
 
+#ifdef CONFIG_COMPAT
+
+#ifndef COMPAT_SHMLBA
+#define COMPAT_SHMLBA	SHMLBA
+#endif
+
+COMPAT_SYSCALL_DEFINE3(shmat, int, shmid, compat_uptr_t, shmaddr, int, shmflg)
+{
+	unsigned long ret;
+	long err;
+
+	err = do_shmat(shmid, compat_ptr(shmaddr), shmflg, &ret, COMPAT_SHMLBA);
+	if (err)
+		return err;
+	force_successful_syscall_return();
+	return (long)ret;
+}
+#endif
+
 /*
  * detach and kill segment if marked destroyed.
  * The work is done in shm_close.
@@ -1397,7 +1590,7 @@ static int sysvipc_shm_proc_show(struct seq_file *s, void *it)
 
 	seq_printf(s,
 		   "%10d %10d  %4o " SIZE_SPEC " %5u %5u  "
-		   "%5lu %5u %5u %5u %5u %10lu %10lu %10lu "
+		   "%5lu %5u %5u %5u %5u %10llu %10llu %10llu "
 		   SIZE_SPEC " " SIZE_SPEC "\n",
 		   shp->shm_perm.key,
 		   shp->shm_perm.id,
diff --git a/ipc/syscall.c b/ipc/syscall.c
index 52429489cde0070ab9398648ca326592e824a2a7..667022746ca56914e77fcb0b9a1c23ff4b02d3d6 100644
--- a/ipc/syscall.c
+++ b/ipc/syscall.c
@@ -5,12 +5,12 @@
  * the individual syscalls instead.
  */
 #include <linux/unistd.h>
+#include <linux/syscalls.h>
 
 #ifdef __ARCH_WANT_SYS_IPC
 #include <linux/errno.h>
 #include <linux/ipc.h>
 #include <linux/shm.h>
-#include <linux/syscalls.h>
 #include <linux/uaccess.h>
 
 SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
@@ -97,3 +97,91 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
 	}
 }
 #endif
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+
+#ifndef COMPAT_SHMLBA
+#define COMPAT_SHMLBA	SHMLBA
+#endif
+
+struct compat_ipc_kludge {
+	compat_uptr_t msgp;
+	compat_long_t msgtyp;
+};
+
+#ifdef CONFIG_ARCH_WANT_OLD_COMPAT_IPC
+COMPAT_SYSCALL_DEFINE6(ipc, u32, call, int, first, int, second,
+	u32, third, compat_uptr_t, ptr, u32, fifth)
+{
+	int version;
+	u32 pad;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		/* struct sembuf is the same on 32 and 64bit :)) */
+		return sys_semtimedop(first, compat_ptr(ptr), second, NULL);
+	case SEMTIMEDOP:
+		return compat_sys_semtimedop(first, compat_ptr(ptr), second,
+						compat_ptr(fifth));
+	case SEMGET:
+		return sys_semget(first, second, third);
+	case SEMCTL:
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(pad, (u32 __user *) compat_ptr(ptr)))
+			return -EFAULT;
+		return compat_sys_semctl(first, second, third, pad);
+
+	case MSGSND:
+		return compat_sys_msgsnd(first, ptr, second, third);
+
+	case MSGRCV: {
+		void __user *uptr = compat_ptr(ptr);
+
+		if (first < 0 || second < 0)
+			return -EINVAL;
+
+		if (!version) {
+			struct compat_ipc_kludge ipck;
+			if (!uptr)
+				return -EINVAL;
+			if (copy_from_user(&ipck, uptr, sizeof(ipck)))
+				return -EFAULT;
+			return compat_sys_msgrcv(first, ipck.msgp, second,
+						 ipck.msgtyp, third);
+		}
+		return compat_sys_msgrcv(first, ptr, second, fifth, third);
+	}
+	case MSGGET:
+		return sys_msgget(first, second);
+	case MSGCTL:
+		return compat_sys_msgctl(first, second, compat_ptr(ptr));
+
+	case SHMAT: {
+		int err;
+		unsigned long raddr;
+
+		if (version == 1)
+			return -EINVAL;
+		err = do_shmat(first, compat_ptr(ptr), second, &raddr,
+			       COMPAT_SHMLBA);
+		if (err < 0)
+			return err;
+		return put_user(raddr, (compat_ulong_t *)compat_ptr(third));
+	}
+	case SHMDT:
+		return sys_shmdt(compat_ptr(ptr));
+	case SHMGET:
+		return sys_shmget(first, (unsigned)second, third);
+	case SHMCTL:
+		return compat_sys_shmctl(first, second, compat_ptr(ptr));
+	}
+
+	return -ENOSYS;
+}
+#endif
+#endif
diff --git a/ipc/util.h b/ipc/util.h
index 80c9f51c3f07bed4bad42edec9f71177d69ff1e4..b21297bc11ebfe4bd65317e59a401a2fcd49e566 100644
--- a/ipc/util.h
+++ b/ipc/util.h
@@ -194,4 +194,34 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
 			const struct ipc_ops *ops, struct ipc_params *params);
 void free_ipcs(struct ipc_namespace *ns, struct ipc_ids *ids,
 		void (*free)(struct ipc_namespace *, struct kern_ipc_perm *));
+
+#ifdef CONFIG_COMPAT
+#include <linux/compat.h>
+struct compat_ipc_perm {
+	key_t key;
+	__compat_uid_t uid;
+	__compat_gid_t gid;
+	__compat_uid_t cuid;
+	__compat_gid_t cgid;
+	compat_mode_t mode;
+	unsigned short seq;
+};
+
+void to_compat_ipc_perm(struct compat_ipc_perm *, struct ipc64_perm *);
+void to_compat_ipc64_perm(struct compat_ipc64_perm *, struct ipc64_perm *);
+int get_compat_ipc_perm(struct ipc64_perm *, struct compat_ipc_perm __user *);
+int get_compat_ipc64_perm(struct ipc64_perm *,
+			  struct compat_ipc64_perm __user *);
+
+static inline int compat_ipc_parse_version(int *cmd)
+{
+#ifdef	CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
+	int version = *cmd & IPC_64;
+	*cmd &= ~IPC_64;
+	return version;
+#else
+	return IPC_64;
+#endif
+}
+#endif
 #endif
diff --git a/kernel/audit.h b/kernel/audit.h
index b331d9b83f6344c9194462bf31dc1e55e7e7c0d8..9b110ae17ee3fe744592fdb1127d1dc868577af2 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -182,7 +182,7 @@ struct audit_context {
 			mqd_t			mqdes;
 			size_t			msg_len;
 			unsigned int		msg_prio;
-			struct timespec		abs_timeout;
+			struct timespec64	abs_timeout;
 		} mq_sendrecv;
 		struct {
 			int			oflag;
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index aac1a41f82bd78d3fed70a048abf348d4b07b941..ecc23e25c9eb2b3aedf5db585905d7b044d6b276 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -1235,11 +1235,11 @@ static void show_special(struct audit_context *context, int *call_panic)
 	case AUDIT_MQ_SENDRECV:
 		audit_log_format(ab,
 			"mqdes=%d msg_len=%zd msg_prio=%u "
-			"abs_timeout_sec=%ld abs_timeout_nsec=%ld",
+			"abs_timeout_sec=%lld abs_timeout_nsec=%ld",
 			context->mq_sendrecv.mqdes,
 			context->mq_sendrecv.msg_len,
 			context->mq_sendrecv.msg_prio,
-			context->mq_sendrecv.abs_timeout.tv_sec,
+			(long long) context->mq_sendrecv.abs_timeout.tv_sec,
 			context->mq_sendrecv.abs_timeout.tv_nsec);
 		break;
 	case AUDIT_MQ_NOTIFY:
@@ -2083,15 +2083,15 @@ void __audit_mq_open(int oflag, umode_t mode, struct mq_attr *attr)
  *
  */
 void __audit_mq_sendrecv(mqd_t mqdes, size_t msg_len, unsigned int msg_prio,
-			const struct timespec *abs_timeout)
+			const struct timespec64 *abs_timeout)
 {
 	struct audit_context *context = current->audit_context;
-	struct timespec *p = &context->mq_sendrecv.abs_timeout;
+	struct timespec64 *p = &context->mq_sendrecv.abs_timeout;
 
 	if (abs_timeout)
-		memcpy(p, abs_timeout, sizeof(struct timespec));
+		memcpy(p, abs_timeout, sizeof(*p));
 	else
-		memset(p, 0, sizeof(struct timespec));
+		memset(p, 0, sizeof(*p));
 
 	context->mq_sendrecv.mqdes = mqdes;
 	context->mq_sendrecv.msg_len = msg_len;
diff --git a/kernel/compat.c b/kernel/compat.c
index 6f0a0e723a0622a8876f9bfc81bbe08346db2ffd..772e038d04d9a85ef6e78c2df8924ca5348fce78 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -200,29 +200,6 @@ int compat_put_timespec(const struct timespec *ts, void __user *uts)
 }
 EXPORT_SYMBOL_GPL(compat_put_timespec);
 
-int compat_convert_timespec(struct timespec __user **kts,
-			    const void __user *cts)
-{
-	struct timespec ts;
-	struct timespec __user *uts;
-
-	if (!cts || COMPAT_USE_64BIT_TIME) {
-		*kts = (struct timespec __user *)cts;
-		return 0;
-	}
-
-	uts = compat_alloc_user_space(sizeof(ts));
-	if (!uts)
-		return -EFAULT;
-	if (compat_get_timespec(&ts, cts))
-		return -EFAULT;
-	if (copy_to_user(uts, &ts, sizeof(ts)))
-		return -EFAULT;
-
-	*kts = uts;
-	return 0;
-}
-
 int get_compat_itimerval(struct itimerval *o, const struct compat_itimerval __user *i)
 {
 	struct compat_itimerval v32;