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