diff options
Diffstat (limited to 'kernel')
| -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 = { |
