xref: /linux/kernel/power/user.c (revision b0148a98ec5151fec82064d95f11eb9efbc628ea)
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 
27 #include <asm/uaccess.h>
28 
29 #include "power.h"
30 
31 #define SNAPSHOT_MINOR	231
32 
33 static struct snapshot_data {
34 	struct snapshot_handle handle;
35 	int swap;
36 	struct bitmap_page *bitmap;
37 	int mode;
38 	char frozen;
39 	char ready;
40 } snapshot_state;
41 
42 static atomic_t device_available = ATOMIC_INIT(1);
43 
44 static int snapshot_open(struct inode *inode, struct file *filp)
45 {
46 	struct snapshot_data *data;
47 
48 	if (!atomic_add_unless(&device_available, -1, 0))
49 		return -EBUSY;
50 
51 	if ((filp->f_flags & O_ACCMODE) == O_RDWR)
52 		return -ENOSYS;
53 
54 	nonseekable_open(inode, filp);
55 	data = &snapshot_state;
56 	filp->private_data = data;
57 	memset(&data->handle, 0, sizeof(struct snapshot_handle));
58 	if ((filp->f_flags & O_ACCMODE) == O_RDONLY) {
59 		data->swap = swsusp_resume_device ?
60 			swap_type_of(swsusp_resume_device, 0, NULL) : -1;
61 		data->mode = O_RDONLY;
62 	} else {
63 		data->swap = -1;
64 		data->mode = O_WRONLY;
65 	}
66 	data->bitmap = NULL;
67 	data->frozen = 0;
68 	data->ready = 0;
69 
70 	return 0;
71 }
72 
73 static int snapshot_release(struct inode *inode, struct file *filp)
74 {
75 	struct snapshot_data *data;
76 
77 	swsusp_free();
78 	data = filp->private_data;
79 	free_all_swap_pages(data->swap, data->bitmap);
80 	free_bitmap(data->bitmap);
81 	if (data->frozen) {
82 		mutex_lock(&pm_mutex);
83 		thaw_processes();
84 		enable_nonboot_cpus();
85 		mutex_unlock(&pm_mutex);
86 	}
87 	atomic_inc(&device_available);
88 	return 0;
89 }
90 
91 static ssize_t snapshot_read(struct file *filp, char __user *buf,
92                              size_t count, loff_t *offp)
93 {
94 	struct snapshot_data *data;
95 	ssize_t res;
96 
97 	data = filp->private_data;
98 	res = snapshot_read_next(&data->handle, count);
99 	if (res > 0) {
100 		if (copy_to_user(buf, data_of(data->handle), res))
101 			res = -EFAULT;
102 		else
103 			*offp = data->handle.offset;
104 	}
105 	return res;
106 }
107 
108 static ssize_t snapshot_write(struct file *filp, const char __user *buf,
109                               size_t count, loff_t *offp)
110 {
111 	struct snapshot_data *data;
112 	ssize_t res;
113 
114 	data = filp->private_data;
115 	res = snapshot_write_next(&data->handle, count);
116 	if (res > 0) {
117 		if (copy_from_user(data_of(data->handle), buf, res))
118 			res = -EFAULT;
119 		else
120 			*offp = data->handle.offset;
121 	}
122 	return res;
123 }
124 
125 static int snapshot_ioctl(struct inode *inode, struct file *filp,
126                           unsigned int cmd, unsigned long arg)
127 {
128 	int error = 0;
129 	struct snapshot_data *data;
130 	loff_t avail;
131 	sector_t offset;
132 
133 	if (_IOC_TYPE(cmd) != SNAPSHOT_IOC_MAGIC)
134 		return -ENOTTY;
135 	if (_IOC_NR(cmd) > SNAPSHOT_IOC_MAXNR)
136 		return -ENOTTY;
137 	if (!capable(CAP_SYS_ADMIN))
138 		return -EPERM;
139 
140 	data = filp->private_data;
141 
142 	switch (cmd) {
143 
144 	case SNAPSHOT_FREEZE:
145 		if (data->frozen)
146 			break;
147 		mutex_lock(&pm_mutex);
148 		error = disable_nonboot_cpus();
149 		if (!error) {
150 			error = freeze_processes();
151 			if (error) {
152 				thaw_processes();
153 				enable_nonboot_cpus();
154 				error = -EBUSY;
155 			}
156 		}
157 		mutex_unlock(&pm_mutex);
158 		if (!error)
159 			data->frozen = 1;
160 		break;
161 
162 	case SNAPSHOT_UNFREEZE:
163 		if (!data->frozen)
164 			break;
165 		mutex_lock(&pm_mutex);
166 		thaw_processes();
167 		enable_nonboot_cpus();
168 		mutex_unlock(&pm_mutex);
169 		data->frozen = 0;
170 		break;
171 
172 	case SNAPSHOT_ATOMIC_SNAPSHOT:
173 		if (data->mode != O_RDONLY || !data->frozen  || data->ready) {
174 			error = -EPERM;
175 			break;
176 		}
177 		mutex_lock(&pm_mutex);
178 		/* Free memory before shutting down devices. */
179 		error = swsusp_shrink_memory();
180 		if (!error) {
181 			suspend_console();
182 			error = device_suspend(PMSG_FREEZE);
183 			if (!error) {
184 				in_suspend = 1;
185 				error = swsusp_suspend();
186 				device_resume();
187 			}
188 			resume_console();
189 		}
190 		mutex_unlock(&pm_mutex);
191 		if (!error)
192 			error = put_user(in_suspend, (unsigned int __user *)arg);
193 		if (!error)
194 			data->ready = 1;
195 		break;
196 
197 	case SNAPSHOT_ATOMIC_RESTORE:
198 		snapshot_write_finalize(&data->handle);
199 		if (data->mode != O_WRONLY || !data->frozen ||
200 		    !snapshot_image_loaded(&data->handle)) {
201 			error = -EPERM;
202 			break;
203 		}
204 		mutex_lock(&pm_mutex);
205 		pm_prepare_console();
206 		suspend_console();
207 		error = device_suspend(PMSG_PRETHAW);
208 		if (!error) {
209 			error = swsusp_resume();
210 			device_resume();
211 		}
212 		resume_console();
213 		pm_restore_console();
214 		mutex_unlock(&pm_mutex);
215 		break;
216 
217 	case SNAPSHOT_FREE:
218 		swsusp_free();
219 		memset(&data->handle, 0, sizeof(struct snapshot_handle));
220 		data->ready = 0;
221 		break;
222 
223 	case SNAPSHOT_SET_IMAGE_SIZE:
224 		image_size = arg;
225 		break;
226 
227 	case SNAPSHOT_AVAIL_SWAP:
228 		avail = count_swap_pages(data->swap, 1);
229 		avail <<= PAGE_SHIFT;
230 		error = put_user(avail, (loff_t __user *)arg);
231 		break;
232 
233 	case SNAPSHOT_GET_SWAP_PAGE:
234 		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
235 			error = -ENODEV;
236 			break;
237 		}
238 		if (!data->bitmap) {
239 			data->bitmap = alloc_bitmap(count_swap_pages(data->swap, 0));
240 			if (!data->bitmap) {
241 				error = -ENOMEM;
242 				break;
243 			}
244 		}
245 		offset = alloc_swapdev_block(data->swap, data->bitmap);
246 		if (offset) {
247 			offset <<= PAGE_SHIFT;
248 			error = put_user(offset, (sector_t __user *)arg);
249 		} else {
250 			error = -ENOSPC;
251 		}
252 		break;
253 
254 	case SNAPSHOT_FREE_SWAP_PAGES:
255 		if (data->swap < 0 || data->swap >= MAX_SWAPFILES) {
256 			error = -ENODEV;
257 			break;
258 		}
259 		free_all_swap_pages(data->swap, data->bitmap);
260 		free_bitmap(data->bitmap);
261 		data->bitmap = NULL;
262 		break;
263 
264 	case SNAPSHOT_SET_SWAP_FILE:
265 		if (!data->bitmap) {
266 			/*
267 			 * User space encodes device types as two-byte values,
268 			 * so we need to recode them
269 			 */
270 			if (old_decode_dev(arg)) {
271 				data->swap = swap_type_of(old_decode_dev(arg),
272 							0, NULL);
273 				if (data->swap < 0)
274 					error = -ENODEV;
275 			} else {
276 				data->swap = -1;
277 				error = -EINVAL;
278 			}
279 		} else {
280 			error = -EPERM;
281 		}
282 		break;
283 
284 	case SNAPSHOT_S2RAM:
285 		if (!data->frozen) {
286 			error = -EPERM;
287 			break;
288 		}
289 
290 		if (!mutex_trylock(&pm_mutex)) {
291 			error = -EBUSY;
292 			break;
293 		}
294 
295 		if (pm_ops->prepare) {
296 			error = pm_ops->prepare(PM_SUSPEND_MEM);
297 			if (error)
298 				goto OutS3;
299 		}
300 
301 		/* Put devices to sleep */
302 		suspend_console();
303 		error = device_suspend(PMSG_SUSPEND);
304 		if (error) {
305 			printk(KERN_ERR "Failed to suspend some devices.\n");
306 		} else {
307 			/* Enter S3, system is already frozen */
308 			suspend_enter(PM_SUSPEND_MEM);
309 
310 			/* Wake up devices */
311 			device_resume();
312 		}
313 		resume_console();
314 		if (pm_ops->finish)
315 			pm_ops->finish(PM_SUSPEND_MEM);
316 
317  OutS3:
318 		mutex_unlock(&pm_mutex);
319 		break;
320 
321 	case SNAPSHOT_PMOPS:
322 		switch (arg) {
323 
324 		case PMOPS_PREPARE:
325 			if (pm_ops->prepare) {
326 				error = pm_ops->prepare(PM_SUSPEND_DISK);
327 			}
328 			break;
329 
330 		case PMOPS_ENTER:
331 			kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
332 			error = pm_ops->enter(PM_SUSPEND_DISK);
333 			break;
334 
335 		case PMOPS_FINISH:
336 			if (pm_ops && pm_ops->finish) {
337 				pm_ops->finish(PM_SUSPEND_DISK);
338 			}
339 			break;
340 
341 		default:
342 			printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);
343 			error = -EINVAL;
344 
345 		}
346 		break;
347 
348 	case SNAPSHOT_SET_SWAP_AREA:
349 		if (data->bitmap) {
350 			error = -EPERM;
351 		} else {
352 			struct resume_swap_area swap_area;
353 			dev_t swdev;
354 
355 			error = copy_from_user(&swap_area, (void __user *)arg,
356 					sizeof(struct resume_swap_area));
357 			if (error) {
358 				error = -EFAULT;
359 				break;
360 			}
361 
362 			/*
363 			 * User space encodes device types as two-byte values,
364 			 * so we need to recode them
365 			 */
366 			swdev = old_decode_dev(swap_area.dev);
367 			if (swdev) {
368 				offset = swap_area.offset;
369 				data->swap = swap_type_of(swdev, offset, NULL);
370 				if (data->swap < 0)
371 					error = -ENODEV;
372 			} else {
373 				data->swap = -1;
374 				error = -EINVAL;
375 			}
376 		}
377 		break;
378 
379 	default:
380 		error = -ENOTTY;
381 
382 	}
383 
384 	return error;
385 }
386 
387 static const struct file_operations snapshot_fops = {
388 	.open = snapshot_open,
389 	.release = snapshot_release,
390 	.read = snapshot_read,
391 	.write = snapshot_write,
392 	.llseek = no_llseek,
393 	.ioctl = snapshot_ioctl,
394 };
395 
396 static struct miscdevice snapshot_device = {
397 	.minor = SNAPSHOT_MINOR,
398 	.name = "snapshot",
399 	.fops = &snapshot_fops,
400 };
401 
402 static int __init snapshot_device_init(void)
403 {
404 	return misc_register(&snapshot_device);
405 };
406 
407 device_initcall(snapshot_device_init);
408