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