user.c (9e8238020c5beba64e7ffafbb7ea0fb02fe68270) user.c (70d932985757fbe978024db313001218e9f8fe5c)
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 */

--- 21 unchanged lines hidden (view full) ---

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;
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 */

--- 21 unchanged lines hidden (view full) ---

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;
38} snapshot_state;
39
39} snapshot_state;
40
40atomic_t snapshot_device_available = ATOMIC_INIT(1);
41int is_hibernate_resume_dev(const struct inode *bd_inode)
42{
43 return hibernation_available() && snapshot_state.bd_inode == bd_inode;
44}
41
42static int snapshot_open(struct inode *inode, struct file *filp)
43{
44 struct snapshot_data *data;
45
46static int snapshot_open(struct inode *inode, struct file *filp)
47{
48 struct snapshot_data *data;
45 int error, nr_calls = 0;
49 int error;
46
47 if (!hibernation_available())
48 return -EPERM;
49
50 lock_system_sleep();
51
50
51 if (!hibernation_available())
52 return -EPERM;
53
54 lock_system_sleep();
55
52 if (!atomic_add_unless(&snapshot_device_available, -1, 0)) {
56 if (!hibernate_acquire()) {
53 error = -EBUSY;
54 goto Unlock;
55 }
56
57 if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
57 error = -EBUSY;
58 goto Unlock;
59 }
60
61 if ((filp->f_flags & O_ACCMODE) == O_RDWR) {
58 atomic_inc(&snapshot_device_available);
62 hibernate_release();
59 error = -ENOSYS;
60 goto Unlock;
61 }
62 nonseekable_open(inode, filp);
63 data = &snapshot_state;
64 filp->private_data = data;
65 memset(&data->handle, 0, sizeof(struct snapshot_handle));
66 if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
67 /* Hibernating. The image device should be accessible. */
68 data->swap = swsusp_resume_device ?
69 swap_type_of(swsusp_resume_device, 0, NULL) : -1;
70 data->mode = O_RDONLY;
71 data->free_bitmaps = false;
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;
72 error = __pm_notifier_call_chain(PM_HIBERNATION_PREPARE, -1, &nr_calls);
73 if (error)
74 __pm_notifier_call_chain(PM_POST_HIBERNATION, --nr_calls, NULL);
76 error = pm_notifier_call_chain_robust(PM_HIBERNATION_PREPARE, PM_POST_HIBERNATION);
75 } else {
76 /*
77 * Resuming. We may need to wait for the image device to
78 * appear.
79 */
80 wait_for_device_probe();
81
82 data->swap = -1;
83 data->mode = O_WRONLY;
77 } else {
78 /*
79 * Resuming. We may need to wait for the image device to
80 * appear.
81 */
82 wait_for_device_probe();
83
84 data->swap = -1;
85 data->mode = O_WRONLY;
84 error = __pm_notifier_call_chain(PM_RESTORE_PREPARE, -1, &nr_calls);
86 error = pm_notifier_call_chain_robust(PM_RESTORE_PREPARE, PM_POST_RESTORE);
85 if (!error) {
86 error = create_basic_memory_bitmaps();
87 data->free_bitmaps = !error;
87 if (!error) {
88 error = create_basic_memory_bitmaps();
89 data->free_bitmaps = !error;
88 } else
89 nr_calls--;
90
91 if (error)
92 __pm_notifier_call_chain(PM_POST_RESTORE, nr_calls, NULL);
90 }
93 }
94 if (error)
91 }
92 if (error)
95 atomic_inc(&snapshot_device_available);
93 hibernate_release();
96
97 data->frozen = false;
98 data->ready = false;
99 data->platform_support = false;
94
95 data->frozen = false;
96 data->ready = false;
97 data->platform_support = false;
98 data->bd_inode = NULL;
100
101 Unlock:
102 unlock_system_sleep();
103
104 return error;
105}
106
107static int snapshot_release(struct inode *inode, struct file *filp)
108{
109 struct snapshot_data *data;
110
111 lock_system_sleep();
112
113 swsusp_free();
114 data = filp->private_data;
99
100 Unlock:
101 unlock_system_sleep();
102
103 return error;
104}
105
106static int snapshot_release(struct inode *inode, struct file *filp)
107{
108 struct snapshot_data *data;
109
110 lock_system_sleep();
111
112 swsusp_free();
113 data = filp->private_data;
114 data->bd_inode = NULL;
115 free_all_swap_pages(data->swap);
116 if (data->frozen) {
117 pm_restore_gfp_mask();
118 free_basic_memory_bitmaps();
119 thaw_processes();
120 } else if (data->free_bitmaps) {
121 free_basic_memory_bitmaps();
122 }
123 pm_notifier_call_chain(data->mode == O_RDONLY ?
124 PM_POST_HIBERNATION : PM_POST_RESTORE);
115 free_all_swap_pages(data->swap);
116 if (data->frozen) {
117 pm_restore_gfp_mask();
118 free_basic_memory_bitmaps();
119 thaw_processes();
120 } else if (data->free_bitmaps) {
121 free_basic_memory_bitmaps();
122 }
123 pm_notifier_call_chain(data->mode == O_RDONLY ?
124 PM_POST_HIBERNATION : PM_POST_RESTORE);
125 atomic_inc(&snapshot_device_available);
125 hibernate_release();
126
127 unlock_system_sleep();
128
129 return 0;
130}
131
132static ssize_t snapshot_read(struct file *filp, char __user *buf,
133 size_t count, loff_t *offp)

--- 65 unchanged lines hidden (view full) ---

199struct compat_resume_swap_area {
200 compat_loff_t offset;
201 u32 dev;
202} __packed;
203
204static int snapshot_set_swap_area(struct snapshot_data *data,
205 void __user *argp)
206{
126
127 unlock_system_sleep();
128
129 return 0;
130}
131
132static ssize_t snapshot_read(struct file *filp, char __user *buf,
133 size_t count, loff_t *offp)

--- 65 unchanged lines hidden (view full) ---

199struct compat_resume_swap_area {
200 compat_loff_t offset;
201 u32 dev;
202} __packed;
203
204static int snapshot_set_swap_area(struct snapshot_data *data,
205 void __user *argp)
206{
207 struct block_device *bdev;
207 sector_t offset;
208 dev_t swdev;
209
210 if (swsusp_swap_in_use())
211 return -EPERM;
212
213 if (in_compat_syscall()) {
214 struct compat_resume_swap_area swap_area;

--- 14 unchanged lines hidden (view full) ---

229 /*
230 * User space encodes device types as two-byte values,
231 * so we need to recode them
232 */
233 if (!swdev) {
234 data->swap = -1;
235 return -EINVAL;
236 }
208 sector_t offset;
209 dev_t swdev;
210
211 if (swsusp_swap_in_use())
212 return -EPERM;
213
214 if (in_compat_syscall()) {
215 struct compat_resume_swap_area swap_area;

--- 14 unchanged lines hidden (view full) ---

230 /*
231 * User space encodes device types as two-byte values,
232 * so we need to recode them
233 */
234 if (!swdev) {
235 data->swap = -1;
236 return -EINVAL;
237 }
237 data->swap = swap_type_of(swdev, offset, NULL);
238 data->swap = swap_type_of(swdev, offset, &bdev);
238 if (data->swap < 0)
239 return -ENODEV;
239 if (data->swap < 0)
240 return -ENODEV;
241
242 data->bd_inode = bdev->bd_inode;
243 bdput(bdev);
240 return 0;
241}
242
243static long snapshot_ioctl(struct file *filp, unsigned int cmd,
244 unsigned long arg)
245{
246 int error = 0;
247 struct snapshot_data *data;

--- 208 unchanged lines hidden ---
244 return 0;
245}
246
247static long snapshot_ioctl(struct file *filp, unsigned int cmd,
248 unsigned long arg)
249{
250 int error = 0;
251 struct snapshot_data *data;

--- 208 unchanged lines hidden ---