1 /*
2  * save.h: HVM support routines for save/restore
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms and conditions of the GNU General Public License,
6  * version 2, as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope it will be useful, but WITHOUT
9  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
11  * more details.
12  *
13  * You should have received a copy of the GNU General Public License along with
14  * this program; If not, see <http://www.gnu.org/licenses/>.
15  */
16 
17 #ifndef __XEN_HVM_SAVE_H__
18 #define __XEN_HVM_SAVE_H__
19 
20 #include <xen/types.h>
21 #include <xen/init.h>
22 #include <public/xen.h>
23 #include <public/hvm/save.h>
24 
25 /* Marshalling and unmarshalling uses a buffer with size and cursor. */
26 typedef struct hvm_domain_context {
27     uint32_t cur;
28     uint32_t size;
29     uint8_t *data;
30 } hvm_domain_context_t;
31 
32 /* Marshalling an entry: check space and fill in the header */
33 int _hvm_init_entry(struct hvm_domain_context *h,
34                     uint16_t tc, uint16_t inst, uint32_t len);
35 
36 /* Marshalling: copy the contents in a type-safe way */
37 void _hvm_write_entry(struct hvm_domain_context *h,
38                       void *src, uint32_t src_len);
39 
40 /* Marshalling: init and copy; evaluates to zero on success */
41 #define hvm_save_entry(_x, _inst, _h, _src) ({                  \
42     int r;                                                      \
43     r = _hvm_init_entry((_h), HVM_SAVE_CODE(_x),                \
44                         (_inst), HVM_SAVE_LENGTH(_x));          \
45     if ( r == 0 )                                               \
46         _hvm_write_entry((_h), (_src), HVM_SAVE_LENGTH(_x));    \
47     r; })
48 
49 /* Unmarshalling: test an entry's size and typecode and record the instance */
50 int _hvm_check_entry(struct hvm_domain_context *h,
51                      uint16_t type, uint32_t len, bool_t strict_length);
52 
53 /* Unmarshalling: copy the contents in a type-safe way */
54 void _hvm_read_entry(struct hvm_domain_context *h,
55                      void *dest, uint32_t dest_len);
56 
57 /*
58  * Unmarshalling: check, then copy. Evaluates to zero on success. This load
59  * function requires the save entry to be the same size as the dest structure.
60  */
61 #define _hvm_load_entry(_x, _h, _dst, _strict) ({                       \
62     int r;                                                              \
63     struct hvm_save_descriptor *desc                                    \
64         = (struct hvm_save_descriptor *)&(_h)->data[(_h)->cur];         \
65     if ( (r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x),                 \
66                HVM_SAVE_LENGTH(_x), (_strict))) == 0 )                  \
67     {                                                                   \
68         _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH(_x));             \
69         if ( HVM_SAVE_HAS_COMPAT(_x) &&                                 \
70              desc->length != HVM_SAVE_LENGTH(_x) )                      \
71             r = HVM_SAVE_FIX_COMPAT(_x, (_dst), desc->length);          \
72     }                                                                   \
73     else if (HVM_SAVE_HAS_COMPAT(_x)                                    \
74              && (r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x),          \
75                        HVM_SAVE_LENGTH_COMPAT(_x), (_strict))) == 0 ) { \
76         _hvm_read_entry((_h), (_dst), HVM_SAVE_LENGTH_COMPAT(_x));      \
77         r = HVM_SAVE_FIX_COMPAT(_x, (_dst), desc->length);              \
78     }                                                                   \
79     r; })
80 
81 #define hvm_load_entry(_x, _h, _dst)            \
82     _hvm_load_entry(_x, _h, _dst, 1)
83 #define hvm_load_entry_zeroextend(_x, _h, _dst) \
84     _hvm_load_entry(_x, _h, _dst, 0)
85 
86 /* Unmarshalling: what is the instance ID of the next entry? */
hvm_load_instance(const struct hvm_domain_context * h)87 static inline unsigned int hvm_load_instance(const struct hvm_domain_context *h)
88 {
89     const struct hvm_save_descriptor *d = (const void *)&h->data[h->cur];
90 
91     return d->instance;
92 }
93 
94 /* Handler types for different types of save-file entry.
95  * The save handler may save multiple instances of a type into the buffer;
96  * the load handler will be called once for each instance found when
97  * restoring.  Both return non-zero on error. */
98 typedef int (*hvm_save_handler) (struct vcpu *v,
99                                  hvm_domain_context_t *h);
100 typedef int (*hvm_load_handler) (struct domain *d,
101                                  hvm_domain_context_t *h);
102 
103 /* Init-time function to declare a pair of handlers for a type,
104  * and the maximum buffer space needed to save this type of state */
105 void hvm_register_savevm(uint16_t typecode,
106                          const char *name,
107                          hvm_save_handler save_state,
108                          hvm_load_handler load_state,
109                          size_t size, int kind);
110 
111 /* The space needed for saving can be per-domain or per-vcpu: */
112 #define HVMSR_PER_DOM  0
113 #define HVMSR_PER_VCPU 1
114 
115 /* Syntactic sugar around that function: specify the max number of
116  * saves, and this calculates the size of buffer needed */
117 #define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load, _num, _k)             \
118 static int __init __hvm_register_##_x##_save_and_restore(void)            \
119 {                                                                         \
120     hvm_register_savevm(HVM_SAVE_CODE(_x),                                \
121                         #_x,                                              \
122                         &_save,                                           \
123                         &_load,                                           \
124                         (_num) * (HVM_SAVE_LENGTH(_x)                     \
125                                   + sizeof (struct hvm_save_descriptor)), \
126                         _k);                                              \
127     return 0;                                                             \
128 }                                                                         \
129 __initcall(__hvm_register_##_x##_save_and_restore);
130 
131 
132 /* Entry points for saving and restoring HVM domain state */
133 size_t hvm_save_size(struct domain *d);
134 int hvm_save(struct domain *d, hvm_domain_context_t *h);
135 int hvm_save_one(struct domain *d, unsigned int typecode, unsigned int instance,
136                  XEN_GUEST_HANDLE_64(uint8) handle, uint64_t *bufsz);
137 int hvm_load(struct domain *d, hvm_domain_context_t *h);
138 
139 /* Arch-specific definitions. */
140 struct hvm_save_header;
141 void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr);
142 int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr);
143 
144 #endif /* __XEN_HVM_SAVE_H__ */
145