diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h
index a56e608db2f9e4aad716b96669de02c7571dc1df..b37153ecf2ac33e19b7df4b061afddf4238f7ebb 100644
--- a/arch/alpha/include/asm/unistd.h
+++ b/arch/alpha/include/asm/unistd.h
@@ -10,7 +10,6 @@
 #define __ARCH_WANT_SYS_GETHOSTNAME
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_FORK
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index 59db80193454dab9c3c837b5bc7ac50f64102fdd..de602533a3bd28f410b13542e010404ca81a0cab 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -18,7 +18,6 @@
 #define __ARCH_WANT_SYS_FADVISE64
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT /*will be unused*/
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_CLONE
 #define __ARCH_WANT_SYS_FORK
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index e55813029d5a2fcf2c67c428a4ff4eea94b44ecb..3c09450908aa055c3b1cb6f5c43889cfe9a4e99d 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -35,7 +35,6 @@
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLD_UNAME
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
diff --git a/arch/parisc/include/asm/unistd.h b/arch/parisc/include/asm/unistd.h
index 5f4c68daa261727c614392346926d22fbef7eaa6..7dc31c84dd37c9f2f17709447b3000107fe200ef 100644
--- a/arch/parisc/include/asm/unistd.h
+++ b/arch/parisc/include/asm/unistd.h
@@ -156,7 +156,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5)	\
 #define __ARCH_WANT_SYS_GETPGRP
 #define __ARCH_WANT_SYS_LLSEEK
 #define __ARCH_WANT_SYS_NICE
-#define __ARCH_WANT_SYS_OLD_GETRLIMIT
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
index 4f2df589ec1de2e227d0ed7fa43fddf1eecff3ee..f256e1d14a147f417eb537cd5467ecacf84655bf 100644
--- a/arch/powerpc/include/asm/compat.h
+++ b/arch/powerpc/include/asm/compat.h
@@ -109,7 +109,6 @@ struct compat_statfs {
 	int		f_spare[4];
 };
 
-#define COMPAT_RLIM_OLD_INFINITY	0x7fffffff
 #define COMPAT_RLIM_INFINITY		0xffffffff
 
 typedef u32		compat_old_sigset_t;
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index 0ddd37e6c29d90e2b996d9056b89a3d367582eae..b9300f8aee10a5754909e63946c6f06d0bbc74f1 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -178,7 +178,6 @@ struct compat_statfs64 {
 	u32		f_spare[4];
 };
 
-#define COMPAT_RLIM_OLD_INFINITY	0x7fffffff
 #define COMPAT_RLIM_INFINITY		0xffffffff
 
 typedef u32		compat_old_sigset_t;	/* at least 32 bits */
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
index 24118c0b464090372fbd831a891890ecb8debd9b..5343c19814b381065492a58ddf49ca8b7ec814bc 100644
--- a/arch/x86/include/asm/compat.h
+++ b/arch/x86/include/asm/compat.h
@@ -116,7 +116,6 @@ struct compat_statfs {
 	int		f_spare[4];
 };
 
-#define COMPAT_RLIM_OLD_INFINITY	0x7fffffff
 #define COMPAT_RLIM_INFINITY		0xffffffff
 
 typedef u32		compat_old_sigset_t;	/* at least 32 bits */
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 04325b81c2b410ed560b43af82a4a906e040f16d..38554c2ea38adc28f0835b35f65cdb2c94451656 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -4,7 +4,6 @@
 #include <linux/cdrom.h>
 #include <linux/compat.h>
 #include <linux/elevator.h>
-#include <linux/fd.h>
 #include <linux/hdreg.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
@@ -80,19 +79,16 @@ static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
 static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
 		unsigned int cmd, unsigned long arg)
 {
-	mm_segment_t old_fs = get_fs();
-	unsigned long kval;
-	unsigned int __user *uvp;
+	unsigned long *__user p;
 	int error;
 
-	set_fs(KERNEL_DS);
+	p = compat_alloc_user_space(sizeof(unsigned long));
 	error = __blkdev_driver_ioctl(bdev, mode,
-				cmd, (unsigned long)(&kval));
-	set_fs(old_fs);
-
+				cmd, (unsigned long)p);
 	if (error == 0) {
-		uvp = compat_ptr(arg);
-		if (put_user(kval, uvp))
+		unsigned int __user *uvp = compat_ptr(arg);
+		unsigned long v;
+		if (get_user(v, p) || put_user(v, uvp))
 			error = -EFAULT;
 	}
 	return error;
@@ -209,318 +205,6 @@ static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
 #define BLKBSZSET_32		_IOW(0x12, 113, int)
 #define BLKGETSIZE64_32		_IOR(0x12, 114, int)
 
-struct compat_floppy_drive_params {
-	char		cmos;
-	compat_ulong_t	max_dtr;
-	compat_ulong_t	hlt;
-	compat_ulong_t	hut;
-	compat_ulong_t	srt;
-	compat_ulong_t	spinup;
-	compat_ulong_t	spindown;
-	unsigned char	spindown_offset;
-	unsigned char	select_delay;
-	unsigned char	rps;
-	unsigned char	tracks;
-	compat_ulong_t	timeout;
-	unsigned char	interleave_sect;
-	struct floppy_max_errors max_errors;
-	char		flags;
-	char		read_track;
-	short		autodetect[8];
-	compat_int_t	checkfreq;
-	compat_int_t	native_format;
-};
-
-struct compat_floppy_drive_struct {
-	signed char	flags;
-	compat_ulong_t	spinup_date;
-	compat_ulong_t	select_date;
-	compat_ulong_t	first_read_date;
-	short		probed_format;
-	short		track;
-	short		maxblock;
-	short		maxtrack;
-	compat_int_t	generation;
-	compat_int_t	keep_data;
-	compat_int_t	fd_ref;
-	compat_int_t	fd_device;
-	compat_int_t	last_checked;
-	compat_caddr_t dmabuf;
-	compat_int_t	bufblocks;
-};
-
-struct compat_floppy_fdc_state {
-	compat_int_t	spec1;
-	compat_int_t	spec2;
-	compat_int_t	dtr;
-	unsigned char	version;
-	unsigned char	dor;
-	compat_ulong_t	address;
-	unsigned int	rawcmd:2;
-	unsigned int	reset:1;
-	unsigned int	need_configure:1;
-	unsigned int	perp_mode:2;
-	unsigned int	has_fifo:1;
-	unsigned int	driver_version;
-	unsigned char	track[4];
-};
-
-struct compat_floppy_write_errors {
-	unsigned int	write_errors;
-	compat_ulong_t	first_error_sector;
-	compat_int_t	first_error_generation;
-	compat_ulong_t	last_error_sector;
-	compat_int_t	last_error_generation;
-	compat_uint_t	badness;
-};
-
-#define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct)
-#define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct)
-#define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params)
-#define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params)
-#define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct)
-#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct)
-#define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state)
-#define FDWERRORGET32  _IOR(2, 0x17, struct compat_floppy_write_errors)
-
-static struct {
-	unsigned int	cmd32;
-	unsigned int	cmd;
-} fd_ioctl_trans_table[] = {
-	{ FDSETPRM32, FDSETPRM },
-	{ FDDEFPRM32, FDDEFPRM },
-	{ FDGETPRM32, FDGETPRM },
-	{ FDSETDRVPRM32, FDSETDRVPRM },
-	{ FDGETDRVPRM32, FDGETDRVPRM },
-	{ FDGETDRVSTAT32, FDGETDRVSTAT },
-	{ FDPOLLDRVSTAT32, FDPOLLDRVSTAT },
-	{ FDGETFDCSTAT32, FDGETFDCSTAT },
-	{ FDWERRORGET32, FDWERRORGET }
-};
-
-#define NR_FD_IOCTL_TRANS ARRAY_SIZE(fd_ioctl_trans_table)
-
-static int compat_fd_ioctl(struct block_device *bdev, fmode_t mode,
-		unsigned int cmd, unsigned long arg)
-{
-	mm_segment_t old_fs = get_fs();
-	void *karg = NULL;
-	unsigned int kcmd = 0;
-	int i, err;
-
-	for (i = 0; i < NR_FD_IOCTL_TRANS; i++)
-		if (cmd == fd_ioctl_trans_table[i].cmd32) {
-			kcmd = fd_ioctl_trans_table[i].cmd;
-			break;
-		}
-	if (!kcmd)
-		return -EINVAL;
-
-	switch (cmd) {
-	case FDSETPRM32:
-	case FDDEFPRM32:
-	case FDGETPRM32:
-	{
-		compat_uptr_t name;
-		struct compat_floppy_struct __user *uf;
-		struct floppy_struct *f;
-
-		uf = compat_ptr(arg);
-		f = karg = kmalloc(sizeof(struct floppy_struct), GFP_KERNEL);
-		if (!karg)
-			return -ENOMEM;
-		if (cmd == FDGETPRM32)
-			break;
-		err = __get_user(f->size, &uf->size);
-		err |= __get_user(f->sect, &uf->sect);
-		err |= __get_user(f->head, &uf->head);
-		err |= __get_user(f->track, &uf->track);
-		err |= __get_user(f->stretch, &uf->stretch);
-		err |= __get_user(f->gap, &uf->gap);
-		err |= __get_user(f->rate, &uf->rate);
-		err |= __get_user(f->spec1, &uf->spec1);
-		err |= __get_user(f->fmt_gap, &uf->fmt_gap);
-		err |= __get_user(name, &uf->name);
-		f->name = compat_ptr(name);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
-		break;
-	}
-	case FDSETDRVPRM32:
-	case FDGETDRVPRM32:
-	{
-		struct compat_floppy_drive_params __user *uf;
-		struct floppy_drive_params *f;
-
-		uf = compat_ptr(arg);
-		f = karg = kmalloc(sizeof(struct floppy_drive_params), GFP_KERNEL);
-		if (!karg)
-			return -ENOMEM;
-		if (cmd == FDGETDRVPRM32)
-			break;
-		err = __get_user(f->cmos, &uf->cmos);
-		err |= __get_user(f->max_dtr, &uf->max_dtr);
-		err |= __get_user(f->hlt, &uf->hlt);
-		err |= __get_user(f->hut, &uf->hut);
-		err |= __get_user(f->srt, &uf->srt);
-		err |= __get_user(f->spinup, &uf->spinup);
-		err |= __get_user(f->spindown, &uf->spindown);
-		err |= __get_user(f->spindown_offset, &uf->spindown_offset);
-		err |= __get_user(f->select_delay, &uf->select_delay);
-		err |= __get_user(f->rps, &uf->rps);
-		err |= __get_user(f->tracks, &uf->tracks);
-		err |= __get_user(f->timeout, &uf->timeout);
-		err |= __get_user(f->interleave_sect, &uf->interleave_sect);
-		err |= __copy_from_user(&f->max_errors, &uf->max_errors, sizeof(f->max_errors));
-		err |= __get_user(f->flags, &uf->flags);
-		err |= __get_user(f->read_track, &uf->read_track);
-		err |= __copy_from_user(f->autodetect, uf->autodetect, sizeof(f->autodetect));
-		err |= __get_user(f->checkfreq, &uf->checkfreq);
-		err |= __get_user(f->native_format, &uf->native_format);
-		if (err) {
-			err = -EFAULT;
-			goto out;
-		}
-		break;
-	}
-	case FDGETDRVSTAT32:
-	case FDPOLLDRVSTAT32:
-		karg = kmalloc(sizeof(struct floppy_drive_struct), GFP_KERNEL);
-		if (!karg)
-			return -ENOMEM;
-		break;
-	case FDGETFDCSTAT32:
-		karg = kmalloc(sizeof(struct floppy_fdc_state), GFP_KERNEL);
-		if (!karg)
-			return -ENOMEM;
-		break;
-	case FDWERRORGET32:
-		karg = kmalloc(sizeof(struct floppy_write_errors), GFP_KERNEL);
-		if (!karg)
-			return -ENOMEM;
-		break;
-	default:
-		return -EINVAL;
-	}
-	set_fs(KERNEL_DS);
-	err = __blkdev_driver_ioctl(bdev, mode, kcmd, (unsigned long)karg);
-	set_fs(old_fs);
-	if (err)
-		goto out;
-	switch (cmd) {
-	case FDGETPRM32:
-	{
-		struct floppy_struct *f = karg;
-		struct compat_floppy_struct __user *uf = compat_ptr(arg);
-
-		err = __put_user(f->size, &uf->size);
-		err |= __put_user(f->sect, &uf->sect);
-		err |= __put_user(f->head, &uf->head);
-		err |= __put_user(f->track, &uf->track);
-		err |= __put_user(f->stretch, &uf->stretch);
-		err |= __put_user(f->gap, &uf->gap);
-		err |= __put_user(f->rate, &uf->rate);
-		err |= __put_user(f->spec1, &uf->spec1);
-		err |= __put_user(f->fmt_gap, &uf->fmt_gap);
-		err |= __put_user((u64)f->name, (compat_caddr_t __user *)&uf->name);
-		break;
-	}
-	case FDGETDRVPRM32:
-	{
-		struct compat_floppy_drive_params __user *uf;
-		struct floppy_drive_params *f = karg;
-
-		uf = compat_ptr(arg);
-		err = __put_user(f->cmos, &uf->cmos);
-		err |= __put_user(f->max_dtr, &uf->max_dtr);
-		err |= __put_user(f->hlt, &uf->hlt);
-		err |= __put_user(f->hut, &uf->hut);
-		err |= __put_user(f->srt, &uf->srt);
-		err |= __put_user(f->spinup, &uf->spinup);
-		err |= __put_user(f->spindown, &uf->spindown);
-		err |= __put_user(f->spindown_offset, &uf->spindown_offset);
-		err |= __put_user(f->select_delay, &uf->select_delay);
-		err |= __put_user(f->rps, &uf->rps);
-		err |= __put_user(f->tracks, &uf->tracks);
-		err |= __put_user(f->timeout, &uf->timeout);
-		err |= __put_user(f->interleave_sect, &uf->interleave_sect);
-		err |= __copy_to_user(&uf->max_errors, &f->max_errors, sizeof(f->max_errors));
-		err |= __put_user(f->flags, &uf->flags);
-		err |= __put_user(f->read_track, &uf->read_track);
-		err |= __copy_to_user(uf->autodetect, f->autodetect, sizeof(f->autodetect));
-		err |= __put_user(f->checkfreq, &uf->checkfreq);
-		err |= __put_user(f->native_format, &uf->native_format);
-		break;
-	}
-	case FDGETDRVSTAT32:
-	case FDPOLLDRVSTAT32:
-	{
-		struct compat_floppy_drive_struct __user *uf;
-		struct floppy_drive_struct *f = karg;
-
-		uf = compat_ptr(arg);
-		err = __put_user(f->flags, &uf->flags);
-		err |= __put_user(f->spinup_date, &uf->spinup_date);
-		err |= __put_user(f->select_date, &uf->select_date);
-		err |= __put_user(f->first_read_date, &uf->first_read_date);
-		err |= __put_user(f->probed_format, &uf->probed_format);
-		err |= __put_user(f->track, &uf->track);
-		err |= __put_user(f->maxblock, &uf->maxblock);
-		err |= __put_user(f->maxtrack, &uf->maxtrack);
-		err |= __put_user(f->generation, &uf->generation);
-		err |= __put_user(f->keep_data, &uf->keep_data);
-		err |= __put_user(f->fd_ref, &uf->fd_ref);
-		err |= __put_user(f->fd_device, &uf->fd_device);
-		err |= __put_user(f->last_checked, &uf->last_checked);
-		err |= __put_user((u64)f->dmabuf, &uf->dmabuf);
-		err |= __put_user((u64)f->bufblocks, &uf->bufblocks);
-		break;
-	}
-	case FDGETFDCSTAT32:
-	{
-		struct compat_floppy_fdc_state __user *uf;
-		struct floppy_fdc_state *f = karg;
-
-		uf = compat_ptr(arg);
-		err = __put_user(f->spec1, &uf->spec1);
-		err |= __put_user(f->spec2, &uf->spec2);
-		err |= __put_user(f->dtr, &uf->dtr);
-		err |= __put_user(f->version, &uf->version);
-		err |= __put_user(f->dor, &uf->dor);
-		err |= __put_user(f->address, &uf->address);
-		err |= __copy_to_user((char __user *)&uf->address + sizeof(uf->address),
-				   (char *)&f->address + sizeof(f->address), sizeof(int));
-		err |= __put_user(f->driver_version, &uf->driver_version);
-		err |= __copy_to_user(uf->track, f->track, sizeof(f->track));
-		break;
-	}
-	case FDWERRORGET32:
-	{
-		struct compat_floppy_write_errors __user *uf;
-		struct floppy_write_errors *f = karg;
-
-		uf = compat_ptr(arg);
-		err = __put_user(f->write_errors, &uf->write_errors);
-		err |= __put_user(f->first_error_sector, &uf->first_error_sector);
-		err |= __put_user(f->first_error_generation, &uf->first_error_generation);
-		err |= __put_user(f->last_error_sector, &uf->last_error_sector);
-		err |= __put_user(f->last_error_generation, &uf->last_error_generation);
-		err |= __put_user(f->badness, &uf->badness);
-		break;
-	}
-	default:
-		break;
-	}
-	if (err)
-		err = -EFAULT;
-
-out:
-	kfree(karg);
-	return err;
-}
-
 static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
 			unsigned cmd, unsigned long arg)
 {
@@ -537,16 +221,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
 	case HDIO_GET_ADDRESS:
 	case HDIO_GET_BUSSTATE:
 		return compat_hdio_ioctl(bdev, mode, cmd, arg);
-	case FDSETPRM32:
-	case FDDEFPRM32:
-	case FDGETPRM32:
-	case FDSETDRVPRM32:
-	case FDGETDRVPRM32:
-	case FDGETDRVSTAT32:
-	case FDPOLLDRVSTAT32:
-	case FDGETFDCSTAT32:
-	case FDWERRORGET32:
-		return compat_fd_ioctl(bdev, mode, cmd, arg);
 	case CDROMREADAUDIO:
 		return compat_cdrom_read_audio(bdev, mode, cmd, arg);
 	case CDROM_SEND_PACKET:
@@ -566,23 +240,6 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
 	case HDIO_DRIVE_CMD:
 	/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
 	case 0x330:
-	/* 0x02 -- Floppy ioctls */
-	case FDMSGON:
-	case FDMSGOFF:
-	case FDSETEMSGTRESH:
-	case FDFLUSH:
-	case FDWERRORCLR:
-	case FDSETMAXERRS:
-	case FDGETMAXERRS:
-	case FDGETDRVTYP:
-	case FDEJECT:
-	case FDCLRPRM:
-	case FDFMTBEG:
-	case FDFMTEND:
-	case FDRESET:
-	case FDTWADDLE:
-	case FDFMTTRK:
-	case FDRAWCMD:
 	/* CDROM stuff */
 	case CDROMPAUSE:
 	case CDROMRESUME:
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index ce823647a9c449d8a63c80db17e5e8a9529e67e7..9c00f29e40c10e824052b43372d2ff80d1ed9339 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -192,6 +192,7 @@ static int print_unex = 1;
 #include <linux/io.h>
 #include <linux/uaccess.h>
 #include <linux/async.h>
+#include <linux/compat.h>
 
 /*
  * PS/2 floppies have much slower step rates than regular floppies.
@@ -3568,6 +3569,330 @@ static int fd_ioctl(struct block_device *bdev, fmode_t mode,
 	return ret;
 }
 
+#ifdef CONFIG_COMPAT
+
+struct compat_floppy_drive_params {
+	char		cmos;
+	compat_ulong_t	max_dtr;
+	compat_ulong_t	hlt;
+	compat_ulong_t	hut;
+	compat_ulong_t	srt;
+	compat_ulong_t	spinup;
+	compat_ulong_t	spindown;
+	unsigned char	spindown_offset;
+	unsigned char	select_delay;
+	unsigned char	rps;
+	unsigned char	tracks;
+	compat_ulong_t	timeout;
+	unsigned char	interleave_sect;
+	struct floppy_max_errors max_errors;
+	char		flags;
+	char		read_track;
+	short		autodetect[8];
+	compat_int_t	checkfreq;
+	compat_int_t	native_format;
+};
+
+struct compat_floppy_drive_struct {
+	signed char	flags;
+	compat_ulong_t	spinup_date;
+	compat_ulong_t	select_date;
+	compat_ulong_t	first_read_date;
+	short		probed_format;
+	short		track;
+	short		maxblock;
+	short		maxtrack;
+	compat_int_t	generation;
+	compat_int_t	keep_data;
+	compat_int_t	fd_ref;
+	compat_int_t	fd_device;
+	compat_int_t	last_checked;
+	compat_caddr_t dmabuf;
+	compat_int_t	bufblocks;
+};
+
+struct compat_floppy_fdc_state {
+	compat_int_t	spec1;
+	compat_int_t	spec2;
+	compat_int_t	dtr;
+	unsigned char	version;
+	unsigned char	dor;
+	compat_ulong_t	address;
+	unsigned int	rawcmd:2;
+	unsigned int	reset:1;
+	unsigned int	need_configure:1;
+	unsigned int	perp_mode:2;
+	unsigned int	has_fifo:1;
+	unsigned int	driver_version;
+	unsigned char	track[4];
+};
+
+struct compat_floppy_write_errors {
+	unsigned int	write_errors;
+	compat_ulong_t	first_error_sector;
+	compat_int_t	first_error_generation;
+	compat_ulong_t	last_error_sector;
+	compat_int_t	last_error_generation;
+	compat_uint_t	badness;
+};
+
+#define FDSETPRM32 _IOW(2, 0x42, struct compat_floppy_struct)
+#define FDDEFPRM32 _IOW(2, 0x43, struct compat_floppy_struct)
+#define FDSETDRVPRM32 _IOW(2, 0x90, struct compat_floppy_drive_params)
+#define FDGETDRVPRM32 _IOR(2, 0x11, struct compat_floppy_drive_params)
+#define FDGETDRVSTAT32 _IOR(2, 0x12, struct compat_floppy_drive_struct)
+#define FDPOLLDRVSTAT32 _IOR(2, 0x13, struct compat_floppy_drive_struct)
+#define FDGETFDCSTAT32 _IOR(2, 0x15, struct compat_floppy_fdc_state)
+#define FDWERRORGET32  _IOR(2, 0x17, struct compat_floppy_write_errors)
+
+static int compat_set_geometry(struct block_device *bdev, fmode_t mode, unsigned int cmd,
+		    struct compat_floppy_struct __user *arg)
+{
+	struct floppy_struct v;
+	int drive, type;
+	int err;
+
+	BUILD_BUG_ON(offsetof(struct floppy_struct, name) !=
+		     offsetof(struct compat_floppy_struct, name));
+
+	if (!(mode & (FMODE_WRITE | FMODE_WRITE_IOCTL)))
+		return -EPERM;
+
+	memset(&v, 0, sizeof(struct floppy_struct));
+	if (copy_from_user(&v, arg, offsetof(struct floppy_struct, name)))
+		return -EFAULT;
+
+	mutex_lock(&floppy_mutex);
+	drive = (long)bdev->bd_disk->private_data;
+	type = ITYPE(UDRS->fd_device);
+	err = set_geometry(cmd == FDSETPRM32 ? FDSETPRM : FDDEFPRM,
+			&v, drive, type, bdev);
+	mutex_unlock(&floppy_mutex);
+	return err;
+}
+
+static int compat_get_prm(int drive,
+			  struct compat_floppy_struct __user *arg)
+{
+	struct compat_floppy_struct v;
+	struct floppy_struct *p;
+	int err;
+
+	memset(&v, 0, sizeof(v));
+	mutex_lock(&floppy_mutex);
+	err = get_floppy_geometry(drive, ITYPE(UDRS->fd_device), &p);
+	if (err) {
+		mutex_unlock(&floppy_mutex);
+		return err;
+	}
+	memcpy(&v, p, offsetof(struct floppy_struct, name));
+	mutex_unlock(&floppy_mutex);
+	if (copy_to_user(arg, &v, sizeof(struct compat_floppy_struct)))
+		return -EFAULT;
+	return 0;
+}
+
+static int compat_setdrvprm(int drive,
+			    struct compat_floppy_drive_params __user *arg)
+{
+	struct compat_floppy_drive_params v;
+
+	if (!capable(CAP_SYS_ADMIN))
+		return -EPERM;
+	if (copy_from_user(&v, arg, sizeof(struct compat_floppy_drive_params)))
+		return -EFAULT;
+	mutex_lock(&floppy_mutex);
+	UDP->cmos = v.cmos;
+	UDP->max_dtr = v.max_dtr;
+	UDP->hlt = v.hlt;
+	UDP->hut = v.hut;
+	UDP->srt = v.srt;
+	UDP->spinup = v.spinup;
+	UDP->spindown = v.spindown;
+	UDP->spindown_offset = v.spindown_offset;
+	UDP->select_delay = v.select_delay;
+	UDP->rps = v.rps;
+	UDP->tracks = v.tracks;
+	UDP->timeout = v.timeout;
+	UDP->interleave_sect = v.interleave_sect;
+	UDP->max_errors = v.max_errors;
+	UDP->flags = v.flags;
+	UDP->read_track = v.read_track;
+	memcpy(UDP->autodetect, v.autodetect, sizeof(v.autodetect));
+	UDP->checkfreq = v.checkfreq;
+	UDP->native_format = v.native_format;
+	mutex_unlock(&floppy_mutex);
+	return 0;
+}
+
+static int compat_getdrvprm(int drive,
+			    struct compat_floppy_drive_params __user *arg)
+{
+	struct compat_floppy_drive_params v;
+
+	memset(&v, 0, sizeof(struct compat_floppy_drive_params));
+	mutex_lock(&floppy_mutex);
+	v.cmos = UDP->cmos;
+	v.max_dtr = UDP->max_dtr;
+	v.hlt = UDP->hlt;
+	v.hut = UDP->hut;
+	v.srt = UDP->srt;
+	v.spinup = UDP->spinup;
+	v.spindown = UDP->spindown;
+	v.spindown_offset = UDP->spindown_offset;
+	v.select_delay = UDP->select_delay;
+	v.rps = UDP->rps;
+	v.tracks = UDP->tracks;
+	v.timeout = UDP->timeout;
+	v.interleave_sect = UDP->interleave_sect;
+	v.max_errors = UDP->max_errors;
+	v.flags = UDP->flags;
+	v.read_track = UDP->read_track;
+	memcpy(v.autodetect, UDP->autodetect, sizeof(v.autodetect));
+	v.checkfreq = UDP->checkfreq;
+	v.native_format = UDP->native_format;
+	mutex_unlock(&floppy_mutex);
+
+	if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_params)))
+		return -EFAULT;
+	return 0;
+}
+
+static int compat_getdrvstat(int drive, bool poll,
+			    struct compat_floppy_drive_struct __user *arg)
+{
+	struct compat_floppy_drive_struct v;
+
+	memset(&v, 0, sizeof(struct compat_floppy_drive_struct));
+	mutex_lock(&floppy_mutex);
+
+	if (poll) {
+		if (lock_fdc(drive))
+			goto Eintr;
+		if (poll_drive(true, FD_RAW_NEED_DISK) == -EINTR)
+			goto Eintr;
+		process_fd_request();
+	}
+	v.spinup_date = UDRS->spinup_date;
+	v.select_date = UDRS->select_date;
+	v.first_read_date = UDRS->first_read_date;
+	v.probed_format = UDRS->probed_format;
+	v.track = UDRS->track;
+	v.maxblock = UDRS->maxblock;
+	v.maxtrack = UDRS->maxtrack;
+	v.generation = UDRS->generation;
+	v.keep_data = UDRS->keep_data;
+	v.fd_ref = UDRS->fd_ref;
+	v.fd_device = UDRS->fd_device;
+	v.last_checked = UDRS->last_checked;
+	v.dmabuf = (uintptr_t)UDRS->dmabuf;
+	v.bufblocks = UDRS->bufblocks;
+	mutex_unlock(&floppy_mutex);
+
+	if (copy_from_user(arg, &v, sizeof(struct compat_floppy_drive_struct)))
+		return -EFAULT;
+	return 0;
+Eintr:
+	mutex_unlock(&floppy_mutex);
+	return -EINTR;
+}
+
+static int compat_getfdcstat(int drive,
+			    struct compat_floppy_fdc_state __user *arg)
+{
+	struct compat_floppy_fdc_state v32;
+	struct floppy_fdc_state v;
+
+	mutex_lock(&floppy_mutex);
+	v = *UFDCS;
+	mutex_unlock(&floppy_mutex);
+
+	memset(&v32, 0, sizeof(struct compat_floppy_fdc_state));
+	v32.spec1 = v.spec1;
+	v32.spec2 = v.spec2;
+	v32.dtr = v.dtr;
+	v32.version = v.version;
+	v32.dor = v.dor;
+	v32.address = v.address;
+	v32.rawcmd = v.rawcmd;
+	v32.reset = v.reset;
+	v32.need_configure = v.need_configure;
+	v32.perp_mode = v.perp_mode;
+	v32.has_fifo = v.has_fifo;
+	v32.driver_version = v.driver_version;
+	memcpy(v32.track, v.track, 4);
+	if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_fdc_state)))
+		return -EFAULT;
+	return 0;
+}
+
+static int compat_werrorget(int drive,
+			    struct compat_floppy_write_errors __user *arg)
+{
+	struct compat_floppy_write_errors v32;
+	struct floppy_write_errors v;
+
+	memset(&v32, 0, sizeof(struct compat_floppy_write_errors));
+	mutex_lock(&floppy_mutex);
+	v = *UDRWE;
+	mutex_unlock(&floppy_mutex);
+	v32.write_errors = v.write_errors;
+	v32.first_error_sector = v.first_error_sector;
+	v32.first_error_generation = v.first_error_generation;
+	v32.last_error_sector = v.last_error_sector;
+	v32.last_error_generation = v.last_error_generation;
+	v32.badness = v.badness;
+	if (copy_to_user(arg, &v32, sizeof(struct compat_floppy_write_errors)))
+		return -EFAULT;
+	return 0;
+}
+
+static int fd_compat_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
+		    unsigned long param)
+{
+	int drive = (long)bdev->bd_disk->private_data;
+	switch (cmd) {
+	case FDMSGON:
+	case FDMSGOFF:
+	case FDSETEMSGTRESH:
+	case FDFLUSH:
+	case FDWERRORCLR:
+	case FDEJECT:
+	case FDCLRPRM:
+	case FDFMTBEG:
+	case FDRESET:
+	case FDTWADDLE:
+		return fd_ioctl(bdev, mode, cmd, param);
+	case FDSETMAXERRS:
+	case FDGETMAXERRS:
+	case FDGETDRVTYP:
+	case FDFMTEND:
+	case FDFMTTRK:
+	case FDRAWCMD:
+		return fd_ioctl(bdev, mode, cmd,
+				(unsigned long)compat_ptr(param));
+	case FDSETPRM32:
+	case FDDEFPRM32:
+		return compat_set_geometry(bdev, mode, cmd, compat_ptr(param));
+	case FDGETPRM32:
+		return compat_get_prm(drive, compat_ptr(param));
+	case FDSETDRVPRM32:
+		return compat_setdrvprm(drive, compat_ptr(param));
+	case FDGETDRVPRM32:
+		return compat_getdrvprm(drive, compat_ptr(param));
+	case FDPOLLDRVSTAT32:
+		return compat_getdrvstat(drive, true, compat_ptr(param));
+	case FDGETDRVSTAT32:
+		return compat_getdrvstat(drive, false, compat_ptr(param));
+	case FDGETFDCSTAT32:
+		return compat_getfdcstat(drive, compat_ptr(param));
+	case FDWERRORGET32:
+		return compat_werrorget(drive, compat_ptr(param));
+	}
+	return -EINVAL;
+}
+#endif
+
 static void __init config_types(void)
 {
 	bool has_drive = false;
@@ -3885,6 +4210,9 @@ static const struct block_device_operations floppy_fops = {
 	.getgeo			= fd_getgeo,
 	.check_events		= floppy_check_events,
 	.revalidate_disk	= floppy_revalidate,
+#ifdef CONFIG_COMPAT
+	.compat_ioctl		= fd_compat_ioctl,
+#endif
 };
 
 /*
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index f45119c5337d7b3bdf5eb3b5663f5873dd8ac6c1..2ffca42326863dd95bc851c657de214aad66223a 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -231,6 +231,102 @@ static int handle_send_req(ipmi_user_t     user,
 	return rv;
 }
 
+static int handle_recv(struct ipmi_file_private *priv,
+			bool trunc, struct ipmi_recv *rsp,
+			int (*copyout)(struct ipmi_recv *, void __user *),
+			void __user *to)
+{
+	int              addr_len;
+	struct list_head *entry;
+	struct ipmi_recv_msg  *msg;
+	unsigned long    flags;
+	int rv = 0;
+
+	/* We claim a mutex because we don't want two
+	   users getting something from the queue at a time.
+	   Since we have to release the spinlock before we can
+	   copy the data to the user, it's possible another
+	   user will grab something from the queue, too.  Then
+	   the messages might get out of order if something
+	   fails and the message gets put back onto the
+	   queue.  This mutex prevents that problem. */
+	mutex_lock(&priv->recv_mutex);
+
+	/* Grab the message off the list. */
+	spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+	if (list_empty(&(priv->recv_msgs))) {
+		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+		rv = -EAGAIN;
+		goto recv_err;
+	}
+	entry = priv->recv_msgs.next;
+	msg = list_entry(entry, struct ipmi_recv_msg, link);
+	list_del(entry);
+	spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+
+	addr_len = ipmi_addr_length(msg->addr.addr_type);
+	if (rsp->addr_len < addr_len)
+	{
+		rv = -EINVAL;
+		goto recv_putback_on_err;
+	}
+
+	if (copy_to_user(rsp->addr, &(msg->addr), addr_len)) {
+		rv = -EFAULT;
+		goto recv_putback_on_err;
+	}
+	rsp->addr_len = addr_len;
+
+	rsp->recv_type = msg->recv_type;
+	rsp->msgid = msg->msgid;
+	rsp->msg.netfn = msg->msg.netfn;
+	rsp->msg.cmd = msg->msg.cmd;
+
+	if (msg->msg.data_len > 0) {
+		if (rsp->msg.data_len < msg->msg.data_len) {
+			rv = -EMSGSIZE;
+			if (trunc)
+				msg->msg.data_len = rsp->msg.data_len;
+			else
+				goto recv_putback_on_err;
+		}
+
+		if (copy_to_user(rsp->msg.data,
+				 msg->msg.data,
+				 msg->msg.data_len))
+		{
+			rv = -EFAULT;
+			goto recv_putback_on_err;
+		}
+		rsp->msg.data_len = msg->msg.data_len;
+	} else {
+		rsp->msg.data_len = 0;
+	}
+
+	rv = copyout(rsp, to);
+	if (rv)
+		goto recv_putback_on_err;
+
+	mutex_unlock(&priv->recv_mutex);
+	ipmi_free_recv_msg(msg);
+	return 0;
+
+recv_putback_on_err:
+	/* If we got an error, put the message back onto
+	   the head of the queue. */
+	spin_lock_irqsave(&(priv->recv_msg_lock), flags);
+	list_add(entry, &(priv->recv_msgs));
+	spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
+recv_err:
+	mutex_unlock(&priv->recv_mutex);
+	return rv;
+}
+
+static int copyout_recv(struct ipmi_recv *rsp, void __user *to)
+{
+	return copy_to_user(to, rsp, sizeof(struct ipmi_recv)) ? -EFAULT : 0;
+}
+
 static int ipmi_ioctl(struct file   *file,
 		      unsigned int  cmd,
 		      unsigned long data)
@@ -277,100 +373,12 @@ static int ipmi_ioctl(struct file   *file,
 	case IPMICTL_RECEIVE_MSG_TRUNC:
 	{
 		struct ipmi_recv      rsp;
-		int              addr_len;
-		struct list_head *entry;
-		struct ipmi_recv_msg  *msg;
-		unsigned long    flags;
-		
-
-		rv = 0;
-		if (copy_from_user(&rsp, arg, sizeof(rsp))) {
-			rv = -EFAULT;
-			break;
-		}
-
-		/* We claim a mutex because we don't want two
-                   users getting something from the queue at a time.
-                   Since we have to release the spinlock before we can
-                   copy the data to the user, it's possible another
-                   user will grab something from the queue, too.  Then
-                   the messages might get out of order if something
-                   fails and the message gets put back onto the
-                   queue.  This mutex prevents that problem. */
-		mutex_lock(&priv->recv_mutex);
-
-		/* Grab the message off the list. */
-		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
-		if (list_empty(&(priv->recv_msgs))) {
-			spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
-			rv = -EAGAIN;
-			goto recv_err;
-		}
-		entry = priv->recv_msgs.next;
-		msg = list_entry(entry, struct ipmi_recv_msg, link);
-		list_del(entry);
-		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
-
-		addr_len = ipmi_addr_length(msg->addr.addr_type);
-		if (rsp.addr_len < addr_len)
-		{
-			rv = -EINVAL;
-			goto recv_putback_on_err;
-		}
 
-		if (copy_to_user(rsp.addr, &(msg->addr), addr_len)) {
+		if (copy_from_user(&rsp, arg, sizeof(rsp)))
 			rv = -EFAULT;
-			goto recv_putback_on_err;
-		}
-		rsp.addr_len = addr_len;
-
-		rsp.recv_type = msg->recv_type;
-		rsp.msgid = msg->msgid;
-		rsp.msg.netfn = msg->msg.netfn;
-		rsp.msg.cmd = msg->msg.cmd;
-
-		if (msg->msg.data_len > 0) {
-			if (rsp.msg.data_len < msg->msg.data_len) {
-				rv = -EMSGSIZE;
-				if (cmd == IPMICTL_RECEIVE_MSG_TRUNC) {
-					msg->msg.data_len = rsp.msg.data_len;
-				} else {
-					goto recv_putback_on_err;
-				}
-			}
-
-			if (copy_to_user(rsp.msg.data,
-					 msg->msg.data,
-					 msg->msg.data_len))
-			{
-				rv = -EFAULT;
-				goto recv_putback_on_err;
-			}
-			rsp.msg.data_len = msg->msg.data_len;
-		} else {
-			rsp.msg.data_len = 0;
-		}
-
-		if (copy_to_user(arg, &rsp, sizeof(rsp))) {
-			rv = -EFAULT;
-			goto recv_putback_on_err;
-		}
-
-		mutex_unlock(&priv->recv_mutex);
-		ipmi_free_recv_msg(msg);
-		break;
-
-	recv_putback_on_err:
-		/* If we got an error, put the message back onto
-		   the head of the queue. */
-		spin_lock_irqsave(&(priv->recv_msg_lock), flags);
-		list_add(entry, &(priv->recv_msgs));
-		spin_unlock_irqrestore(&(priv->recv_msg_lock), flags);
-		mutex_unlock(&priv->recv_mutex);
-		break;
-
-	recv_err:
-		mutex_unlock(&priv->recv_mutex);
+		else
+			rv = handle_recv(priv, cmd == IPMICTL_RECEIVE_MSG_TRUNC,
+					 &rsp, copyout_recv, arg);
 		break;
 	}
 
@@ -696,85 +704,56 @@ struct compat_ipmi_req_settime {
 /*
  * Define some helper functions for copying IPMI data
  */
-static long get_compat_ipmi_msg(struct ipmi_msg *p64,
-				struct compat_ipmi_msg __user *p32)
-{
-	compat_uptr_t tmp;
-
-	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
-			__get_user(p64->netfn, &p32->netfn) ||
-			__get_user(p64->cmd, &p32->cmd) ||
-			__get_user(p64->data_len, &p32->data_len) ||
-			__get_user(tmp, &p32->data))
-		return -EFAULT;
-	p64->data = compat_ptr(tmp);
-	return 0;
-}
-
-static long put_compat_ipmi_msg(struct ipmi_msg *p64,
-				struct compat_ipmi_msg __user *p32)
+static void get_compat_ipmi_msg(struct ipmi_msg *p64,
+				struct compat_ipmi_msg *p32)
 {
-	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
-			__put_user(p64->netfn, &p32->netfn) ||
-			__put_user(p64->cmd, &p32->cmd) ||
-			__put_user(p64->data_len, &p32->data_len))
-		return -EFAULT;
-	return 0;
+	p64->netfn = p32->netfn;
+	p64->cmd = p32->cmd;
+	p64->data_len = p32->data_len;
+	p64->data = compat_ptr(p32->data);
 }
 
-static long get_compat_ipmi_req(struct ipmi_req *p64,
-				struct compat_ipmi_req __user *p32)
+static void get_compat_ipmi_req(struct ipmi_req *p64,
+				struct compat_ipmi_req *p32)
 {
-
-	compat_uptr_t	tmp;
-
-	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
-			__get_user(tmp, &p32->addr) ||
-			__get_user(p64->addr_len, &p32->addr_len) ||
-			__get_user(p64->msgid, &p32->msgid) ||
-			get_compat_ipmi_msg(&p64->msg, &p32->msg))
-		return -EFAULT;
-	p64->addr = compat_ptr(tmp);
-	return 0;
+	p64->addr = compat_ptr(p32->addr);
+	p64->addr_len = p32->addr_len;
+	p64->msgid = p32->msgid;
+	get_compat_ipmi_msg(&p64->msg, &p32->msg);
 }
 
-static long get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
-		struct compat_ipmi_req_settime __user *p32)
+static void get_compat_ipmi_req_settime(struct ipmi_req_settime *p64,
+		struct compat_ipmi_req_settime *p32)
 {
-	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
-			get_compat_ipmi_req(&p64->req, &p32->req) ||
-			__get_user(p64->retries, &p32->retries) ||
-			__get_user(p64->retry_time_ms, &p32->retry_time_ms))
-		return -EFAULT;
-	return 0;
+	get_compat_ipmi_req(&p64->req, &p32->req);
+	p64->retries = p32->retries;
+	p64->retry_time_ms = p32->retry_time_ms;
 }
 
-static long get_compat_ipmi_recv(struct ipmi_recv *p64,
-				 struct compat_ipmi_recv __user *p32)
+static void get_compat_ipmi_recv(struct ipmi_recv *p64,
+				 struct compat_ipmi_recv *p32)
 {
-	compat_uptr_t tmp;
-
-	if (!access_ok(VERIFY_READ, p32, sizeof(*p32)) ||
-			__get_user(p64->recv_type, &p32->recv_type) ||
-			__get_user(tmp, &p32->addr) ||
-			__get_user(p64->addr_len, &p32->addr_len) ||
-			__get_user(p64->msgid, &p32->msgid) ||
-			get_compat_ipmi_msg(&p64->msg, &p32->msg))
-		return -EFAULT;
-	p64->addr = compat_ptr(tmp);
-	return 0;
+	memset(p64, 0, sizeof(struct ipmi_recv));
+	p64->recv_type = p32->recv_type;
+	p64->addr = compat_ptr(p32->addr);
+	p64->addr_len = p32->addr_len;
+	p64->msgid = p32->msgid;
+	get_compat_ipmi_msg(&p64->msg, &p32->msg);
 }
 
-static long put_compat_ipmi_recv(struct ipmi_recv *p64,
-				 struct compat_ipmi_recv __user *p32)
+static int copyout_recv32(struct ipmi_recv *p64, void __user *to)
 {
-	if (!access_ok(VERIFY_WRITE, p32, sizeof(*p32)) ||
-			__put_user(p64->recv_type, &p32->recv_type) ||
-			__put_user(p64->addr_len, &p32->addr_len) ||
-			__put_user(p64->msgid, &p32->msgid) ||
-			put_compat_ipmi_msg(&p64->msg, &p32->msg))
-		return -EFAULT;
-	return 0;
+	struct compat_ipmi_recv v32;
+	memset(&v32, 0, sizeof(struct compat_ipmi_recv));
+	v32.recv_type = p64->recv_type;
+	v32.addr = ptr_to_compat(p64->addr);
+	v32.addr_len = p64->addr_len;
+	v32.msgid = p64->msgid;
+	v32.msg.netfn = p64->msg.netfn;
+	v32.msg.cmd = p64->msg.cmd;
+	v32.msg.data_len = p64->msg.data_len;
+	v32.msg.data = ptr_to_compat(p64->msg.data);
+	return copy_to_user(to, &v32, sizeof(v32)) ? -EFAULT : 0;
 }
 
 /*
@@ -783,17 +762,19 @@ static long put_compat_ipmi_recv(struct ipmi_recv *p64,
 static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
 			      unsigned long arg)
 {
-	int rc;
 	struct ipmi_file_private *priv = filep->private_data;
 
 	switch(cmd) {
 	case COMPAT_IPMICTL_SEND_COMMAND:
 	{
 		struct ipmi_req	rp;
+		struct compat_ipmi_req r32;
 
-		if (get_compat_ipmi_req(&rp, compat_ptr(arg)))
+		if (copy_from_user(&r32, compat_ptr(arg), sizeof(r32)))
 			return -EFAULT;
 
+		get_compat_ipmi_req(&rp, &r32);
+
 		return handle_send_req(priv->user, &rp,
 				priv->default_retries,
 				priv->default_retry_time_ms);
@@ -801,42 +782,30 @@ static long compat_ipmi_ioctl(struct file *filep, unsigned int cmd,
 	case COMPAT_IPMICTL_SEND_COMMAND_SETTIME:
 	{
 		struct ipmi_req_settime	sp;
+		struct compat_ipmi_req_settime sp32;
 
-		if (get_compat_ipmi_req_settime(&sp, compat_ptr(arg)))
+		if (copy_from_user(&sp32, compat_ptr(arg), sizeof(sp32)))
 			return -EFAULT;
 
+		get_compat_ipmi_req_settime(&sp, &sp32);
+
 		return handle_send_req(priv->user, &sp.req,
 				sp.retries, sp.retry_time_ms);
 	}
 	case COMPAT_IPMICTL_RECEIVE_MSG:
 	case COMPAT_IPMICTL_RECEIVE_MSG_TRUNC:
 	{
-		struct ipmi_recv   __user *precv64;
 		struct ipmi_recv   recv64;
+		struct compat_ipmi_recv recv32;
 
-		memset(&recv64, 0, sizeof(recv64));
-		if (get_compat_ipmi_recv(&recv64, compat_ptr(arg)))
+		if (copy_from_user(&recv32, compat_ptr(arg), sizeof(recv32)))
 			return -EFAULT;
 
-		precv64 = compat_alloc_user_space(sizeof(recv64));
-		if (copy_to_user(precv64, &recv64, sizeof(recv64)))
-			return -EFAULT;
-
-		rc = ipmi_ioctl(filep,
-				((cmd == COMPAT_IPMICTL_RECEIVE_MSG)
-				 ? IPMICTL_RECEIVE_MSG
-				 : IPMICTL_RECEIVE_MSG_TRUNC),
-				(unsigned long) precv64);
-		if (rc != 0)
-			return rc;
-
-		if (copy_from_user(&recv64, precv64, sizeof(recv64)))
-			return -EFAULT;
-
-		if (put_compat_ipmi_recv(&recv64, compat_ptr(arg)))
-			return -EFAULT;
+		get_compat_ipmi_recv(&recv64, &recv32);
 
-		return rc;
+		return handle_recv(priv,
+				 cmd == COMPAT_IPMICTL_RECEIVE_MSG_TRUNC,
+				 &recv64, copyout_recv32, compat_ptr(arg));
 	}
 	default:
 		return ipmi_ioctl(filep, cmd, arg);
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 0e7d0e81a7cb5f7bc388353679607aac050539d7..ebe27595c4afbc343285cdcfca0070720c5512be 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1966,27 +1966,21 @@ static int proc_disconnectsignal_compat(struct usb_dev_state *ps, void __user *a
 static int get_urb32(struct usbdevfs_urb *kurb,
 		     struct usbdevfs_urb32 __user *uurb)
 {
-	__u32  uptr;
-	if (!access_ok(VERIFY_READ, uurb, sizeof(*uurb)) ||
-	    __get_user(kurb->type, &uurb->type) ||
-	    __get_user(kurb->endpoint, &uurb->endpoint) ||
-	    __get_user(kurb->status, &uurb->status) ||
-	    __get_user(kurb->flags, &uurb->flags) ||
-	    __get_user(kurb->buffer_length, &uurb->buffer_length) ||
-	    __get_user(kurb->actual_length, &uurb->actual_length) ||
-	    __get_user(kurb->start_frame, &uurb->start_frame) ||
-	    __get_user(kurb->number_of_packets, &uurb->number_of_packets) ||
-	    __get_user(kurb->error_count, &uurb->error_count) ||
-	    __get_user(kurb->signr, &uurb->signr))
+	struct usbdevfs_urb32 urb32;
+	if (copy_from_user(&urb32, uurb, sizeof(*uurb)))
 		return -EFAULT;
-
-	if (__get_user(uptr, &uurb->buffer))
-		return -EFAULT;
-	kurb->buffer = compat_ptr(uptr);
-	if (__get_user(uptr, &uurb->usercontext))
-		return -EFAULT;
-	kurb->usercontext = compat_ptr(uptr);
-
+	kurb->type = urb32.type;
+	kurb->endpoint = urb32.endpoint;
+	kurb->status = urb32.status;
+	kurb->flags = urb32.flags;
+	kurb->buffer = compat_ptr(urb32.buffer);
+	kurb->buffer_length = urb32.buffer_length;
+	kurb->actual_length = urb32.actual_length;
+	kurb->start_frame = urb32.start_frame;
+	kurb->number_of_packets = urb32.number_of_packets;
+	kurb->error_count = urb32.error_count;
+	kurb->signr = urb32.signr;
+	kurb->usercontext = compat_ptr(urb32.usercontext);
 	return 0;
 }
 
@@ -2198,18 +2192,14 @@ static int proc_ioctl_default(struct usb_dev_state *ps, void __user *arg)
 #ifdef CONFIG_COMPAT
 static int proc_ioctl_compat(struct usb_dev_state *ps, compat_uptr_t arg)
 {
-	struct usbdevfs_ioctl32 __user *uioc;
+	struct usbdevfs_ioctl32 ioc32;
 	struct usbdevfs_ioctl ctrl;
-	u32 udata;
 
-	uioc = compat_ptr((long)arg);
-	if (!access_ok(VERIFY_READ, uioc, sizeof(*uioc)) ||
-	    __get_user(ctrl.ifno, &uioc->ifno) ||
-	    __get_user(ctrl.ioctl_code, &uioc->ioctl_code) ||
-	    __get_user(udata, &uioc->data))
+	if (copy_from_user(&ioc32, compat_ptr(arg), sizeof(ioc32)))
 		return -EFAULT;
-	ctrl.data = compat_ptr(udata);
-
+	ctrl.ifno = ioc32.ifno;
+	ctrl.ioctl_code = ioc32.ioctl_code;
+	ctrl.data = compat_ptr(ioc32.data);
 	return proc_ioctl(ps, &ctrl);
 }
 #endif
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index 069fe7960df1cedd17c3f7119d2ab6a6989e46c1..5324358f110fa6e52e5c004a1bf59125b3b36753 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -1331,22 +1331,13 @@ static int do_fscreeninfo_to_user(struct fb_fix_screeninfo *fix,
 static int fb_get_fscreeninfo(struct fb_info *info, unsigned int cmd,
 			      unsigned long arg)
 {
-	mm_segment_t old_fs;
 	struct fb_fix_screeninfo fix;
-	struct fb_fix_screeninfo32 __user *fix32;
-	int err;
-
-	fix32 = compat_ptr(arg);
-
-	old_fs = get_fs();
-	set_fs(KERNEL_DS);
-	err = do_fb_ioctl(info, cmd, (unsigned long) &fix);
-	set_fs(old_fs);
 
-	if (!err)
-		err = do_fscreeninfo_to_user(&fix, fix32);
-
-	return err;
+	if (!lock_fb_info(info))
+		return -ENODEV;
+	fix = info->fix;
+	unlock_fb_info(info);
+	return do_fscreeninfo_to_user(&fix, compat_ptr(arg));
 }
 
 static long fb_compat_ioctl(struct file *file, unsigned int cmd,
diff --git a/fs/select.c b/fs/select.c
index 5b524a977d91e408fb1f4fe7418fb966d53087c0..9d5f15ed87fe7999eaaad22497899e696ad34147 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -1161,59 +1161,25 @@ static
 int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
 			unsigned long *fdset)
 {
-	nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
 	if (ufdset) {
-		unsigned long odd;
-
-		if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
-			return -EFAULT;
-
-		odd = nr & 1UL;
-		nr &= ~1UL;
-		while (nr) {
-			unsigned long h, l;
-			if (__get_user(l, ufdset) || __get_user(h, ufdset+1))
-				return -EFAULT;
-			ufdset += 2;
-			*fdset++ = h << 32 | l;
-			nr -= 2;
-		}
-		if (odd && __get_user(*fdset, ufdset))
-			return -EFAULT;
+		return compat_get_bitmap(fdset, ufdset, nr);
 	} else {
 		/* Tricky, must clear full unsigned long in the
-		 * kernel fdset at the end, this makes sure that
+		 * kernel fdset at the end, ALIGN makes sure that
 		 * actually happens.
 		 */
-		memset(fdset, 0, ((nr + 1) & ~1)*sizeof(compat_ulong_t));
+		memset(fdset, 0, ALIGN(nr, BITS_PER_LONG));
+		return 0;
 	}
-	return 0;
 }
 
 static
 int compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
 		      unsigned long *fdset)
 {
-	unsigned long odd;
-	nr = DIV_ROUND_UP(nr, __COMPAT_NFDBITS);
-
 	if (!ufdset)
 		return 0;
-
-	odd = nr & 1UL;
-	nr &= ~1UL;
-	while (nr) {
-		unsigned long h, l;
-		l = *fdset++;
-		h = l >> 32;
-		if (__put_user(l, ufdset) || __put_user(h, ufdset+1))
-			return -EFAULT;
-		ufdset += 2;
-		nr -= 2;
-	}
-	if (odd && __put_user(*fdset, ufdset))
-		return -EFAULT;
-	return 0;
+	return compat_put_bitmap(ufdset, fdset, nr);
 }
 
 
diff --git a/include/linux/compat.h b/include/linux/compat.h
index 2ed54020ace0c994c5fce8dd3e513f8818303d93..5a6a109b4a508b544882e358def3d11820bce250 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -402,8 +402,7 @@ asmlinkage long compat_sys_wait4(compat_pid_t pid,
 
 #define BITS_PER_COMPAT_LONG    (8*sizeof(compat_long_t))
 
-#define BITS_TO_COMPAT_LONGS(bits) \
-	(((bits)+BITS_PER_COMPAT_LONG-1)/BITS_PER_COMPAT_LONG)
+#define BITS_TO_COMPAT_LONGS(bits) DIV_ROUND_UP(bits, BITS_PER_COMPAT_LONG)
 
 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
 		       unsigned long bitmap_size);
diff --git a/include/linux/signal.h b/include/linux/signal.h
index a39feddd71ba47b67e16351b2f02ea1523943872..e2678b5dbb213f6751283ecc890be2aad304008a 100644
--- a/include/linux/signal.h
+++ b/include/linux/signal.h
@@ -243,8 +243,6 @@ extern int do_send_sig_info(int sig, struct siginfo *info,
 				struct task_struct *p, bool group);
 extern int group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p);
 extern int __group_send_sig_info(int, struct siginfo *, struct task_struct *);
-extern int do_sigtimedwait(const sigset_t *, siginfo_t *,
-				const struct timespec *);
 extern int sigprocmask(int, sigset_t *, sigset_t *);
 extern void set_current_blocked(sigset_t *);
 extern void __set_current_blocked(const sigset_t *);
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f88176347a73bd6335f270779738d5..3cb15ea48aeea8414beed8cdd11d1ece13f71d0d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -650,7 +650,7 @@ asmlinkage long sys_olduname(struct oldold_utsname __user *);
 
 asmlinkage long sys_getrlimit(unsigned int resource,
 				struct rlimit __user *rlim);
-#if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64))
+#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim);
 #endif
 asmlinkage long sys_setrlimit(unsigned int resource,
diff --git a/include/linux/time.h b/include/linux/time.h
index f9858d7e63611d4b0a36a119197ebda22e249bd4..4abb32d4c6b853fa3030703d9458689b875e713c 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -180,9 +180,6 @@ extern int do_getitimer(int which, struct itimerval *value);
 
 extern long do_utimes(int dfd, const char __user *filename, struct timespec *times, int flags);
 
-struct tms;
-extern void do_sys_times(struct tms *);
-
 /*
  * Similar to the struct tm in userspace <time.h>, but it needs to be here so
  * that the kernel source is self contained.
diff --git a/ipc/Makefile b/ipc/Makefile
index 86c7300ecdf5d566111459fe07e7d171e08a192d..9c200e544434761aac1e0d2d9effbcb1c616bd91 100644
--- a/ipc/Makefile
+++ b/ipc/Makefile
@@ -5,8 +5,7 @@
 obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
 obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o syscall.o
 obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
-obj_mq-$(CONFIG_COMPAT) += compat_mq.o
-obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
+obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o
 obj-$(CONFIG_IPC_NS) += namespace.o
 obj-$(CONFIG_POSIX_MQUEUE_SYSCTL) += mq_sysctl.o
 
diff --git a/ipc/compat_mq.c b/ipc/compat_mq.c
deleted file mode 100644
index ef6f91cc4490b5a36311083c1530c345507d0246..0000000000000000000000000000000000000000
--- a/ipc/compat_mq.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- *  ipc/compat_mq.c
- *    32 bit emulation for POSIX message queue system calls
- *
- *    Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
- *    Author: Arnd Bergmann <arnd@arndb.de>
- */
-
-#include <linux/compat.h>
-#include <linux/fs.h>
-#include <linux/kernel.h>
-#include <linux/mqueue.h>
-#include <linux/syscalls.h>
-
-#include <linux/uaccess.h>
-
-struct compat_mq_attr {
-	compat_long_t mq_flags;      /* message queue flags		     */
-	compat_long_t mq_maxmsg;     /* maximum number of messages	     */
-	compat_long_t mq_msgsize;    /* maximum message size		     */
-	compat_long_t mq_curmsgs;    /* number of messages currently queued  */
-	compat_long_t __reserved[4]; /* ignored for input, zeroed for output */
-};
-
-static inline int get_compat_mq_attr(struct mq_attr *attr,
-			const struct compat_mq_attr __user *uattr)
-{
-	if (!access_ok(VERIFY_READ, uattr, sizeof *uattr))
-		return -EFAULT;
-
-	return __get_user(attr->mq_flags, &uattr->mq_flags)
-		| __get_user(attr->mq_maxmsg, &uattr->mq_maxmsg)
-		| __get_user(attr->mq_msgsize, &uattr->mq_msgsize)
-		| __get_user(attr->mq_curmsgs, &uattr->mq_curmsgs);
-}
-
-static inline int put_compat_mq_attr(const struct mq_attr *attr,
-			struct compat_mq_attr __user *uattr)
-{
-	if (clear_user(uattr, sizeof *uattr))
-		return -EFAULT;
-
-	return __put_user(attr->mq_flags, &uattr->mq_flags)
-		| __put_user(attr->mq_maxmsg, &uattr->mq_maxmsg)
-		| __put_user(attr->mq_msgsize, &uattr->mq_msgsize)
-		| __put_user(attr->mq_curmsgs, &uattr->mq_curmsgs);
-}
-
-COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name,
-		       int, oflag, compat_mode_t, mode,
-		       struct compat_mq_attr __user *, u_attr)
-{
-	void __user *p = NULL;
-	if (u_attr && oflag & O_CREAT) {
-		struct mq_attr attr;
-
-		memset(&attr, 0, sizeof(attr));
-
-		p = compat_alloc_user_space(sizeof(attr));
-		if (get_compat_mq_attr(&attr, u_attr) ||
-		    copy_to_user(p, &attr, sizeof(attr)))
-			return -EFAULT;
-	}
-	return sys_mq_open(u_name, oflag, mode, p);
-}
-
-COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
-		       const char __user *, u_msg_ptr,
-		       compat_size_t, msg_len, unsigned int, msg_prio,
-		       const struct compat_timespec __user *, u_abs_timeout)
-{
-	struct timespec __user *u_ts;
-
-	if (compat_convert_timespec(&u_ts, u_abs_timeout))
-		return -EFAULT;
-
-	return sys_mq_timedsend(mqdes, u_msg_ptr, msg_len,
-			msg_prio, u_ts);
-}
-
-COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
-		       char __user *, u_msg_ptr,
-		       compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
-		       const struct compat_timespec __user *, u_abs_timeout)
-{
-	struct timespec __user *u_ts;
-
-	if (compat_convert_timespec(&u_ts, u_abs_timeout))
-		return -EFAULT;
-
-	return sys_mq_timedreceive(mqdes, u_msg_ptr, msg_len,
-			u_msg_prio, u_ts);
-}
-
-COMPAT_SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
-		       const struct compat_sigevent __user *, u_notification)
-{
-	struct sigevent __user *p = NULL;
-	if (u_notification) {
-		struct sigevent n;
-		p = compat_alloc_user_space(sizeof(*p));
-		if (get_compat_sigevent(&n, u_notification))
-			return -EFAULT;
-		if (n.sigev_notify == SIGEV_THREAD)
-			n.sigev_value.sival_ptr = compat_ptr(n.sigev_value.sival_int);
-		if (copy_to_user(p, &n, sizeof(*p)))
-			return -EFAULT;
-	}
-	return sys_mq_notify(mqdes, p);
-}
-
-COMPAT_SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
-		       const struct compat_mq_attr __user *, u_mqstat,
-		       struct compat_mq_attr __user *, u_omqstat)
-{
-	struct mq_attr mqstat;
-	struct mq_attr __user *p = compat_alloc_user_space(2 * sizeof(*p));
-	long ret;
-
-	memset(&mqstat, 0, sizeof(mqstat));
-
-	if (u_mqstat) {
-		if (get_compat_mq_attr(&mqstat, u_mqstat) ||
-		    copy_to_user(p, &mqstat, sizeof(mqstat)))
-			return -EFAULT;
-	}
-	ret = sys_mq_getsetattr(mqdes,
-				u_mqstat ? p : NULL,
-				u_omqstat ? p + 1 : NULL);
-	if (ret)
-		return ret;
-	if (u_omqstat) {
-		if (copy_from_user(&mqstat, p + 1, sizeof(mqstat)) ||
-		    put_compat_mq_attr(&mqstat, u_omqstat))
-			return -EFAULT;
-	}
-	return 0;
-}
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index e8d41ff57241d86e6c2aa0c46e6408897491256e..c9ff943f19abc68158278a0221c6e8a6e432fec5 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -668,14 +668,12 @@ static void __do_notify(struct mqueue_inode_info *info)
 }
 
 static int prepare_timeout(const struct timespec __user *u_abs_timeout,
-			   ktime_t *expires, struct timespec *ts)
+			   struct timespec *ts)
 {
 	if (copy_from_user(ts, u_abs_timeout, sizeof(struct timespec)))
 		return -EFAULT;
 	if (!timespec_valid(ts))
 		return -EINVAL;
-
-	*expires = timespec_to_ktime(*ts);
 	return 0;
 }
 
@@ -770,23 +768,19 @@ static struct file *do_open(struct path *path, int oflag)
 	return dentry_open(path, oflag, current_cred());
 }
 
-SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
-		struct mq_attr __user *, u_attr)
+static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
+		      struct mq_attr *attr)
 {
 	struct path path;
 	struct file *filp;
 	struct filename *name;
-	struct mq_attr attr;
 	int fd, error;
 	struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
 	struct vfsmount *mnt = ipc_ns->mq_mnt;
 	struct dentry *root = mnt->mnt_root;
 	int ro;
 
-	if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
-		return -EFAULT;
-
-	audit_mq_open(oflag, mode, u_attr ? &attr : NULL);
+	audit_mq_open(oflag, mode, attr);
 
 	if (IS_ERR(name = getname(u_name)))
 		return PTR_ERR(name);
@@ -819,9 +813,8 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
 				goto out;
 			}
 			audit_inode_parent_hidden(name, root);
-			filp = do_create(ipc_ns, d_inode(root),
-						&path, oflag, mode,
-						u_attr ? &attr : NULL);
+			filp = do_create(ipc_ns, d_inode(root), &path,
+					 oflag, mode, attr);
 		}
 	} else {
 		if (d_really_is_negative(path.dentry)) {
@@ -851,6 +844,16 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
 	return fd;
 }
 
+SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
+		struct mq_attr __user *, u_attr)
+{
+	struct mq_attr attr;
+	if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
+		return -EFAULT;
+
+	return do_mq_open(u_name, oflag, mode, u_attr ? &attr : NULL);
+}
+
 SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name)
 {
 	int err;
@@ -957,9 +960,9 @@ static inline void pipelined_receive(struct wake_q_head *wake_q,
 	sender->state = STATE_READY;
 }
 
-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)
+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 fd f;
 	struct inode *inode;
@@ -968,22 +971,19 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
 	struct msg_msg *msg_ptr;
 	struct mqueue_inode_info *info;
 	ktime_t expires, *timeout = NULL;
-	struct timespec ts;
 	struct posix_msg_tree_node *new_leaf = NULL;
 	int ret = 0;
 	DEFINE_WAKE_Q(wake_q);
 
-	if (u_abs_timeout) {
-		int res = prepare_timeout(u_abs_timeout, &expires, &ts);
-		if (res)
-			return res;
-		timeout = &expires;
-	}
-
 	if (unlikely(msg_prio >= (unsigned long) MQ_PRIO_MAX))
 		return -EINVAL;
 
-	audit_mq_sendrecv(mqdes, msg_len, msg_prio, timeout ? &ts : NULL);
+	if (ts) {
+		expires = timespec_to_ktime(*ts);
+		timeout = &expires;
+	}
+
+	audit_mq_sendrecv(mqdes, msg_len, msg_prio, ts);
 
 	f = fdget(mqdes);
 	if (unlikely(!f.file)) {
@@ -1078,9 +1078,9 @@ SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes, const char __user *, u_msg_ptr,
 	return ret;
 }
 
-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)
+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)
 {
 	ssize_t ret;
 	struct msg_msg *msg_ptr;
@@ -1089,17 +1089,14 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
 	struct mqueue_inode_info *info;
 	struct ext_wait_queue wait;
 	ktime_t expires, *timeout = NULL;
-	struct timespec ts;
 	struct posix_msg_tree_node *new_leaf = NULL;
 
-	if (u_abs_timeout) {
-		int res = prepare_timeout(u_abs_timeout, &expires, &ts);
-		if (res)
-			return res;
+	if (ts) {
+		expires = timespec_to_ktime(*ts);
 		timeout = &expires;
 	}
 
-	audit_mq_sendrecv(mqdes, msg_len, 0, timeout ? &ts : NULL);
+	audit_mq_sendrecv(mqdes, msg_len, 0, ts);
 
 	f = fdget(mqdes);
 	if (unlikely(!f.file)) {
@@ -1183,42 +1180,62 @@ SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
 	return ret;
 }
 
+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;
+	if (u_abs_timeout) {
+		int res = prepare_timeout(u_abs_timeout, &ts);
+		if (res)
+			return res;
+		p = &ts;
+	}
+	return do_mq_timedsend(mqdes, u_msg_ptr, msg_len, msg_prio, p);
+}
+
+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;
+	if (u_abs_timeout) {
+		int res = prepare_timeout(u_abs_timeout, &ts);
+		if (res)
+			return res;
+		p = &ts;
+	}
+	return do_mq_timedreceive(mqdes, u_msg_ptr, msg_len, u_msg_prio, p);
+}
+
 /*
  * Notes: the case when user wants us to deregister (with NULL as pointer)
  * and he isn't currently owner of notification, will be silently discarded.
  * It isn't explicitly defined in the POSIX.
  */
-SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
-		const struct sigevent __user *, u_notification)
+static int do_mq_notify(mqd_t mqdes, const struct sigevent *notification)
 {
 	int ret;
 	struct fd f;
 	struct sock *sock;
 	struct inode *inode;
-	struct sigevent notification;
 	struct mqueue_inode_info *info;
 	struct sk_buff *nc;
 
-	if (u_notification) {
-		if (copy_from_user(&notification, u_notification,
-					sizeof(struct sigevent)))
-			return -EFAULT;
-	}
-
-	audit_mq_notify(mqdes, u_notification ? &notification : NULL);
+	audit_mq_notify(mqdes, notification);
 
 	nc = NULL;
 	sock = NULL;
-	if (u_notification != NULL) {
-		if (unlikely(notification.sigev_notify != SIGEV_NONE &&
-			     notification.sigev_notify != SIGEV_SIGNAL &&
-			     notification.sigev_notify != SIGEV_THREAD))
+	if (notification != NULL) {
+		if (unlikely(notification->sigev_notify != SIGEV_NONE &&
+			     notification->sigev_notify != SIGEV_SIGNAL &&
+			     notification->sigev_notify != SIGEV_THREAD))
 			return -EINVAL;
-		if (notification.sigev_notify == SIGEV_SIGNAL &&
-			!valid_signal(notification.sigev_signo)) {
+		if (notification->sigev_notify == SIGEV_SIGNAL &&
+			!valid_signal(notification->sigev_signo)) {
 			return -EINVAL;
 		}
-		if (notification.sigev_notify == SIGEV_THREAD) {
+		if (notification->sigev_notify == SIGEV_THREAD) {
 			long timeo;
 
 			/* create the notify skb */
@@ -1228,7 +1245,7 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 				goto out;
 			}
 			if (copy_from_user(nc->data,
-					notification.sigev_value.sival_ptr,
+					notification->sigev_value.sival_ptr,
 					NOTIFY_COOKIE_LEN)) {
 				ret = -EFAULT;
 				goto out;
@@ -1238,7 +1255,7 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 			skb_put(nc, NOTIFY_COOKIE_LEN);
 			/* and attach it to the socket */
 retry:
-			f = fdget(notification.sigev_signo);
+			f = fdget(notification->sigev_signo);
 			if (!f.file) {
 				ret = -EBADF;
 				goto out;
@@ -1278,7 +1295,7 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 
 	ret = 0;
 	spin_lock(&info->lock);
-	if (u_notification == NULL) {
+	if (notification == NULL) {
 		if (info->notify_owner == task_tgid(current)) {
 			remove_notification(info);
 			inode->i_atime = inode->i_ctime = current_time(inode);
@@ -1286,7 +1303,7 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 	} else if (info->notify_owner != NULL) {
 		ret = -EBUSY;
 	} else {
-		switch (notification.sigev_notify) {
+		switch (notification->sigev_notify) {
 		case SIGEV_NONE:
 			info->notify.sigev_notify = SIGEV_NONE;
 			break;
@@ -1298,8 +1315,8 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 			info->notify.sigev_notify = SIGEV_THREAD;
 			break;
 		case SIGEV_SIGNAL:
-			info->notify.sigev_signo = notification.sigev_signo;
-			info->notify.sigev_value = notification.sigev_value;
+			info->notify.sigev_signo = notification->sigev_signo;
+			info->notify.sigev_value = notification->sigev_value;
 			info->notify.sigev_notify = SIGEV_SIGNAL;
 			break;
 		}
@@ -1320,44 +1337,49 @@ SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
 	return ret;
 }
 
-SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
-		const struct mq_attr __user *, u_mqstat,
-		struct mq_attr __user *, u_omqstat)
+SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
+		const struct sigevent __user *, u_notification)
+{
+	struct sigevent n, *p = NULL;
+	if (u_notification) {
+		if (copy_from_user(&n, u_notification, sizeof(struct sigevent)))
+			return -EFAULT;
+		p = &n;
+	}
+	return do_mq_notify(mqdes, p);
+}
+
+static int do_mq_getsetattr(int mqdes, struct mq_attr *new, struct mq_attr *old)
 {
-	int ret;
-	struct mq_attr mqstat, omqstat;
 	struct fd f;
 	struct inode *inode;
 	struct mqueue_inode_info *info;
 
-	if (u_mqstat != NULL) {
-		if (copy_from_user(&mqstat, u_mqstat, sizeof(struct mq_attr)))
-			return -EFAULT;
-		if (mqstat.mq_flags & (~O_NONBLOCK))
-			return -EINVAL;
-	}
+	if (new && (new->mq_flags & (~O_NONBLOCK)))
+		return -EINVAL;
 
 	f = fdget(mqdes);
-	if (!f.file) {
-		ret = -EBADF;
-		goto out;
-	}
+	if (!f.file)
+		return -EBADF;
 
-	inode = file_inode(f.file);
 	if (unlikely(f.file->f_op != &mqueue_file_operations)) {
-		ret = -EBADF;
-		goto out_fput;
+		fdput(f);
+		return -EBADF;
 	}
+
+	inode = file_inode(f.file);
 	info = MQUEUE_I(inode);
 
 	spin_lock(&info->lock);
 
-	omqstat = info->attr;
-	omqstat.mq_flags = f.file->f_flags & O_NONBLOCK;
-	if (u_mqstat) {
-		audit_mq_getsetattr(mqdes, &mqstat);
+	if (old) {
+		*old = info->attr;
+		old->mq_flags = f.file->f_flags & O_NONBLOCK;
+	}
+	if (new) {
+		audit_mq_getsetattr(mqdes, new);
 		spin_lock(&f.file->f_lock);
-		if (mqstat.mq_flags & O_NONBLOCK)
+		if (new->mq_flags & O_NONBLOCK)
 			f.file->f_flags |= O_NONBLOCK;
 		else
 			f.file->f_flags &= ~O_NONBLOCK;
@@ -1367,17 +1389,168 @@ SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
 	}
 
 	spin_unlock(&info->lock);
+	fdput(f);
+	return 0;
+}
 
-	ret = 0;
-	if (u_omqstat != NULL && copy_to_user(u_omqstat, &omqstat,
-						sizeof(struct mq_attr)))
-		ret = -EFAULT;
+SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
+		const struct mq_attr __user *, u_mqstat,
+		struct mq_attr __user *, u_omqstat)
+{
+	int ret;
+	struct mq_attr mqstat, omqstat;
+	struct mq_attr *new = NULL, *old = NULL;
 
-out_fput:
-	fdput(f);
-out:
-	return ret;
+	if (u_mqstat) {
+		new = &mqstat;
+		if (copy_from_user(new, u_mqstat, sizeof(struct mq_attr)))
+			return -EFAULT;
+	}
+	if (u_omqstat)
+		old = &omqstat;
+
+	ret = do_mq_getsetattr(mqdes, new, old);
+	if (ret || !old)
+		return ret;
+
+	if (copy_to_user(u_omqstat, old, sizeof(struct mq_attr)))
+		return -EFAULT;
+	return 0;
+}
+
+#ifdef CONFIG_COMPAT
+
+struct compat_mq_attr {
+	compat_long_t mq_flags;      /* message queue flags		     */
+	compat_long_t mq_maxmsg;     /* maximum number of messages	     */
+	compat_long_t mq_msgsize;    /* maximum message size		     */
+	compat_long_t mq_curmsgs;    /* number of messages currently queued  */
+	compat_long_t __reserved[4]; /* ignored for input, zeroed for output */
+};
+
+static inline int get_compat_mq_attr(struct mq_attr *attr,
+			const struct compat_mq_attr __user *uattr)
+{
+	struct compat_mq_attr v;
+
+	if (copy_from_user(&v, uattr, sizeof(*uattr)))
+		return -EFAULT;
+
+	memset(attr, 0, sizeof(*attr));
+	attr->mq_flags = v.mq_flags;
+	attr->mq_maxmsg = v.mq_maxmsg;
+	attr->mq_msgsize = v.mq_msgsize;
+	attr->mq_curmsgs = v.mq_curmsgs;
+	return 0;
+}
+
+static inline int put_compat_mq_attr(const struct mq_attr *attr,
+			struct compat_mq_attr __user *uattr)
+{
+	struct compat_mq_attr v;
+
+	memset(&v, 0, sizeof(v));
+	v.mq_flags = attr->mq_flags;
+	v.mq_maxmsg = attr->mq_maxmsg;
+	v.mq_msgsize = attr->mq_msgsize;
+	v.mq_curmsgs = attr->mq_curmsgs;
+	if (copy_to_user(uattr, &v, sizeof(*uattr)))
+		return -EFAULT;
+	return 0;
+}
+
+COMPAT_SYSCALL_DEFINE4(mq_open, const char __user *, u_name,
+		       int, oflag, compat_mode_t, mode,
+		       struct compat_mq_attr __user *, u_attr)
+{
+	struct mq_attr attr, *p = NULL;
+	if (u_attr && oflag & O_CREAT) {
+		p = &attr;
+		if (get_compat_mq_attr(&attr, u_attr))
+			return -EFAULT;
+	}
+	return do_mq_open(u_name, oflag, mode, p);
+}
+
+static int compat_prepare_timeout(const struct compat_timespec __user *p,
+				   struct timespec *ts)
+{
+	if (compat_get_timespec(ts, p))
+		return -EFAULT;
+	if (!timespec_valid(ts))
+		return -EINVAL;
+	return 0;
+}
+
+COMPAT_SYSCALL_DEFINE5(mq_timedsend, mqd_t, mqdes,
+		       const char __user *, u_msg_ptr,
+		       compat_size_t, msg_len, unsigned int, msg_prio,
+		       const struct compat_timespec __user *, u_abs_timeout)
+{
+	struct timespec ts, *p = NULL;
+	if (u_abs_timeout) {
+		int res = compat_prepare_timeout(u_abs_timeout, &ts);
+		if (res)
+			return res;
+		p = &ts;
+	}
+	return do_mq_timedsend(mqdes, u_msg_ptr, msg_len, msg_prio, p);
+}
+
+COMPAT_SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes,
+		       char __user *, u_msg_ptr,
+		       compat_size_t, msg_len, unsigned int __user *, u_msg_prio,
+		       const struct compat_timespec __user *, u_abs_timeout)
+{
+	struct timespec ts, *p = NULL;
+	if (u_abs_timeout) {
+		int res = compat_prepare_timeout(u_abs_timeout, &ts);
+		if (res)
+			return res;
+		p = &ts;
+	}
+	return do_mq_timedreceive(mqdes, u_msg_ptr, msg_len, u_msg_prio, p);
+}
+
+COMPAT_SYSCALL_DEFINE2(mq_notify, mqd_t, mqdes,
+		       const struct compat_sigevent __user *, u_notification)
+{
+	struct sigevent n, *p = NULL;
+	if (u_notification) {
+		if (get_compat_sigevent(&n, u_notification))
+			return -EFAULT;
+		if (n.sigev_notify == SIGEV_THREAD)
+			n.sigev_value.sival_ptr = compat_ptr(n.sigev_value.sival_int);
+		p = &n;
+	}
+	return do_mq_notify(mqdes, p);
+}
+
+COMPAT_SYSCALL_DEFINE3(mq_getsetattr, mqd_t, mqdes,
+		       const struct compat_mq_attr __user *, u_mqstat,
+		       struct compat_mq_attr __user *, u_omqstat)
+{
+	int ret;
+	struct mq_attr mqstat, omqstat;
+	struct mq_attr *new = NULL, *old = NULL;
+
+	if (u_mqstat) {
+		new = &mqstat;
+		if (get_compat_mq_attr(new, u_mqstat))
+			return -EFAULT;
+	}
+	if (u_omqstat)
+		old = &omqstat;
+
+	ret = do_mq_getsetattr(mqdes, new, old);
+	if (ret || !old)
+		return ret;
+
+	if (put_compat_mq_attr(old, u_omqstat))
+		return -EFAULT;
+	return 0;
 }
+#endif
 
 static const struct inode_operations mqueue_dir_inode_operations = {
 	.lookup = simple_lookup,
diff --git a/kernel/compat.c b/kernel/compat.c
index 0621c8e1ab7273fb33eee4812c58bf4c9b07f2d6..6f0a0e723a0622a8876f9bfc81bbe08346db2ffd 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -247,53 +247,6 @@ int put_compat_itimerval(struct compat_itimerval __user *o, const struct itimerv
 	return copy_to_user(o, &v32, sizeof(struct compat_itimerval)) ? -EFAULT : 0;
 }
 
-static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
-{
-	return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
-}
-
-COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
-{
-	if (tbuf) {
-		struct tms tms;
-		struct compat_tms tmp;
-
-		do_sys_times(&tms);
-		/* Convert our struct tms to the compat version. */
-		tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
-		tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
-		tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
-		tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
-		if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
-			return -EFAULT;
-	}
-	force_successful_syscall_return();
-	return compat_jiffies_to_clock_t(jiffies);
-}
-
-#ifdef __ARCH_WANT_SYS_SIGPENDING
-
-/*
- * Assumption: old_sigset_t and compat_old_sigset_t are both
- * types that can be passed to put_user()/get_user().
- */
-
-COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set)
-{
-	old_sigset_t s;
-	long ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_sigpending((old_sigset_t __user *) &s);
-	set_fs(old_fs);
-	if (ret == 0)
-		ret = put_user(s, set);
-	return ret;
-}
-
-#endif
-
 #ifdef __ARCH_WANT_SYS_SIGPROCMASK
 
 /*
@@ -348,94 +301,29 @@ COMPAT_SYSCALL_DEFINE3(sigprocmask, int, how,
 
 #endif
 
-COMPAT_SYSCALL_DEFINE2(setrlimit, unsigned int, resource,
-		       struct compat_rlimit __user *, rlim)
-{
-	struct rlimit r;
-
-	if (!access_ok(VERIFY_READ, rlim, sizeof(*rlim)) ||
-	    __get_user(r.rlim_cur, &rlim->rlim_cur) ||
-	    __get_user(r.rlim_max, &rlim->rlim_max))
-		return -EFAULT;
-
-	if (r.rlim_cur == COMPAT_RLIM_INFINITY)
-		r.rlim_cur = RLIM_INFINITY;
-	if (r.rlim_max == COMPAT_RLIM_INFINITY)
-		r.rlim_max = RLIM_INFINITY;
-	return do_prlimit(current, resource, &r, NULL);
-}
-
-#ifdef COMPAT_RLIM_OLD_INFINITY
-
-COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
-		       struct compat_rlimit __user *, rlim)
-{
-	struct rlimit r;
-	int ret;
-	mm_segment_t old_fs = get_fs();
-
-	set_fs(KERNEL_DS);
-	ret = sys_old_getrlimit(resource, (struct rlimit __user *)&r);
-	set_fs(old_fs);
-
-	if (!ret) {
-		if (r.rlim_cur > COMPAT_RLIM_OLD_INFINITY)
-			r.rlim_cur = COMPAT_RLIM_INFINITY;
-		if (r.rlim_max > COMPAT_RLIM_OLD_INFINITY)
-			r.rlim_max = COMPAT_RLIM_INFINITY;
-
-		if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
-		    __put_user(r.rlim_cur, &rlim->rlim_cur) ||
-		    __put_user(r.rlim_max, &rlim->rlim_max))
-			return -EFAULT;
-	}
-	return ret;
-}
-
-#endif
-
-COMPAT_SYSCALL_DEFINE2(getrlimit, unsigned int, resource,
-		       struct compat_rlimit __user *, rlim)
-{
-	struct rlimit r;
-	int ret;
-
-	ret = do_prlimit(current, resource, NULL, &r);
-	if (!ret) {
-		if (r.rlim_cur > COMPAT_RLIM_INFINITY)
-			r.rlim_cur = COMPAT_RLIM_INFINITY;
-		if (r.rlim_max > COMPAT_RLIM_INFINITY)
-			r.rlim_max = COMPAT_RLIM_INFINITY;
-
-		if (!access_ok(VERIFY_WRITE, rlim, sizeof(*rlim)) ||
-		    __put_user(r.rlim_cur, &rlim->rlim_cur) ||
-		    __put_user(r.rlim_max, &rlim->rlim_max))
-			return -EFAULT;
-	}
-	return ret;
-}
-
 int put_compat_rusage(const struct rusage *r, struct compat_rusage __user *ru)
 {
-	if (!access_ok(VERIFY_WRITE, ru, sizeof(*ru)) ||
-	    __put_user(r->ru_utime.tv_sec, &ru->ru_utime.tv_sec) ||
-	    __put_user(r->ru_utime.tv_usec, &ru->ru_utime.tv_usec) ||
-	    __put_user(r->ru_stime.tv_sec, &ru->ru_stime.tv_sec) ||
-	    __put_user(r->ru_stime.tv_usec, &ru->ru_stime.tv_usec) ||
-	    __put_user(r->ru_maxrss, &ru->ru_maxrss) ||
-	    __put_user(r->ru_ixrss, &ru->ru_ixrss) ||
-	    __put_user(r->ru_idrss, &ru->ru_idrss) ||
-	    __put_user(r->ru_isrss, &ru->ru_isrss) ||
-	    __put_user(r->ru_minflt, &ru->ru_minflt) ||
-	    __put_user(r->ru_majflt, &ru->ru_majflt) ||
-	    __put_user(r->ru_nswap, &ru->ru_nswap) ||
-	    __put_user(r->ru_inblock, &ru->ru_inblock) ||
-	    __put_user(r->ru_oublock, &ru->ru_oublock) ||
-	    __put_user(r->ru_msgsnd, &ru->ru_msgsnd) ||
-	    __put_user(r->ru_msgrcv, &ru->ru_msgrcv) ||
-	    __put_user(r->ru_nsignals, &ru->ru_nsignals) ||
-	    __put_user(r->ru_nvcsw, &ru->ru_nvcsw) ||
-	    __put_user(r->ru_nivcsw, &ru->ru_nivcsw))
+	struct compat_rusage r32;
+	memset(&r32, 0, sizeof(r32));
+	r32.ru_utime.tv_sec = r->ru_utime.tv_sec;
+	r32.ru_utime.tv_usec = r->ru_utime.tv_usec;
+	r32.ru_stime.tv_sec = r->ru_stime.tv_sec;
+	r32.ru_stime.tv_usec = r->ru_stime.tv_usec;
+	r32.ru_maxrss = r->ru_maxrss;
+	r32.ru_ixrss = r->ru_ixrss;
+	r32.ru_idrss = r->ru_idrss;
+	r32.ru_isrss = r->ru_isrss;
+	r32.ru_minflt = r->ru_minflt;
+	r32.ru_majflt = r->ru_majflt;
+	r32.ru_nswap = r->ru_nswap;
+	r32.ru_inblock = r->ru_inblock;
+	r32.ru_oublock = r->ru_oublock;
+	r32.ru_msgsnd = r->ru_msgsnd;
+	r32.ru_msgrcv = r->ru_msgrcv;
+	r32.ru_nsignals = r->ru_nsignals;
+	r32.ru_nvcsw = r->ru_nvcsw;
+	r32.ru_nivcsw = r->ru_nivcsw;
+	if (copy_to_user(ru, &r32, sizeof(r32)))
 		return -EFAULT;
 	return 0;
 }
@@ -565,84 +453,59 @@ int get_compat_sigevent(struct sigevent *event,
 long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
 		       unsigned long bitmap_size)
 {
-	int i, j;
-	unsigned long m;
-	compat_ulong_t um;
 	unsigned long nr_compat_longs;
 
 	/* align bitmap up to nearest compat_long_t boundary */
 	bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
+	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
 	if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
 		return -EFAULT;
 
-	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
-
-	for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
-		m = 0;
-
-		for (j = 0; j < sizeof(m)/sizeof(um); j++) {
-			/*
-			 * We dont want to read past the end of the userspace
-			 * bitmap. We must however ensure the end of the
-			 * kernel bitmap is zeroed.
-			 */
-			if (nr_compat_longs) {
-				nr_compat_longs--;
-				if (__get_user(um, umask))
-					return -EFAULT;
-			} else {
-				um = 0;
-			}
-
-			umask++;
-			m |= (long)um << (j * BITS_PER_COMPAT_LONG);
-		}
-		*mask++ = m;
+	user_access_begin();
+	while (nr_compat_longs > 1) {
+		compat_ulong_t l1, l2;
+		unsafe_get_user(l1, umask++, Efault);
+		unsafe_get_user(l2, umask++, Efault);
+		*mask++ = ((unsigned long)l2 << BITS_PER_COMPAT_LONG) | l1;
+		nr_compat_longs -= 2;
 	}
-
+	if (nr_compat_longs)
+		unsafe_get_user(*mask, umask++, Efault);
+	user_access_end();
 	return 0;
+
+Efault:
+	user_access_end();
+	return -EFAULT;
 }
 
 long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
 		       unsigned long bitmap_size)
 {
-	int i, j;
-	unsigned long m;
-	compat_ulong_t um;
 	unsigned long nr_compat_longs;
 
 	/* align bitmap up to nearest compat_long_t boundary */
 	bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
+	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
 
 	if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
 		return -EFAULT;
 
-	nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
-
-	for (i = 0; i < BITS_TO_LONGS(bitmap_size); i++) {
-		m = *mask++;
-
-		for (j = 0; j < sizeof(m)/sizeof(um); j++) {
-			um = m;
-
-			/*
-			 * We dont want to write past the end of the userspace
-			 * bitmap.
-			 */
-			if (nr_compat_longs) {
-				nr_compat_longs--;
-				if (__put_user(um, umask))
-					return -EFAULT;
-			}
-
-			umask++;
-			m >>= 4*sizeof(um);
-			m >>= 4*sizeof(um);
-		}
+	user_access_begin();
+	while (nr_compat_longs > 1) {
+		unsigned long m = *mask++;
+		unsafe_put_user((compat_ulong_t)m, umask++, Efault);
+		unsafe_put_user(m >> BITS_PER_COMPAT_LONG, umask++, Efault);
+		nr_compat_longs -= 2;
 	}
-
+	if (nr_compat_longs)
+		unsafe_put_user((compat_ulong_t)*mask, umask++, Efault);
+	user_access_end();
 	return 0;
+Efault:
+	user_access_end();
+	return -EFAULT;
 }
 
 void
@@ -668,38 +531,6 @@ sigset_to_compat(compat_sigset_t *compat, const sigset_t *set)
 	}
 }
 
-COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
-		struct compat_siginfo __user *, uinfo,
-		struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
-{
-	compat_sigset_t s32;
-	sigset_t s;
-	struct timespec t;
-	siginfo_t info;
-	long ret;
-
-	if (sigsetsize != sizeof(sigset_t))
-		return -EINVAL;
-
-	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
-		return -EFAULT;
-	sigset_from_compat(&s, &s32);
-
-	if (uts) {
-		if (compat_get_timespec(&t, uts))
-			return -EFAULT;
-	}
-
-	ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
-
-	if (ret > 0 && uinfo) {
-		if (copy_siginfo_to_user32(uinfo, &info))
-			ret = -EFAULT;
-	}
-
-	return ret;
-}
-
 #ifdef CONFIG_NUMA
 COMPAT_SYSCALL_DEFINE6(move_pages, pid_t, pid, compat_ulong_t, nr_pages,
 		       compat_uptr_t __user *, pages32,
diff --git a/kernel/signal.c b/kernel/signal.c
index 35a570f71f07c4ec52769f893bb22625f6e8acfd..48a59eefd8adb8ffeb2be4a7b7307eba18950155 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2776,7 +2776,7 @@ int copy_siginfo_to_user(siginfo_t __user *to, const siginfo_t *from)
  *  @info: if non-null, the signal's siginfo is returned here
  *  @ts: upper bound on process time suspension
  */
-int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
+static int do_sigtimedwait(const sigset_t *which, siginfo_t *info,
 		    const struct timespec *ts)
 {
 	ktime_t *to = NULL, timeout = KTIME_MAX;
@@ -2865,6 +2865,40 @@ SYSCALL_DEFINE4(rt_sigtimedwait, const sigset_t __user *, uthese,
 	return ret;
 }
 
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE4(rt_sigtimedwait, compat_sigset_t __user *, uthese,
+		struct compat_siginfo __user *, uinfo,
+		struct compat_timespec __user *, uts, compat_size_t, sigsetsize)
+{
+	compat_sigset_t s32;
+	sigset_t s;
+	struct timespec t;
+	siginfo_t info;
+	long ret;
+
+	if (sigsetsize != sizeof(sigset_t))
+		return -EINVAL;
+
+	if (copy_from_user(&s32, uthese, sizeof(compat_sigset_t)))
+		return -EFAULT;
+	sigset_from_compat(&s, &s32);
+
+	if (uts) {
+		if (compat_get_timespec(&t, uts))
+			return -EFAULT;
+	}
+
+	ret = do_sigtimedwait(&s, &info, uts ? &t : NULL);
+
+	if (ret > 0 && uinfo) {
+		if (copy_siginfo_to_user32(uinfo, &info))
+			ret = -EFAULT;
+	}
+
+	return ret;
+}
+#endif
+
 /**
  *  sys_kill - send a signal to a process
  *  @pid: the PID of the process
@@ -3121,78 +3155,68 @@ int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
 }
 
 static int
-do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long sp)
+do_sigaltstack (const stack_t *ss, stack_t *oss, unsigned long sp)
 {
-	stack_t oss;
-	int error;
+	struct task_struct *t = current;
 
-	oss.ss_sp = (void __user *) current->sas_ss_sp;
-	oss.ss_size = current->sas_ss_size;
-	oss.ss_flags = sas_ss_flags(sp) |
-		(current->sas_ss_flags & SS_FLAG_BITS);
+	if (oss) {
+		memset(oss, 0, sizeof(stack_t));
+		oss->ss_sp = (void __user *) t->sas_ss_sp;
+		oss->ss_size = t->sas_ss_size;
+		oss->ss_flags = sas_ss_flags(sp) |
+			(current->sas_ss_flags & SS_FLAG_BITS);
+	}
 
-	if (uss) {
-		void __user *ss_sp;
-		size_t ss_size;
-		unsigned ss_flags;
+	if (ss) {
+		void __user *ss_sp = ss->ss_sp;
+		size_t ss_size = ss->ss_size;
+		unsigned ss_flags = ss->ss_flags;
 		int ss_mode;
 
-		error = -EFAULT;
-		if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
-			goto out;
-		error = __get_user(ss_sp, &uss->ss_sp) |
-			__get_user(ss_flags, &uss->ss_flags) |
-			__get_user(ss_size, &uss->ss_size);
-		if (error)
-			goto out;
-
-		error = -EPERM;
-		if (on_sig_stack(sp))
-			goto out;
+		if (unlikely(on_sig_stack(sp)))
+			return -EPERM;
 
 		ss_mode = ss_flags & ~SS_FLAG_BITS;
-		error = -EINVAL;
-		if (ss_mode != SS_DISABLE && ss_mode != SS_ONSTACK &&
-				ss_mode != 0)
-			goto out;
+		if (unlikely(ss_mode != SS_DISABLE && ss_mode != SS_ONSTACK &&
+				ss_mode != 0))
+			return -EINVAL;
 
 		if (ss_mode == SS_DISABLE) {
 			ss_size = 0;
 			ss_sp = NULL;
 		} else {
-			error = -ENOMEM;
-			if (ss_size < MINSIGSTKSZ)
-				goto out;
+			if (unlikely(ss_size < MINSIGSTKSZ))
+				return -ENOMEM;
 		}
 
-		current->sas_ss_sp = (unsigned long) ss_sp;
-		current->sas_ss_size = ss_size;
-		current->sas_ss_flags = ss_flags;
+		t->sas_ss_sp = (unsigned long) ss_sp;
+		t->sas_ss_size = ss_size;
+		t->sas_ss_flags = ss_flags;
 	}
-
-	error = 0;
-	if (uoss) {
-		error = -EFAULT;
-		if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
-			goto out;
-		error = __put_user(oss.ss_sp, &uoss->ss_sp) |
-			__put_user(oss.ss_size, &uoss->ss_size) |
-			__put_user(oss.ss_flags, &uoss->ss_flags);
-	}
-
-out:
-	return error;
+	return 0;
 }
+
 SYSCALL_DEFINE2(sigaltstack,const stack_t __user *,uss, stack_t __user *,uoss)
 {
-	return do_sigaltstack(uss, uoss, current_user_stack_pointer());
+	stack_t new, old;
+	int err;
+	if (uss && copy_from_user(&new, uss, sizeof(stack_t)))
+		return -EFAULT;
+	err = do_sigaltstack(uss ? &new : NULL, uoss ? &old : NULL,
+			      current_user_stack_pointer());
+	if (!err && uoss && copy_to_user(uoss, &old, sizeof(stack_t)))
+		err = -EFAULT;
+	return err;
 }
 
 int restore_altstack(const stack_t __user *uss)
 {
-	int err = do_sigaltstack(uss, NULL, current_user_stack_pointer());
+	stack_t new;
+	if (copy_from_user(&new, uss, sizeof(stack_t)))
+		return -EFAULT;
+	(void)do_sigaltstack(&new, NULL, current_user_stack_pointer());
 	/* squash all but EFAULT for now */
-	return err == -EFAULT ? err : 0;
+	return 0;
 }
 
 int __save_altstack(stack_t __user *uss, unsigned long sp)
@@ -3215,29 +3239,24 @@ COMPAT_SYSCALL_DEFINE2(sigaltstack,
 {
 	stack_t uss, uoss;
 	int ret;
-	mm_segment_t seg;
 
 	if (uss_ptr) {
 		compat_stack_t uss32;
-
-		memset(&uss, 0, sizeof(stack_t));
 		if (copy_from_user(&uss32, uss_ptr, sizeof(compat_stack_t)))
 			return -EFAULT;
 		uss.ss_sp = compat_ptr(uss32.ss_sp);
 		uss.ss_flags = uss32.ss_flags;
 		uss.ss_size = uss32.ss_size;
 	}
-	seg = get_fs();
-	set_fs(KERNEL_DS);
-	ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
-			     (stack_t __force __user *) &uoss,
+	ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss,
 			     compat_user_stack_pointer());
-	set_fs(seg);
 	if (ret >= 0 && uoss_ptr)  {
-		if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(compat_stack_t)) ||
-		    __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
-		    __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
-		    __put_user(uoss.ss_size, &uoss_ptr->ss_size))
+		compat_stack_t old;
+		memset(&old, 0, sizeof(old));
+		old.ss_sp = ptr_to_compat(uoss.ss_sp);
+		old.ss_flags = uoss.ss_flags;
+		old.ss_size = uoss.ss_size;
+		if (copy_to_user(uoss_ptr, &old, sizeof(compat_stack_t)))
 			ret = -EFAULT;
 	}
 	return ret;
@@ -3277,6 +3296,18 @@ SYSCALL_DEFINE1(sigpending, old_sigset_t __user *, set)
 	return sys_rt_sigpending((sigset_t __user *)set, sizeof(old_sigset_t)); 
 }
 
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE1(sigpending, compat_old_sigset_t __user *, set32)
+{
+	sigset_t set;
+	int err = do_sigpending(&set, sizeof(old_sigset_t)); 
+	if (err == 0)
+		if (copy_to_user(set32, &set, sizeof(old_sigset_t)))
+			err = -EFAULT;
+	return err;
+}
+#endif
+
 #endif
 
 #ifdef __ARCH_WANT_SYS_SIGPROCMASK
diff --git a/kernel/sys.c b/kernel/sys.c
index dab1a0658a92b7903a9b0318ee89429e18df2339..47d901586b4e0ac5185ba256a720098ad11c96f7 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -886,7 +886,7 @@ SYSCALL_DEFINE0(getegid)
 	return from_kgid_munged(current_user_ns(), current_egid());
 }
 
-void do_sys_times(struct tms *tms)
+static void do_sys_times(struct tms *tms)
 {
 	u64 tgutime, tgstime, cutime, cstime;
 
@@ -912,6 +912,32 @@ SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
 	return (long) jiffies_64_to_clock_t(get_jiffies_64());
 }
 
+#ifdef CONFIG_COMPAT
+static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
+{
+	return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
+}
+
+COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
+{
+	if (tbuf) {
+		struct tms tms;
+		struct compat_tms tmp;
+
+		do_sys_times(&tms);
+		/* Convert our struct tms to the compat version. */
+		tmp.tms_utime = clock_t_to_compat_clock_t(tms.tms_utime);
+		tmp.tms_stime = clock_t_to_compat_clock_t(tms.tms_stime);
+		tmp.tms_cutime = clock_t_to_compat_clock_t(tms.tms_cutime);
+		tmp.tms_cstime = clock_t_to_compat_clock_t(tms.tms_cstime);
+		if (copy_to_user(tbuf, &tmp, sizeof(tmp)))
+			return -EFAULT;
+	}
+	force_successful_syscall_return();
+	return compat_jiffies_to_clock_t(jiffies);
+}
+#endif
+
 /*
  * This needs some heavy checking ...
  * I just haven't the stomach for it. I also don't fully
@@ -1306,6 +1332,54 @@ SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
 	return ret;
 }
 
+#ifdef CONFIG_COMPAT
+
+COMPAT_SYSCALL_DEFINE2(setrlimit, unsigned int, resource,
+		       struct compat_rlimit __user *, rlim)
+{
+	struct rlimit r;
+	struct compat_rlimit r32;
+
+	if (copy_from_user(&r32, rlim, sizeof(struct compat_rlimit)))
+		return -EFAULT;
+
+	if (r32.rlim_cur == COMPAT_RLIM_INFINITY)
+		r.rlim_cur = RLIM_INFINITY;
+	else
+		r.rlim_cur = r32.rlim_cur;
+	if (r32.rlim_max == COMPAT_RLIM_INFINITY)
+		r.rlim_max = RLIM_INFINITY;
+	else
+		r.rlim_max = r32.rlim_max;
+	return do_prlimit(current, resource, &r, NULL);
+}
+
+COMPAT_SYSCALL_DEFINE2(getrlimit, unsigned int, resource,
+		       struct compat_rlimit __user *, rlim)
+{
+	struct rlimit r;
+	int ret;
+
+	ret = do_prlimit(current, resource, NULL, &r);
+	if (!ret) {
+		struct rlimit r32;
+		if (r.rlim_cur > COMPAT_RLIM_INFINITY)
+			r32.rlim_cur = COMPAT_RLIM_INFINITY;
+		else
+			r32.rlim_cur = r.rlim_cur;
+		if (r.rlim_max > COMPAT_RLIM_INFINITY)
+			r32.rlim_max = COMPAT_RLIM_INFINITY;
+		else
+			r32.rlim_max = r.rlim_max;
+
+		if (copy_to_user(rlim, &r32, sizeof(struct compat_rlimit)))
+			return -EFAULT;
+	}
+	return ret;
+}
+
+#endif
+
 #ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
 
 /*
@@ -1328,6 +1402,30 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
 	return copy_to_user(rlim, &x, sizeof(x)) ? -EFAULT : 0;
 }
 
+#ifdef CONFIG_COMPAT
+COMPAT_SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
+		       struct compat_rlimit __user *, rlim)
+{
+	struct rlimit r;
+
+	if (resource >= RLIM_NLIMITS)
+		return -EINVAL;
+
+	task_lock(current->group_leader);
+	r = current->signal->rlim[resource];
+	task_unlock(current->group_leader);
+	if (r.rlim_cur > 0x7FFFFFFF)
+		r.rlim_cur = 0x7FFFFFFF;
+	if (r.rlim_max > 0x7FFFFFFF)
+		r.rlim_max = 0x7FFFFFFF;
+
+	if (put_user(r.rlim_cur, &rlim->rlim_cur) ||
+	    put_user(r.rlim_max, &rlim->rlim_max))
+		return -EFAULT;
+	return 0;
+}
+#endif
+
 #endif
 
 static inline bool rlim64_is_infinity(__u64 rlim64)