1/* $OpenBSD: hibernate.h,v 1.51 2025/07/05 09:24:37 jsg 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 <crypto/sha2.h>
26
27#define HIB_PHYSSEG_MAX 22
28
29#define HIBERNATE_CHUNK_USED 1
30#define HIBERNATE_CHUNK_CONFLICT 2
31#define HIBERNATE_CHUNK_PLACED 4
32
33/* Magic number used to indicate hibernate signature block */
34#define HIBERNATE_MAGIC 0x0B5D0B5D
35
36/* Page skip operations used during unpack */
37#define HIB_MOVE 2
38#define HIB_SKIP 1
39
40struct hiballoc_entry;
41
42/*
43 * Allocator operates from an arena, that is pre-allocated by the caller.
44 */
45struct hiballoc_arena {
46 RBT_HEAD(hiballoc_addr, hiballoc_entry) hib_addrs;
47};
48
49/*
50 * Describes a zlib compression stream and its associated hiballoc area
51 */
52struct hibernate_zlib_state {
53 z_stream hib_stream;
54 struct hiballoc_arena hiballoc_arena;
55};
56
57/*
58 * Describes a range of physical memory on the machine
59 */
60struct hibernate_memory_range {
61 paddr_t base;
62 paddr_t end;
63};
64
65/*
66 * Describes a hibernate chunk structure, used when splitting the memory
67 * image of the machine into easy-to-manage pieces.
68 */
69struct hibernate_disk_chunk {
70 paddr_t base; /* Base of chunk */
71 paddr_t end; /* End of chunk */
72 daddr_t offset; /* Abs. disk block locating chunk */
73 size_t compressed_size; /* Compressed size on disk */
74 short flags; /* Flags */
75};
76
77#define HIB_INIT -1
78#define HIB_DONE -2
79#define HIB_R 0
80#define HIB_W 1
81typedef int (*hibio_fn)(dev_t, daddr_t, vaddr_t, size_t, int, void *);
82
83/*
84 * Used to store information about the hibernation state of the machine,
85 * such as memory range count and extents, disk sector size, and various
86 * offsets where things are located on disk.
87 */
88union hibernate_info {
89 struct {
90 u_int32_t magic;
91 dev_t dev;
92 size_t nranges;
93 struct hibernate_memory_range ranges[HIB_PHYSSEG_MAX];
94 size_t image_size;
95 size_t chunk_ctr;
96 daddr_t sig_offset;
97 daddr_t chunktable_offset;
98 daddr_t image_offset;
99 paddr_t piglet_pa;
100 vaddr_t piglet_va;
101 hibio_fn io_func;
102 void *io_page;
103 u_int8_t kern_hash[SHA256_DIGEST_LENGTH];
104#ifndef NO_PROPOLICE
105 long guard;
106#endif /* ! NO_PROPOLICE */
107 u_int32_t retguard_ofs;
108 u_int32_t sec_size;
109 };
110
111 /* XXX - remove restriction to have the struct fit in a single block */
112 char pad[4096]; /* Pad to largest allowable disk sector size in bytes */
113};
114
115void *hib_alloc(struct hiballoc_arena*, size_t);
116void hib_free(struct hiballoc_arena*, void*);
117int hiballoc_init(struct hiballoc_arena*, void*, size_t len);
118void uvm_pmr_dirty_everything(void);
119int uvm_pmr_alloc_pig(paddr_t*, psize_t, paddr_t);
120int uvm_pmr_alloc_piglet(vaddr_t*, paddr_t*, vsize_t, paddr_t);
121int uvm_page_rle(paddr_t);
122void uvmpd_hibernate(void);
123
124hibio_fn get_hibernate_io_function(dev_t);
125int get_hibernate_info(union hibernate_info *, int);
126
127int hibernate_zlib_reset(union hibernate_info *, int);
128void *hibernate_zlib_alloc(void *, int, int);
129void hibernate_zlib_free(void *, void *);
130void hibernate_inflate_region(union hibernate_info *, paddr_t, paddr_t,
131 size_t);
132size_t hibernate_deflate(union hibernate_info *, paddr_t, size_t *);
133void hibernate_process_chunk(union hibernate_info *,
134 struct hibernate_disk_chunk *, paddr_t);
135int hibernate_inflate_page(int *);
136
137int hibernate_block_io(union hibernate_info *, daddr_t, size_t, vaddr_t, int);
138int hibernate_write_signature(union hibernate_info *);
139int hibernate_write_chunktable(union hibernate_info *);
140int hibernate_write_chunks(union hibernate_info *);
141int hibernate_clear_signature(union hibernate_info *);
142int hibernate_compare_signature(union hibernate_info *,
143 union hibernate_info *);
144void hibernate_resume(void);
145int hibernate_suspend(void);
146int hibernate_read_image(union hibernate_info *);
147int hibernate_read_chunks(union hibernate_info *, paddr_t, paddr_t, size_t,
148 struct hibernate_disk_chunk *);
149void hibernate_unpack_image(union hibernate_info *);
150void hibernate_populate_resume_pt(union hibernate_info *, paddr_t, paddr_t);
151int hibernate_alloc(void);
152void hibernate_free(void);
153void hib_getentropy(char **, size_t *);
154
155int hibernate_write(union hibernate_info *, daddr_t, vaddr_t, size_t, int);
156void hibernate_sort_ranges(union hibernate_info *);
157void hibernate_suspend_bufcache(void);
158void hibernate_resume_bufcache(void);
159
160void preallocate_hibernate_memory(void);
161
162#endif /* _SYS_HIBERNATE_H_ */