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 <b...@decadent.org.uk>
---
 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 = {
-- 
1.7.7.3





--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to