xref: /openbmc/linux/kernel/power/user.c (revision 15ad7cdcfd76450d4beebc789ec646664238184d)
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) : -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), 0);
272 				if (data->swap < 0)
273 					error = -ENODEV;
274 			} else {
275 				data->swap = -1;
276 				error = -EINVAL;
277 			}
278 		} else {
279 			error = -EPERM;
280 		}
281 		break;
282 
283 	case SNAPSHOT_S2RAM:
284 		if (!data->frozen) {
285 			error = -EPERM;
286 			break;
287 		}
288 
289 		if (!mutex_trylock(&pm_mutex)) {
290 			error = -EBUSY;
291 			break;
292 		}
293 
294 		if (pm_ops->prepare) {
295 			error = pm_ops->prepare(PM_SUSPEND_MEM);
296 			if (error)
297 				goto OutS3;
298 		}
299 
300 		/* Put devices to sleep */
301 		suspend_console();
302 		error = device_suspend(PMSG_SUSPEND);
303 		if (error) {
304 			printk(KERN_ERR "Failed to suspend some devices.\n");
305 		} else {
306 			/* Enter S3, system is already frozen */
307 			suspend_enter(PM_SUSPEND_MEM);
308 
309 			/* Wake up devices */
310 			device_resume();
311 		}
312 		resume_console();
313 		if (pm_ops->finish)
314 			pm_ops->finish(PM_SUSPEND_MEM);
315 
316  OutS3:
317 		mutex_unlock(&pm_mutex);
318 		break;
319 
320 	case SNAPSHOT_PMOPS:
321 		switch (arg) {
322 
323 		case PMOPS_PREPARE:
324 			if (pm_ops->prepare) {
325 				error = pm_ops->prepare(PM_SUSPEND_DISK);
326 			}
327 			break;
328 
329 		case PMOPS_ENTER:
330 			kernel_shutdown_prepare(SYSTEM_SUSPEND_DISK);
331 			error = pm_ops->enter(PM_SUSPEND_DISK);
332 			break;
333 
334 		case PMOPS_FINISH:
335 			if (pm_ops && pm_ops->finish) {
336 				pm_ops->finish(PM_SUSPEND_DISK);
337 			}
338 			break;
339 
340 		default:
341 			printk(KERN_ERR "SNAPSHOT_PMOPS: invalid argument %ld\n", arg);
342 			error = -EINVAL;
343 
344 		}
345 		break;
346 
347 	case SNAPSHOT_SET_SWAP_AREA:
348 		if (data->bitmap) {
349 			error = -EPERM;
350 		} else {
351 			struct resume_swap_area swap_area;
352 			dev_t swdev;
353 
354 			error = copy_from_user(&swap_area, (void __user *)arg,
355 					sizeof(struct resume_swap_area));
356 			if (error) {
357 				error = -EFAULT;
358 				break;
359 			}
360 
361 			/*
362 			 * User space encodes device types as two-byte values,
363 			 * so we need to recode them
364 			 */
365 			swdev = old_decode_dev(swap_area.dev);
366 			if (swdev) {
367 				offset = swap_area.offset;
368 				data->swap = swap_type_of(swdev, offset);
369 				if (data->swap < 0)
370 					error = -ENODEV;
371 			} else {
372 				data->swap = -1;
373 				error = -EINVAL;
374 			}
375 		}
376 		break;
377 
378 	default:
379 		error = -ENOTTY;
380 
381 	}
382 
383 	return error;
384 }
385 
386 static const struct file_operations snapshot_fops = {
387 	.open = snapshot_open,
388 	.release = snapshot_release,
389 	.read = snapshot_read,
390 	.write = snapshot_write,
391 	.llseek = no_llseek,
392 	.ioctl = snapshot_ioctl,
393 };
394 
395 static struct miscdevice snapshot_device = {
396 	.minor = SNAPSHOT_MINOR,
397 	.name = "snapshot",
398 	.fops = &snapshot_fops,
399 };
400 
401 static int __init snapshot_device_init(void)
402 {
403 	return misc_register(&snapshot_device);
404 };
405 
406 device_initcall(snapshot_device_init);
407