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/kmod.h> 16 #include <linux/string.h> 17 #include <linux/device.h> 18 #include <linux/miscdevice.h> 19 #include <linux/mm.h> 20 #include <linux/swap.h> 21 #include <linux/swapops.h> 22 #include <linux/pm.h> 23 #include <linux/fs.h> 24 #include <linux/console.h> 25 #include <linux/cpu.h> 26 #include <linux/freezer.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 free_basic_memory_bitmaps(); 119 atomic_inc(&snapshot_device_available); 120 } 121 data->frozen = 0; 122 data->ready = 0; 123 data->platform_support = 0; 124 125 Unlock: 126 mutex_unlock(&pm_mutex); 127 128 return error; 129 } 130 131 static int snapshot_release(struct inode *inode, struct file *filp) 132 { 133 struct snapshot_data *data; 134 135 mutex_lock(&pm_mutex); 136 137 swsusp_free(); 138 free_basic_memory_bitmaps(); 139 data = filp->private_data; 140 free_all_swap_pages(data->swap); 141 if (data->frozen) { 142 pm_restore_gfp_mask(); 143 thaw_processes(); 144 } 145 pm_notifier_call_chain(data->mode == O_RDONLY ? 146 PM_POST_HIBERNATION : PM_POST_RESTORE); 147 atomic_inc(&snapshot_device_available); 148 149 mutex_unlock(&pm_mutex); 150 151 return 0; 152 } 153 154 static ssize_t snapshot_read(struct file *filp, char __user *buf, 155 size_t count, loff_t *offp) 156 { 157 struct snapshot_data *data; 158 ssize_t res; 159 loff_t pg_offp = *offp & ~PAGE_MASK; 160 161 mutex_lock(&pm_mutex); 162 163 data = filp->private_data; 164 if (!data->ready) { 165 res = -ENODATA; 166 goto Unlock; 167 } 168 if (!pg_offp) { /* on page boundary? */ 169 res = snapshot_read_next(&data->handle); 170 if (res <= 0) 171 goto Unlock; 172 } else { 173 res = PAGE_SIZE - pg_offp; 174 } 175 176 res = simple_read_from_buffer(buf, count, &pg_offp, 177 data_of(data->handle), res); 178 if (res > 0) 179 *offp += res; 180 181 Unlock: 182 mutex_unlock(&pm_mutex); 183 184 return res; 185 } 186 187 static ssize_t snapshot_write(struct file *filp, const char __user *buf, 188 size_t count, loff_t *offp) 189 { 190 struct snapshot_data *data; 191 ssize_t res; 192 loff_t pg_offp = *offp & ~PAGE_MASK; 193 194 mutex_lock(&pm_mutex); 195 196 data = filp->private_data; 197 198 if (!pg_offp) { 199 res = snapshot_write_next(&data->handle); 200 if (res <= 0) 201 goto unlock; 202 } else { 203 res = PAGE_SIZE - pg_offp; 204 } 205 206 res = simple_write_to_buffer(data_of(data->handle), res, &pg_offp, 207 buf, count); 208 if (res > 0) 209 *offp += res; 210 unlock: 211 mutex_unlock(&pm_mutex); 212 213 return res; 214 } 215 216 static void snapshot_deprecated_ioctl(unsigned int cmd) 217 { 218 if (printk_ratelimit()) 219 printk(KERN_NOTICE "%pf: ioctl '%.8x' is deprecated and will " 220 "be removed soon, update your suspend-to-disk " 221 "utilities\n", 222 __builtin_return_address(0), cmd); 223 } 224 225 static long snapshot_ioctl(struct file *filp, unsigned int cmd, 226 unsigned long arg) 227 { 228 int error = 0; 229 struct snapshot_data *data; 230 loff_t size; 231 sector_t offset; 232 233 if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC) 234 return -ENOTTY; 235 if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR) 236 return -ENOTTY; 237 if (!capable(CAP_SYS_ADMIN)) 238 return -EPERM; 239 240 if (!mutex_trylock(&pm_mutex)) 241 return -EBUSY; 242 243 data = filp->private_data; 244 245 switch (cmd) { 246 247 case SNAPSHOT_FREEZE: 248 if (data->frozen) 249 break; 250 251 printk("Syncing filesystems ... "); 252 sys_sync(); 253 printk("done.\n"); 254 255 error = usermodehelper_disable(); 256 if (error) 257 break; 258 259 error = freeze_processes(); 260 if (error) { 261 thaw_processes(); 262 usermodehelper_enable(); 263 } 264 if (!error) 265 data->frozen = 1; 266 break; 267 268 case SNAPSHOT_UNFREEZE: 269 if (!data->frozen || data->ready) 270 break; 271 pm_restore_gfp_mask(); 272 thaw_processes(); 273 usermodehelper_enable(); 274 data->frozen = 0; 275 break; 276 277 case SNAPSHOT_ATOMIC_SNAPSHOT: 278 snapshot_deprecated_ioctl(cmd); 279 case SNAPSHOT_CREATE_IMAGE: 280 if (data->mode != O_RDONLY || !data->frozen || data->ready) { 281 error = -EPERM; 282 break; 283 } 284 pm_restore_gfp_mask(); 285 error = hibernation_snapshot(data->platform_support); 286 if (!error) 287 error = put_user(in_suspend, (int __user *)arg); 288 if (!error) 289 data->ready = 1; 290 break; 291 292 case SNAPSHOT_ATOMIC_RESTORE: 293 snapshot_write_finalize(&data->handle); 294 if (data->mode != O_WRONLY || !data->frozen || 295 !snapshot_image_loaded(&data->handle)) { 296 error = -EPERM; 297 break; 298 } 299 error = hibernation_restore(data->platform_support); 300 break; 301 302 case SNAPSHOT_FREE: 303 swsusp_free(); 304 memset(&data->handle, 0, sizeof(struct snapshot_handle)); 305 data->ready = 0; 306 break; 307 308 case SNAPSHOT_SET_IMAGE_SIZE: 309 snapshot_deprecated_ioctl(cmd); 310 case SNAPSHOT_PREF_IMAGE_SIZE: 311 image_size = arg; 312 break; 313 314 case SNAPSHOT_GET_IMAGE_SIZE: 315 if (!data->ready) { 316 error = -ENODATA; 317 break; 318 } 319 size = snapshot_get_image_size(); 320 size <<= PAGE_SHIFT; 321 error = put_user(size, (loff_t __user *)arg); 322 break; 323 324 case SNAPSHOT_AVAIL_SWAP: 325 snapshot_deprecated_ioctl(cmd); 326 case SNAPSHOT_AVAIL_SWAP_SIZE: 327 size = count_swap_pages(data->swap, 1); 328 size <<= PAGE_SHIFT; 329 error = put_user(size, (loff_t __user *)arg); 330 break; 331 332 case SNAPSHOT_GET_SWAP_PAGE: 333 snapshot_deprecated_ioctl(cmd); 334 case SNAPSHOT_ALLOC_SWAP_PAGE: 335 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { 336 error = -ENODEV; 337 break; 338 } 339 offset = alloc_swapdev_block(data->swap); 340 if (offset) { 341 offset <<= PAGE_SHIFT; 342 error = put_user(offset, (loff_t __user *)arg); 343 } else { 344 error = -ENOSPC; 345 } 346 break; 347 348 case SNAPSHOT_FREE_SWAP_PAGES: 349 if (data->swap < 0 || data->swap >= MAX_SWAPFILES) { 350 error = -ENODEV; 351 break; 352 } 353 free_all_swap_pages(data->swap); 354 break; 355 356 case SNAPSHOT_SET_SWAP_FILE: /* This ioctl is deprecated */ 357 snapshot_deprecated_ioctl(cmd); 358 if (!swsusp_swap_in_use()) { 359 /* 360 * User space encodes device types as two-byte values, 361 * so we need to recode them 362 */ 363 if (old_decode_dev(arg)) { 364 data->swap = swap_type_of(old_decode_dev(arg), 365 0, NULL); 366 if (data->swap < 0) 367 error = -ENODEV; 368 } else { 369 data->swap = -1; 370 error = -EINVAL; 371 } 372 } else { 373 error = -EPERM; 374 } 375 break; 376 377 case SNAPSHOT_S2RAM: 378 if (!data->frozen) { 379 error = -EPERM; 380 break; 381 } 382 /* 383 * Tasks are frozen and the notifiers have been called with 384 * PM_HIBERNATION_PREPARE 385 */ 386 error = suspend_devices_and_enter(PM_SUSPEND_MEM); 387 data->ready = 0; 388 break; 389 390 case SNAPSHOT_PLATFORM_SUPPORT: 391 data->platform_support = !!arg; 392 break; 393 394 case SNAPSHOT_POWER_OFF: 395 if (data->platform_support) 396 error = hibernation_platform_enter(); 397 break; 398 399 case SNAPSHOT_PMOPS: /* This ioctl is deprecated */ 400 snapshot_deprecated_ioctl(cmd); 401 error = -EINVAL; 402 403 switch (arg) { 404 405 case PMOPS_PREPARE: 406 data->platform_support = 1; 407 error = 0; 408 break; 409 410 case PMOPS_ENTER: 411 if (data->platform_support) 412 error = hibernation_platform_enter(); 413 break; 414 415 case PMOPS_FINISH: 416 if (data->platform_support) 417 error = 0; 418 break; 419 420 default: 421 printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg); 422 423 } 424 break; 425 426 case SNAPSHOT_SET_SWAP_AREA: 427 if (swsusp_swap_in_use()) { 428 error = -EPERM; 429 } else { 430 struct resume_swap_area swap_area; 431 dev_t swdev; 432 433 error = copy_from_user(&swap_area, (void __user *)arg, 434 sizeof(struct resume_swap_area)); 435 if (error) { 436 error = -EFAULT; 437 break; 438 } 439 440 /* 441 * User space encodes device types as two-byte values, 442 * so we need to recode them 443 */ 444 swdev = new_decode_dev(swap_area.dev); 445 if (swdev) { 446 offset = swap_area.offset; 447 data->swap = swap_type_of(swdev, offset, NULL); 448 if (data->swap < 0) 449 error = -ENODEV; 450 } else { 451 data->swap = -1; 452 error = -EINVAL; 453 } 454 } 455 break; 456 457 default: 458 error = -ENOTTY; 459 460 } 461 462 mutex_unlock(&pm_mutex); 463 464 return error; 465 } 466 467 static const struct file_operations snapshot_fops = { 468 .open = snapshot_open, 469 .release = snapshot_release, 470 .read = snapshot_read, 471 .write = snapshot_write, 472 .llseek = no_llseek, 473 .unlocked_ioctl = snapshot_ioctl, 474 }; 475 476 static struct miscdevice snapshot_device = { 477 .minor = SNAPSHOT_MINOR, 478 .name = "snapshot", 479 .fops = &snapshot_fops, 480 }; 481 482 static int __init snapshot_device_init(void) 483 { 484 return misc_register(&snapshot_device); 485 }; 486 487 device_initcall(snapshot_device_init); 488