debuggers.hg

view xen/include/xen/hvm/save.h @ 16381:c0bdfda5183d

hvm: Clean up buf_ioreq handling.
Also, disable stdvga caching on hvm save/restore, as the shadow vga
state is not preserved.
Signed-off-by: Keir Fraser <keir@xensource.com>
author Keir Fraser <keir@xensource.com>
date Thu Nov 08 14:50:01 2007 +0000 (2007-11-08)
parents 9ea5f4c1feb5
children 615ee2933137
line source
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, write to the Free Software Foundation, Inc., 59 Temple
15 * Place - Suite 330, Boston, MA 02111-1307 USA.
16 */
18 #ifndef __XEN_HVM_SAVE_H__
19 #define __XEN_HVM_SAVE_H__
21 #include <public/hvm/save.h>
22 #include <asm/types.h>
24 /* Marshalling and unmarshalling uses a buffer with size and cursor. */
25 typedef struct hvm_domain_context {
26 uint32_t cur;
27 uint32_t size;
28 uint8_t *data;
29 } hvm_domain_context_t;
31 /* Marshalling an entry: check space and fill in the header */
32 static inline int _hvm_init_entry(struct hvm_domain_context *h,
33 uint16_t tc, uint16_t inst, uint32_t len)
34 {
35 struct hvm_save_descriptor *d
36 = (struct hvm_save_descriptor *)&h->data[h->cur];
37 if ( h->size - h->cur < len + sizeof (*d) )
38 {
39 gdprintk(XENLOG_WARNING,
40 "HVM save: no room for %"PRIu32" + %u bytes "
41 "for typecode %"PRIu16"\n",
42 len, (unsigned) sizeof (*d), tc);
43 return -1;
44 }
45 d->typecode = tc;
46 d->instance = inst;
47 d->length = len;
48 h->cur += sizeof (*d);
49 return 0;
50 }
52 /* Marshalling: copy the contents in a type-safe way */
53 #define _hvm_write_entry(_x, _h, _src) do { \
54 *(HVM_SAVE_TYPE(_x) *)(&(_h)->data[(_h)->cur]) = *(_src); \
55 (_h)->cur += HVM_SAVE_LENGTH(_x); \
56 } while (0)
58 /* Marshalling: init and copy; evaluates to zero on success */
59 #define hvm_save_entry(_x, _inst, _h, _src) ({ \
60 int r; \
61 r = _hvm_init_entry((_h), HVM_SAVE_CODE(_x), \
62 (_inst), HVM_SAVE_LENGTH(_x)); \
63 if ( r == 0 ) \
64 _hvm_write_entry(_x, (_h), (_src)); \
65 r; })
67 /* Unmarshalling: test an entry's size and typecode and record the instance */
68 static inline int _hvm_check_entry(struct hvm_domain_context *h,
69 uint16_t type, uint32_t len)
70 {
71 struct hvm_save_descriptor *d
72 = (struct hvm_save_descriptor *)&h->data[h->cur];
73 if ( len + sizeof (*d) > h->size - h->cur)
74 {
75 gdprintk(XENLOG_WARNING,
76 "HVM restore: not enough data left to read %u bytes "
77 "for type %u\n", len, type);
78 return -1;
79 }
80 if ( type != d->typecode || len != d->length )
81 {
82 gdprintk(XENLOG_WARNING,
83 "HVM restore mismatch: expected type %u length %u, "
84 "saw type %u length %u\n", type, len, d->typecode, d->length);
85 return -1;
86 }
87 h->cur += sizeof (*d);
88 return 0;
89 }
91 /* Unmarshalling: copy the contents in a type-safe way */
92 #define _hvm_read_entry(_x, _h, _dst) do { \
93 *(_dst) = *(HVM_SAVE_TYPE(_x) *) (&(_h)->data[(_h)->cur]); \
94 (_h)->cur += HVM_SAVE_LENGTH(_x); \
95 } while (0)
97 /* Unmarshalling: check, then copy. Evaluates to zero on success. */
98 #define hvm_load_entry(_x, _h, _dst) ({ \
99 int r; \
100 r = _hvm_check_entry((_h), HVM_SAVE_CODE(_x), HVM_SAVE_LENGTH(_x)); \
101 if ( r == 0 ) \
102 _hvm_read_entry(_x, (_h), (_dst)); \
103 r; })
105 /* Unmarshalling: what is the instance ID of the next entry? */
106 static inline uint16_t hvm_load_instance(struct hvm_domain_context *h)
107 {
108 struct hvm_save_descriptor *d
109 = (struct hvm_save_descriptor *)&h->data[h->cur];
110 return d->instance;
111 }
113 /* Handler types for different types of save-file entry.
114 * The save handler may save multiple instances of a type into the buffer;
115 * the load handler will be called once for each instance found when
116 * restoring. Both return non-zero on error. */
117 typedef int (*hvm_save_handler) (struct domain *d,
118 hvm_domain_context_t *h);
119 typedef int (*hvm_load_handler) (struct domain *d,
120 hvm_domain_context_t *h);
122 /* Init-time function to declare a pair of handlers for a type,
123 * and the maximum buffer space needed to save this type of state */
124 void hvm_register_savevm(uint16_t typecode,
125 const char *name,
126 hvm_save_handler save_state,
127 hvm_load_handler load_state,
128 size_t size, int kind);
130 /* The space needed for saving can be per-domain or per-vcpu: */
131 #define HVMSR_PER_DOM 0
132 #define HVMSR_PER_VCPU 1
134 /* Syntactic sugar around that function: specify the max number of
135 * saves, and this calculates the size of buffer needed */
136 #define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load, _num, _k) \
137 static int __hvm_register_##_x##_save_and_restore(void) \
138 { \
139 hvm_register_savevm(HVM_SAVE_CODE(_x), \
140 #_x, \
141 &_save, \
142 &_load, \
143 (_num) * (HVM_SAVE_LENGTH(_x) \
144 + sizeof (struct hvm_save_descriptor)), \
145 _k); \
146 return 0; \
147 } \
148 __initcall(__hvm_register_##_x##_save_and_restore);
151 /* Entry points for saving and restoring HVM domain state */
152 size_t hvm_save_size(struct domain *d);
153 int hvm_save(struct domain *d, hvm_domain_context_t *h);
154 int hvm_load(struct domain *d, hvm_domain_context_t *h);
156 /* Arch-specific definitions. */
157 struct hvm_save_header;
158 void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr);
159 int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr);
161 #endif /* __XEN_HVM_SAVE_H__ */