diff options
-rw-r--r-- | kernel/power/power.h | 14 | ||||
-rw-r--r-- | kernel/power/user.c | 31 |
2 files changed, 44 insertions, 1 deletions
diff --git a/kernel/power/power.h b/kernel/power/power.h index adaf7d4fbda..7dbfd9f67e1 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -106,6 +106,16 @@ extern int snapshot_write_next(struct snapshot_handle *handle, size_t count); extern int snapshot_image_loaded(struct snapshot_handle *handle); extern void snapshot_free_unused_memory(struct snapshot_handle *handle); +/* + * This structure is used to pass the values needed for the identification + * of the resume swap area from a user space to the kernel via the + * SNAPSHOT_SET_SWAP_AREA ioctl + */ +struct resume_swap_area { + loff_t offset; + u_int32_t dev; +} __attribute__((packed)); + #define SNAPSHOT_IOC_MAGIC '3' #define SNAPSHOT_FREEZE _IO(SNAPSHOT_IOC_MAGIC, 1) #define SNAPSHOT_UNFREEZE _IO(SNAPSHOT_IOC_MAGIC, 2) @@ -119,7 +129,9 @@ extern void snapshot_free_unused_memory(struct snapshot_handle *handle); #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) #define SNAPSHOT_S2RAM _IO(SNAPSHOT_IOC_MAGIC, 11) #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) -#define SNAPSHOT_IOC_MAXNR 12 +#define SNAPSHOT_SET_SWAP_AREA _IOW(SNAPSHOT_IOC_MAGIC, 13, \ + struct resume_swap_area) +#define SNAPSHOT_IOC_MAXNR 13 #define PMOPS_PREPARE 1 #define PMOPS_ENTER 2 diff --git a/kernel/power/user.c b/kernel/power/user.c index f0b7ef8bdd7..05c58a2c0dd 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -343,6 +343,37 @@ OutS3: } break; + case SNAPSHOT_SET_SWAP_AREA: + if (data->bitmap) { + error = -EPERM; + } else { + struct resume_swap_area swap_area; + dev_t swdev; + + error = copy_from_user(&swap_area, (void __user *)arg, + sizeof(struct resume_swap_area)); + if (error) { + error = -EFAULT; + break; + } + + /* + * User space encodes device types as two-byte values, + * so we need to recode them + */ + swdev = old_decode_dev(swap_area.dev); + if (swdev) { + offset = swap_area.offset; + data->swap = swap_type_of(swdev, offset); + if (data->swap < 0) + error = -ENODEV; + } else { + data->swap = -1; + error = -EINVAL; + } + } + break; + default: error = -ENOTTY; |