1 /* 2 * linux/kernel/power/user.c 3 * 4 * This file provides the user space interface for software suspend/resume. 5 * 6 * Copyright (C) 2006 Rafael J. Wysocki <rjw@sisk.pl> 7 * 8 * This file is released under the GPLv2. 9 * 10 */ 11 12 #include <linux/suspend.h> 13 #include <linux/syscalls.h> 14 #include <linux/reboot.h> 15 #include <linux/string.h> 16 #include <linux/device.h> 17 #include <linux/miscdevice.h> 18 #include <linux/mm.h> 19 #include <linux/swap.h> 20 #include <linux/swapops.h> 21 #include <linux/pm.h> 22 #include <linux/fs.h> 23 #include <linux/console.h> 24 #include <linux/cpu.h> 25 #include <linux/freezer.h> 26 #include <linux/smp_lock.h> 27 #include <scsi/scsi_scan.h> 28 29 #include <asm/uaccess.h> 30 31 #include "power.h" 32 33 /* 34 * NOTE: The SNAPSHOT_SET_SWAP_FILE and SNAPSHOT_PMOPS ioctls are obsolete and 35 * will be removed in the future. They are only preserved here for 36 * compatibility with existing userland utilities. 37 */ 38 #define SNAPSHOT_SET_SWAP_FILE _IOW(SNAPSHOT_IOC_MAGIC, 10, unsigned int) 39 #define SNAPSHOT_PMOPS _IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int) 40 41 #define PMOPS_PREPARE 1 42 #define PMOPS_ENTER 2 43 #define PMOPS_FINISH 3 44 45 /* 46 * NOTE: The following ioctl definitions are wrong and have been replaced with 47 * correct ones. They are only preserved here for compatibility with existing 48 * userland utilities and will be removed in the future. 49 */ 50 #define SNAPSHOT_ATOMIC_SNAPSHOT _IOW(SNAPSHOT_IOC_MAGIC, 3, void *) 51 #define SNAPSHOT_SET_IMAGE_SIZE _IOW(SNAPSHOT_IOC_MAGIC, 6, unsigned long) 52 #define SNAPSHOT_AVAIL_SWAP _IOR(SNAPSHOT_IOC_MAGIC, 7, void *) 53 #define SNAPSHOT_GET_SWAP_PAGE _IOR(SNAPSHOT_IOC_MAGIC, 8, void *) 54 55 56 #define SNAPSHOT_MINOR 231 57 58 static struct snapshot_data { 59 struct snapshot_handle handle; 60 int swap; 61 int mode; 62 char frozen; 63 char ready; 64 char platform_support; 65 } snapshot_state; 66 67 atomic_t snapshot_device_available = ATOMIC_INIT(1); 68 69 static int snapshot_open(struct inode *inode, struct file *filp) 70 { 71 struct snapshot_data *data; 72 int error; 73 74 mutex_lock(&pm_mutex); 75 76 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { 77 error = -EBUSY; 78 goto Unlock; 79 } 80 81 if ((filp->f_flags & O_ACCMODE) == O_RDWR) { 82 atomic_inc(&snapshot_device_available); 83 error = -ENOSYS; 84 goto Unlock; 85 } 86 if(create_basic_memory_bitmaps()) { 87 atomic_inc(&snapshot_device_available); 88 error = -ENOMEM; 89 goto Unlock; 90 } 91 nonseekable_open(inode, filp); 92 data = &snapshot_state; 93 filp->private_data = data; 94 memset(&data->handle, 0, sizeof(struct snapshot_handle)); 95 if ((filp->f_flags & O_ACCMODE) == O_RDONLY) { 96 /* Hibernating. The image device should be accessible. */ 97 data->swap = swsusp_resume_device ? 98 swap_type_of(swsusp_resume_device, 0, NULL) : -1; 99 data->mode = O_RDONLY; 100 error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE); 101 if (error) 102 pm_notifier_call_chain(PM_POST_HIBERNATION); 103 } else { 104 /* 105 * Resuming. We may need to wait for the image device to 106 * appear. 107 */ 108 wait_for_device_probe(); 109 scsi_complete_async_scans(); 110 111 data->swap = -1; 112 data->mode = O_WRONLY; 113 error = pm_notifier_call_chain(PM_RESTORE_PREPARE); 114 if (error) 115 pm_notifier_call_chain(PM_POST_RESTORE); 116 } 117 if (error) 118 atomic_inc(&snapshot_device_available); 119 data->frozen = 0; 120 data->ready = 0; 121 data->platform_support = 0; 122 123 Unlock: 124 mutex_unlock(&pm_mutex); 125 126 return error; 127 } 128 129 static int snapshot_release(struct inode *inode, struct file *filp) 130 { 131 struct snapshot_data *data; 132 133 mutex_lock(&pm_mutex); 134 135 swsusp_free(); 136 free_basic_memory_bitmaps(); 137 data = filp->private_data; 138 free_all_swap_pages(data->swap); 139 if (data->frozen) 140 thaw_processes(); 141 pm_notifier_call_chain(data->mode == O_WRONLY ? 142 PM_POST_HIBERNATION : PM_POST_RESTORE); 143 atomic_inc(&snapshot_device_available); 144 145 mutex_unlock(&pm_mutex); 146 147 return 0; 148 } 149 150 static ssize_t snapshot_read(struct file *filp, char __user *buf, 151 size_t count, loff_t *offp) 152 { 153 struct snapshot_data *data; 154 ssize_t res; 155 156 mutex_lock(&pm_mutex); 157 158 data = filp->private_data; 159 if (!data->ready) { 160 res = -ENODATA; 161 goto Unlock; 162 } 163 res = snapshot_read_next(&data->handle, count); 164 if (res > 0) { 165 if (copy_to_user(buf, data_of(data->handle), res)) 166 res = -EFAULT; 167 else 168 *offp = data->handle.offset; 169 } 170 171 Unlock: 172 mutex_unlock(&pm_mutex); 173 174 return res; 175 } 176 177 static ssize_t snapshot_write(struct file *filp, const char __user *buf, 178 size_t count, loff_t *offp) 179 { 180 struct snapshot_data *data; 181 ssize_t res; 182 183 mutex_lock(&pm_mutex); 184 185 data = filp->private_data; 186 res = snapshot_write_next(&data->handle, count); 187 if (res > 0) { 188 if (copy_from_user(data_of(data->handle), buf, res)) 189 res = -EFAULT; 190 else 191 *offp = data->handle.offset; 192 } 193 194 mutex_unlock(&pm_mutex); 195 196 return res; 197 } 198 199 static long snapshot_ioctl(struct file *filp, unsigned int cmd, 200 unsigned long arg) 201 { 202 int error = 0; 203 struct snapshot_data *data; 204 loff_t size; 205 sector_t offset; 206 207 if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) 208 return -ENOTTY; 209 if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR) 210 return -ENOTTY; 211 if (!capable(CAP_SYS_ADMIN)) 212 return -EPERM; 213 214 if (!mutex_trylock(&pm_mutex)) 215 return -EBUSY; 216 217 data = filp->private_data; 218 219 switch (cmd) { 220 221 case SNAPSHOT_FREEZE: 222 if (data->frozen) 223 break; 224 225 printk("Syncing filesystems ... "); 226 sys_sync(); 227 printk("done.\n"); 228 229 error = usermodehelper_disable(); 230 if (error) 231 break; 232 233 error = freeze_processes(); 234 if (error) { 235 thaw_processes(); 236 usermodehelper_enable(); 237 } 238 if (!error) 239 data->frozen = 1; 240 break; 241 242 case SNAPSHOT_UNFREEZE: 243 if (!data->frozen || data->ready) 244 break; 245 thaw_processes(); 246 usermodehelper_enable(); 247 data->frozen = 0; 248 break; 249 250 case SNAPSHOT_CREATE_IMAGE: 251 case SNAPSHOT_ATOMIC_SNAPSHOT: 252 if (data->mode != O_RDONLY || !data->frozen || data->ready) { 253 error = -EPERM; 254 break; 255 } 256 error = hibernation_snapshot(data->platform_support); 257 if (!error) 258 error = put_user(in_suspend, (int __user *)arg); 259 if (!error) 260 data->ready = 1; 261 break; 262 263 case SNAPSHOT_ATOMIC_RESTORE: 264 snapshot_write_finalize(&data->handle); 265 if (data->mode != O_WRONLY || !data->frozen || 266 !snapshot_image_loaded(&data->handle)) { 267 error = -EPERM; 268 break; 269 } 270 error = hibernation_restore(data->platform_support); 271 break; 272 273 case SNAPSHOT_FREE: 274 swsusp_free(); 275 memset(&data->handle, 0, sizeof(struct snapshot_handle)); 276 data->ready = 0; 277 break; 278 279 case SNAPSHOT_PREF_IMAGE_SIZE: 280 case SNAPSHOT_SET_IMAGE_SIZE: 281 image_size = arg; 282 break; 283 284 case SNAPSHOT_GET_IMAGE_SIZE: 285 if (!data->ready) { 286 error = -ENODATA; 287 break; 288 } 289 size = snapshot_get_image_size(); 290 size <<= PAGE_SHIFT; 291 error = put_user(size, (loff_t __user *)arg); 292 break; 293 294 case SNAPSHOT_AVAIL_SWAP_SIZE: 295 case SNAPSHOT_AVAIL_SWAP: 296 size = count_swap_pages(data->swap, 1); 297 size <<= PAGE_SHIFT; 298 error = put_user(size, (loff_t __user *)arg); 299 break; 300 301 case SNAPSHOT_ALLOC_SWAP_PAGE: 302 case SNAPSHOT_GET_SWAP_PAGE: 303 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { 304 error = -ENODEV; 305 break; 306 } 307 offset = alloc_swapdev_block(data->swap); 308 if (offset) { 309 offset <<= PAGE_SHIFT; 310 error = put_user(offset, (loff_t __user *)arg); 311 } else { 312 error = -ENOSPC; 313 } 314 break; 315 316 case SNAPSHOT_FREE_SWAP_PAGES: 317 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { 318 error = -ENODEV; 319 break; 320 } 321 free_all_swap_pages(data->swap); 322 break; 323 324 case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */ 325 if (!swsusp_swap_in_use()) { 326 /* 327 * User space encodes device types as two-byte values, 328 * so we need to recode them 329 */ 330 if (old_decode_dev(arg)) { 331 data->swap = swap_type_of(old_decode_dev(arg), 332 0, NULL); 333 if (data->swap < 0) 334 error = -ENODEV; 335 } else { 336 data->swap = -1; 337 error = -EINVAL; 338 } 339 } else { 340 error = -EPERM; 341 } 342 break; 343 344 case SNAPSHOT_S2RAM: 345 if (!data->frozen) { 346 error = -EPERM; 347 break; 348 } 349 /* 350 * Tasks are frozen and the notifiers have been called with 351 * PM_HIBERNATION_PREPARE 352 */ 353 error = suspend_devices_and_enter(PM_SUSPEND_MEM); 354 break; 355 356 case SNAPSHOT_PLATFORM_SUPPORT: 357 data->platform_support = !!arg; 358 break; 359 360 case SNAPSHOT_POWER_OFF: 361 if (data->platform_support) 362 error = hibernation_platform_enter(); 363 break; 364 365 case SNAPSHOT_PMOPS: /* This ioctl is deprecated */ 366 error = -EINVAL; 367 368 switch (arg) { 369 370 case PMOPS_PREPARE: 371 data->platform_support = 1; 372 error = 0; 373 break; 374 375 case PMOPS_ENTER: 376 if (data->platform_support) 377 error = hibernation_platform_enter(); 378 break; 379 380 case PMOPS_FINISH: 381 if (data->platform_support) 382 error = 0; 383 break; 384 385 default: 386 printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); 387 388 } 389 break; 390 391 case SNAPSHOT_SET_SWAP_AREA: 392 if (swsusp_swap_in_use()) { 393 error = -EPERM; 394 } else { 395 struct resume_swap_area swap_area; 396 dev_t swdev; 397 398 error = copy_from_user(&swap_area, (void __user *)arg, 399 sizeof(struct resume_swap_area)); 400 if (error) { 401 error = -EFAULT; 402 break; 403 } 404 405 /* 406 * User space encodes device types as two-byte values, 407 * so we need to recode them 408 */ 409 swdev = old_decode_dev(swap_area.dev); 410 if (swdev) { 411 offset = swap_area.offset; 412 data->swap = swap_type_of(swdev, offset, NULL); 413 if (data->swap < 0) 414 error = -ENODEV; 415 } else { 416 data->swap = -1; 417 error = -EINVAL; 418 } 419 } 420 break; 421 422 default: 423 error = -ENOTTY; 424 425 } 426 427 mutex_unlock(&pm_mutex); 428 429 return error; 430 } 431 432 static const struct file_operations snapshot_fops = { 433 .open = snapshot_open, 434 .release = snapshot_release, 435 .read = snapshot_read, 436 .write = snapshot_write, 437 .llseek = no_llseek, 438 .unlocked_ioctl = snapshot_ioctl, 439 }; 440 441 static struct miscdevice snapshot_device = { 442 .minor = SNAPSHOT_MINOR, 443 .name = "snapshot", 444 .fops = &snapshot_fops, 445 }; 446 447 static int __init snapshot_device_init(void) 448 { 449 return misc_register(&snapshot_device); 450 }; 451 452 device_initcall(snapshot_device_init); 453