[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#502816: [PATCH] snapshot: Implement compat_ioctl



On Tuesday, December 27, 2011, Ben Hutchings wrote:
> This allows uswsusp built for i386 to run on an x86_64 kernel (tested
> with Debian package version 1.0+20110509-2).
> 
> References: http://bugs.debian.org/502816
> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>

Applied to linux-pm/linux-next.

Thanks,
Rafael


> ---
>  kernel/power/user.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 64 insertions(+), 0 deletions(-)
> 
> diff --git a/kernel/power/user.c b/kernel/power/user.c
> index 6d8f535..d86e5a7 100644
> --- a/kernel/power/user.c
> +++ b/kernel/power/user.c
> @@ -21,6 +21,7 @@
>  #include <linux/swapops.h>
>  #include <linux/pm.h>
>  #include <linux/fs.h>
> +#include <linux/compat.h>
>  #include <linux/console.h>
>  #include <linux/cpu.h>
>  #include <linux/freezer.h>
> @@ -464,6 +465,66 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
>  	return error;
>  }
>  
> +#ifdef CONFIG_COMPAT
> +
> +struct compat_resume_swap_area {
> +	compat_loff_t offset;
> +	u32 dev;
> +} __packed;
> +
> +static long
> +snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
> +{
> +	BUILD_BUG_ON(sizeof(loff_t) != sizeof(compat_loff_t));
> +
> +	switch (cmd) {
> +	case SNAPSHOT_GET_IMAGE_SIZE:
> +	case SNAPSHOT_AVAIL_SWAP_SIZE:
> +	case SNAPSHOT_ALLOC_SWAP_PAGE: {
> +		compat_loff_t __user *uoffset = compat_ptr(arg);
> +		loff_t offset;
> +		mm_segment_t old_fs;
> +		int err;
> +
> +		old_fs = get_fs();
> +		set_fs(KERNEL_DS);
> +		err = snapshot_ioctl(file, cmd, (unsigned long) &offset);
> +		set_fs(old_fs);
> +		if (!err && put_user(offset, uoffset))
> +			err = -EFAULT;
> +		return err;
> +	}
> +
> +	case SNAPSHOT_CREATE_IMAGE:
> +		return snapshot_ioctl(file, cmd,
> +				      (unsigned long) compat_ptr(arg));
> +
> +	case SNAPSHOT_SET_SWAP_AREA: {
> +		struct compat_resume_swap_area __user *u_swap_area =
> +			compat_ptr(arg);
> +		struct resume_swap_area swap_area;
> +		mm_segment_t old_fs;
> +		int err;
> +
> +		err = get_user(swap_area.offset, &u_swap_area->offset);
> +		err |= get_user(swap_area.dev, &u_swap_area->dev);
> +		if (err)
> +			return -EFAULT;
> +		old_fs = get_fs();
> +		set_fs(KERNEL_DS);
> +		err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA,
> +				     (unsigned long) &swap_area);
> +		set_fs(old_fs);
> +		return err;
> +	}
> +
> +	default:
> +		return snapshot_ioctl(file, cmd, arg);
> +	}
> +}
> +
> +#endif /* CONFIG_COMPAT */
> +
>  static const struct file_operations snapshot_fops = {
>  	.open = snapshot_open,
>  	.release = snapshot_release,
> @@ -471,6 +532,9 @@ static const struct file_operations snapshot_fops = {
>  	.write = snapshot_write,
>  	.llseek = no_llseek,
>  	.unlocked_ioctl = snapshot_ioctl,
> +#ifdef CONFIG_COMPAT
> +	.compat_ioctl = snapshot_compat_ioctl,
> +#endif
>  };
>  
>  static struct miscdevice snapshot_device = {
> 




Reply to: