diff options
author | Ben Hutchings <ben@decadent.org.uk> | 2011-12-27 16:54:52 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2012-01-04 18:05:55 -0500 |
commit | c336078bf65c4d38caa9a4b8b7b7261c778e622c (patch) | |
tree | 607e18f9f5e60ad370e7c0ed7c13c665af04b7e8 /kernel/power | |
parent | 90363ddf0a1a4dccfbb8d0c10b8f488bc7fa69f8 (diff) |
PM / Hibernate: Implement compat_ioctl for /dev/snapshot
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>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Diffstat (limited to 'kernel/power')
-rw-r--r-- | 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 78bdb4404aab..6b1ab7a88522 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/swapops.h> | 21 | #include <linux/swapops.h> |
22 | #include <linux/pm.h> | 22 | #include <linux/pm.h> |
23 | #include <linux/fs.h> | 23 | #include <linux/fs.h> |
24 | #include <linux/compat.h> | ||
24 | #include <linux/console.h> | 25 | #include <linux/console.h> |
25 | #include <linux/cpu.h> | 26 | #include <linux/cpu.h> |
26 | #include <linux/freezer.h> | 27 | #include <linux/freezer.h> |
@@ -380,6 +381,66 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd, | |||
380 | return error; | 381 | return error; |
381 | } | 382 | } |
382 | 383 | ||
384 | #ifdef CONFIG_COMPAT | ||
385 | |||
386 | struct compat_resume_swap_area { | ||
387 | compat_loff_t offset; | ||
388 | u32 dev; | ||
389 | } __packed; | ||
390 | |||
391 | static long | ||
392 | snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
393 | { | ||
394 | BUILD_BUG_ON(sizeof(loff_t) != sizeof(compat_loff_t)); | ||
395 | |||
396 | switch (cmd) { | ||
397 | case SNAPSHOT_GET_IMAGE_SIZE: | ||
398 | case SNAPSHOT_AVAIL_SWAP_SIZE: | ||
399 | case SNAPSHOT_ALLOC_SWAP_PAGE: { | ||
400 | compat_loff_t __user *uoffset = compat_ptr(arg); | ||
401 | loff_t offset; | ||
402 | mm_segment_t old_fs; | ||
403 | int err; | ||
404 | |||
405 | old_fs = get_fs(); | ||
406 | set_fs(KERNEL_DS); | ||
407 | err = snapshot_ioctl(file, cmd, (unsigned long) &offset); | ||
408 | set_fs(old_fs); | ||
409 | if (!err && put_user(offset, uoffset)) | ||
410 | err = -EFAULT; | ||
411 | return err; | ||
412 | } | ||
413 | |||
414 | case SNAPSHOT_CREATE_IMAGE: | ||
415 | return snapshot_ioctl(file, cmd, | ||
416 | (unsigned long) compat_ptr(arg)); | ||
417 | |||
418 | case SNAPSHOT_SET_SWAP_AREA: { | ||
419 | struct compat_resume_swap_area __user *u_swap_area = | ||
420 | compat_ptr(arg); | ||
421 | struct resume_swap_area swap_area; | ||
422 | mm_segment_t old_fs; | ||
423 | int err; | ||
424 | |||
425 | err = get_user(swap_area.offset, &u_swap_area->offset); | ||
426 | err |= get_user(swap_area.dev, &u_swap_area->dev); | ||
427 | if (err) | ||
428 | return -EFAULT; | ||
429 | old_fs = get_fs(); | ||
430 | set_fs(KERNEL_DS); | ||
431 | err = snapshot_ioctl(file, SNAPSHOT_SET_SWAP_AREA, | ||
432 | (unsigned long) &swap_area); | ||
433 | set_fs(old_fs); | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | default: | ||
438 | return snapshot_ioctl(file, cmd, arg); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | #endif /* CONFIG_COMPAT */ | ||
443 | |||
383 | static const struct file_operations snapshot_fops = { | 444 | static const struct file_operations snapshot_fops = { |
384 | .open = snapshot_open, | 445 | .open = snapshot_open, |
385 | .release = snapshot_release, | 446 | .release = snapshot_release, |
@@ -387,6 +448,9 @@ static const struct file_operations snapshot_fops = { | |||
387 | .write = snapshot_write, | 448 | .write = snapshot_write, |
388 | .llseek = no_llseek, | 449 | .llseek = no_llseek, |
389 | .unlocked_ioctl = snapshot_ioctl, | 450 | .unlocked_ioctl = snapshot_ioctl, |
451 | #ifdef CONFIG_COMPAT | ||
452 | .compat_ioctl = snapshot_compat_ioctl, | ||
453 | #endif | ||
390 | }; | 454 | }; |
391 | 455 | ||
392 | static struct miscdevice snapshot_device = { | 456 | static struct miscdevice snapshot_device = { |