xref: /openbsd/sys/sys/hibernate.h (revision 116c1678)
1 /*	$OpenBSD: hibernate.h,v 1.45 2022/01/17 02:54:28 mlarkin Exp $	*/
2 
3 /*
4  * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #ifndef _SYS_HIBERNATE_H_
20 #define _SYS_HIBERNATE_H_
21 
22 #include <sys/types.h>
23 #include <sys/tree.h>
24 #include <lib/libz/zlib.h>
25 #include <machine/vmparam.h>
26 #include <crypto/sha2.h>
27 
28 #define HIB_PHYSSEG_MAX		22
29 
30 #define HIBERNATE_CHUNK_USED 1
31 #define HIBERNATE_CHUNK_CONFLICT 2
32 #define HIBERNATE_CHUNK_PLACED 4
33 
34 /* Magic number used to indicate hibernate signature block */
35 #define HIBERNATE_MAGIC 0x0B5D0B5D
36 
37 /* Page skip operations used during unpack */
38 #define HIB_MOVE 2
39 #define HIB_SKIP 1
40 
41 struct hiballoc_entry;
42 
43 /*
44  * Allocator operates from an arena, that is pre-allocated by the caller.
45  */
46 struct hiballoc_arena {
47 	RBT_HEAD(hiballoc_addr, hiballoc_entry)	hib_addrs;
48 };
49 
50 /*
51  * Describes a zlib compression stream and its associated hiballoc area
52  */
53 struct hibernate_zlib_state {
54         z_stream hib_stream;
55         struct hiballoc_arena hiballoc_arena;
56 };
57 
58 /*
59  * Describes a range of physical memory on the machine
60  */
61 struct hibernate_memory_range {
62 	paddr_t		base;
63 	paddr_t		end;
64 };
65 
66 /*
67  * Describes a hibernate chunk structure, used when splitting the memory
68  * image of the machine into easy-to-manage pieces.
69  */
70 struct hibernate_disk_chunk {
71 	paddr_t		base;		/* Base of chunk */
72 	paddr_t		end;		/* End of chunk */
73 	daddr_t		offset;		/* Abs. disk block locating chunk */
74 	size_t		compressed_size; /* Compressed size on disk */
75 	short		flags;		/* Flags */
76 };
77 
78 #define HIB_INIT	-1
79 #define HIB_DONE	-2
80 #define HIB_R		0
81 #define HIB_W		1
82 typedef	int (*hibio_fn)(dev_t, daddr_t, vaddr_t, size_t, int, void *);
83 
84 /*
85  * Used to store information about the hibernation state of the machine,
86  * such as memory range count and extents, disk sector size, and various
87  * offsets where things are located on disk.
88  */
89 union hibernate_info {
90 	struct {
91 		u_int32_t			magic;
92 		dev_t				dev;
93 		size_t				nranges;
94 		struct hibernate_memory_range	ranges[HIB_PHYSSEG_MAX];
95 		size_t				image_size;
96 		size_t				chunk_ctr;
97 		daddr_t				sig_offset;
98 		daddr_t				chunktable_offset;
99 		daddr_t				image_offset;
100 		paddr_t				piglet_pa;
101 		vaddr_t				piglet_va;
102 		hibio_fn			io_func;
103 		void				*io_page;
104 		u_int8_t			kern_hash[SHA256_DIGEST_LENGTH];
105 #ifndef NO_PROPOLICE
106 		long				guard;
107 #endif /* ! NO_PROPOLICE */
108 		u_int32_t			retguard_ofs;
109 	};
110 
111 	/* XXX - remove restriction to have this union fit in a single block */
112 	char pad[512]; /* Pad to 512 bytes */
113 };
114 
115 void	*hib_alloc(struct hiballoc_arena*, size_t);
116 void	 hib_free(struct hiballoc_arena*, void*);
117 int	 hiballoc_init(struct hiballoc_arena*, void*, size_t len);
118 void	 uvm_pmr_zero_everything(void);
119 void	 uvm_pmr_dirty_everything(void);
120 int	 uvm_pmr_alloc_pig(paddr_t*, psize_t, paddr_t);
121 int	 uvm_pmr_alloc_piglet(vaddr_t*, paddr_t*, vsize_t, paddr_t);
122 void	 uvm_pmr_free_piglet(vaddr_t, vsize_t);
123 int	 uvm_page_rle(paddr_t);
124 void	 uvmpd_hibernate(void);
125 
126 hibio_fn get_hibernate_io_function(dev_t);
127 int	get_hibernate_info(union hibernate_info *, int);
128 
129 int	hibernate_zlib_reset(union hibernate_info *, int);
130 void	*hibernate_zlib_alloc(void *, int, int);
131 void	hibernate_zlib_free(void *, void *);
132 void	hibernate_inflate_region(union hibernate_info *, paddr_t, paddr_t,
133 	    size_t);
134 size_t	hibernate_deflate(union hibernate_info *, paddr_t, size_t *);
135 void	hibernate_process_chunk(union hibernate_info *,
136 	    struct hibernate_disk_chunk *, paddr_t);
137 int	hibernate_inflate_page(int *);
138 
139 int	hibernate_block_io(union hibernate_info *, daddr_t, size_t, vaddr_t, int);
140 int	hibernate_write_signature(union hibernate_info *);
141 int	hibernate_write_chunktable(union hibernate_info *);
142 int	hibernate_write_chunks(union hibernate_info *);
143 int	hibernate_clear_signature(union hibernate_info *);
144 int	hibernate_compare_signature(union hibernate_info *,
145 	    union hibernate_info *);
146 void	hibernate_resume(void);
147 int	hibernate_suspend(void);
148 int	hibernate_read_image(union hibernate_info *);
149 int	hibernate_read_chunks(union hibernate_info *, paddr_t, paddr_t, size_t,
150 	    struct hibernate_disk_chunk *);
151 void	hibernate_unpack_image(union hibernate_info *);
152 void	hibernate_populate_resume_pt(union hibernate_info *, paddr_t, paddr_t);
153 int	hibernate_alloc(void);
154 void	hibernate_free(void);
155 void	hib_getentropy(char **, size_t *);
156 
157 void	hibernate_sort_ranges(union hibernate_info *);
158 void	hibernate_suspend_bufcache(void);
159 void	hibernate_resume_bufcache(void);
160 
161 #endif /* _SYS_HIBERNATE_H_ */
162