1 /*
2  * hvm/save.c: Save and restore HVM guest's emulated hardware state.
3  *
4  * Copyright (c) 2004, Intel Corporation.
5  * Copyright (c) 2007, XenSource Inc.
6  * Copyright (c) 2007, Isaku Yamahata <yamahata at valinux co jp>
7  *                     VA Linux Systems Japan K.K.
8  *                     split x86 specific part
9  *
10  * This program is free software; you can redistribute it and/or modify it
11  * under the terms and conditions of the GNU General Public License,
12  * version 2, as published by the Free Software Foundation.
13  *
14  * This program is distributed in the hope it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17  * more details.
18  *
19  * You should have received a copy of the GNU General Public License along with
20  * this program; If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <xen/guest_access.h>
24 #include <xen/version.h>
25 
26 #include <asm/hvm/support.h>
27 
28 #include <public/hvm/save.h>
29 
arch_hvm_save(struct domain * d,struct hvm_save_header * hdr)30 void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr)
31 {
32     uint32_t eax, ebx, ecx, edx;
33 
34     /* Save some CPUID bits */
35     cpuid(1, &eax, &ebx, &ecx, &edx);
36     hdr->cpuid = eax;
37 
38     /* Save guest's preferred TSC. */
39     hdr->gtsc_khz = d->arch.tsc_khz;
40 
41     /* Time when saving started */
42     d->arch.hvm.sync_tsc = rdtsc();
43 }
44 
arch_hvm_load(struct domain * d,struct hvm_save_header * hdr)45 int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr)
46 {
47     uint32_t eax, ebx, ecx, edx;
48 
49     if ( hdr->magic != HVM_FILE_MAGIC )
50     {
51         printk(XENLOG_G_ERR "HVM%d restore: bad magic number %#"PRIx32"\n",
52                d->domain_id, hdr->magic);
53         return -1;
54     }
55 
56     if ( hdr->version != HVM_FILE_VERSION )
57     {
58         printk(XENLOG_G_ERR "HVM%d restore: unsupported version %u\n",
59                d->domain_id, hdr->version);
60         return -1;
61     }
62 
63     cpuid(1, &eax, &ebx, &ecx, &edx);
64     /* CPUs ought to match but with feature-masking they might not */
65     if ( (hdr->cpuid & ~0x0fUL) != (eax & ~0x0fUL) )
66         printk(XENLOG_G_INFO "HVM%d restore: VM saved on one CPU "
67                "(%#"PRIx32") and restored on another (%#"PRIx32").\n",
68                d->domain_id, hdr->cpuid, eax);
69 
70     /* Restore guest's preferred TSC frequency. */
71     if ( hdr->gtsc_khz )
72         d->arch.tsc_khz = hdr->gtsc_khz;
73     if ( d->arch.vtsc )
74         hvm_set_rdtsc_exiting(d, 1);
75 
76     /* Time when restore started  */
77     d->arch.hvm.sync_tsc = rdtsc();
78 
79     /* VGA state is not saved/restored, so we nobble the cache. */
80     d->arch.hvm.stdvga.cache = STDVGA_CACHE_DISABLED;
81 
82     return 0;
83 }
84 
85 /* List of handlers for various HVM save and restore types */
86 static struct {
87     hvm_save_handler save;
88     hvm_load_handler load;
89     const char *name;
90     size_t size;
91     int kind;
92 } hvm_sr_handlers[HVM_SAVE_CODE_MAX + 1];
93 
94 /* Init-time function to add entries to that list */
hvm_register_savevm(uint16_t typecode,const char * name,hvm_save_handler save_state,hvm_load_handler load_state,size_t size,int kind)95 void __init hvm_register_savevm(uint16_t typecode,
96                                 const char *name,
97                                 hvm_save_handler save_state,
98                                 hvm_load_handler load_state,
99                                 size_t size, int kind)
100 {
101     ASSERT(typecode <= HVM_SAVE_CODE_MAX);
102     ASSERT(hvm_sr_handlers[typecode].save == NULL);
103     ASSERT(hvm_sr_handlers[typecode].load == NULL);
104     hvm_sr_handlers[typecode].save = save_state;
105     hvm_sr_handlers[typecode].load = load_state;
106     hvm_sr_handlers[typecode].name = name;
107     hvm_sr_handlers[typecode].size = size;
108     hvm_sr_handlers[typecode].kind = kind;
109 }
110 
hvm_save_size(struct domain * d)111 size_t hvm_save_size(struct domain *d)
112 {
113     struct vcpu *v;
114     size_t sz;
115     int i;
116 
117     /* Basic overhead for header and footer */
118     sz = (2 * sizeof (struct hvm_save_descriptor)) + HVM_SAVE_LENGTH(HEADER);
119 
120     /* Plus space for each thing we will be saving */
121     for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ )
122         if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU )
123             for_each_vcpu(d, v)
124                 sz += hvm_sr_handlers[i].size;
125         else
126             sz += hvm_sr_handlers[i].size;
127 
128     return sz;
129 }
130 
131 /*
132  * Extract a single instance of a save record, by marshalling all records of
133  * that type and copying out the one we need.
134  */
hvm_save_one(struct domain * d,unsigned int typecode,unsigned int instance,XEN_GUEST_HANDLE_64 (uint8)handle,uint64_t * bufsz)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 {
138     int rv;
139     hvm_domain_context_t ctxt = { };
140     const struct hvm_save_descriptor *desc;
141     struct vcpu *v;
142 
143     if ( d->is_dying ||
144          typecode > HVM_SAVE_CODE_MAX ||
145          hvm_sr_handlers[typecode].size < sizeof(*desc) ||
146          !hvm_sr_handlers[typecode].save )
147         return -EINVAL;
148 
149     if ( hvm_sr_handlers[typecode].kind != HVMSR_PER_VCPU )
150         v = d->vcpu[0];
151     else if ( instance >= d->max_vcpus || !d->vcpu[instance] )
152         return -ENOENT;
153     else
154         v = d->vcpu[instance];
155     ctxt.size = hvm_sr_handlers[typecode].size;
156     ctxt.data = xmalloc_bytes(ctxt.size);
157     if ( !ctxt.data )
158         return -ENOMEM;
159 
160     if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU )
161         vcpu_pause(v);
162     else
163         domain_pause(d);
164 
165     if ( (rv = hvm_sr_handlers[typecode].save(v, &ctxt)) != 0 )
166         printk(XENLOG_G_ERR "HVM%d save: failed to save type %"PRIu16" (%d)\n",
167                d->domain_id, typecode, rv);
168     else if ( (rv = hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU ?
169                -ENODATA : -ENOENT), ctxt.cur >= sizeof(*desc) )
170     {
171         uint32_t off;
172 
173         for ( off = 0; off <= (ctxt.cur - sizeof(*desc)); off += desc->length )
174         {
175             desc = (void *)(ctxt.data + off);
176             /* Move past header */
177             off += sizeof(*desc);
178             if ( ctxt.cur < desc->length ||
179                  off > ctxt.cur - desc->length )
180                 break;
181             if ( instance == desc->instance )
182             {
183                 rv = 0;
184                 if ( guest_handle_is_null(handle) )
185                     *bufsz = desc->length;
186                 else if ( *bufsz < desc->length )
187                     rv = -ENOBUFS;
188                 else if ( copy_to_guest(handle, ctxt.data + off, desc->length) )
189                     rv = -EFAULT;
190                 else
191                     *bufsz = desc->length;
192                 break;
193             }
194         }
195     }
196 
197     if ( hvm_sr_handlers[typecode].kind == HVMSR_PER_VCPU )
198         vcpu_unpause(v);
199     else
200         domain_unpause(d);
201 
202     xfree(ctxt.data);
203     return rv;
204 }
205 
hvm_save(struct domain * d,hvm_domain_context_t * h)206 int hvm_save(struct domain *d, hvm_domain_context_t *h)
207 {
208     char *c;
209     struct hvm_save_header hdr;
210     struct hvm_save_end end;
211     unsigned int i;
212 
213     if ( d->is_dying )
214         return -EINVAL;
215 
216     hdr.magic = HVM_FILE_MAGIC;
217     hdr.version = HVM_FILE_VERSION;
218 
219     /* Save xen changeset */
220     c = strrchr(xen_changeset(), ':');
221     if ( c )
222         hdr.changeset = simple_strtoll(c, NULL, 16);
223     else
224         hdr.changeset = -1ULL; /* Unknown */
225 
226     arch_hvm_save(d, &hdr);
227 
228     if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 )
229     {
230         printk(XENLOG_G_ERR "HVM%d save: failed to write header\n",
231                d->domain_id);
232         return -EFAULT;
233     }
234 
235     /* Save all available kinds of state */
236     for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ )
237     {
238         hvm_save_handler handler = hvm_sr_handlers[i].save;
239 
240         if ( !handler )
241             continue;
242 
243         if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU )
244         {
245             struct vcpu *v;
246 
247             for_each_vcpu ( d, v )
248             {
249                 printk(XENLOG_G_INFO "HVM %pv save: %s\n",
250                        v, hvm_sr_handlers[i].name);
251                 if ( handler(v, h) != 0 )
252                 {
253                     printk(XENLOG_G_ERR
254                            "HVM %pv save: failed to save type %"PRIu16"\n",
255                            v, i);
256                     return -ENODATA;
257                 }
258             }
259         }
260         else
261         {
262             printk(XENLOG_G_INFO "HVM d%d save: %s\n",
263                    d->domain_id, hvm_sr_handlers[i].name);
264             if ( handler(d->vcpu[0], h) != 0 )
265             {
266                 printk(XENLOG_G_ERR
267                        "HVM d%d save: failed to save type %"PRIu16"\n",
268                        d->domain_id, i);
269                 return -ENODATA;
270             }
271         }
272     }
273 
274     /* Save an end-of-file marker */
275     if ( hvm_save_entry(END, 0, h, &end) != 0 )
276     {
277         /* Run out of data */
278         printk(XENLOG_G_ERR "HVM%d save: no room for end marker\n",
279                d->domain_id);
280         return -EFAULT;
281     }
282 
283     /* Save macros should not have let us overrun */
284     ASSERT(h->cur <= h->size);
285     return 0;
286 }
287 
hvm_load(struct domain * d,hvm_domain_context_t * h)288 int hvm_load(struct domain *d, hvm_domain_context_t *h)
289 {
290     struct hvm_save_header hdr;
291     struct hvm_save_descriptor *desc;
292     hvm_load_handler handler;
293     struct vcpu *v;
294 
295     if ( d->is_dying )
296         return -EINVAL;
297 
298     /* Read the save header, which must be first */
299     if ( hvm_load_entry(HEADER, h, &hdr) != 0 )
300         return -1;
301 
302     if ( arch_hvm_load(d, &hdr) )
303         return -1;
304 
305     /* Down all the vcpus: we only re-enable the ones that had state saved. */
306     for_each_vcpu(d, v)
307         if ( !test_and_set_bit(_VPF_down, &v->pause_flags) )
308             vcpu_sleep_nosync(v);
309 
310     for ( ; ; )
311     {
312         if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) )
313         {
314             /* Run out of data */
315             printk(XENLOG_G_ERR
316                    "HVM%d restore: save did not end with a null entry\n",
317                    d->domain_id);
318             return -1;
319         }
320 
321         /* Read the typecode of the next entry  and check for the end-marker */
322         desc = (struct hvm_save_descriptor *)(&h->data[h->cur]);
323         if ( desc->typecode == 0 )
324             return 0;
325 
326         /* Find the handler for this entry */
327         if ( (desc->typecode > HVM_SAVE_CODE_MAX) ||
328              ((handler = hvm_sr_handlers[desc->typecode].load) == NULL) )
329         {
330             printk(XENLOG_G_ERR "HVM%d restore: unknown entry typecode %u\n",
331                    d->domain_id, desc->typecode);
332             return -1;
333         }
334 
335         /* Load the entry */
336         printk(XENLOG_G_INFO "HVM%d restore: %s %"PRIu16"\n", d->domain_id,
337                hvm_sr_handlers[desc->typecode].name, desc->instance);
338         if ( handler(d, h) != 0 )
339         {
340             printk(XENLOG_G_ERR "HVM%d restore: failed to load entry %u/%u\n",
341                    d->domain_id, desc->typecode, desc->instance);
342             return -1;
343         }
344     }
345 
346     /* Not reached */
347 }
348 
_hvm_init_entry(struct hvm_domain_context * h,uint16_t tc,uint16_t inst,uint32_t len)349 int _hvm_init_entry(struct hvm_domain_context *h, uint16_t tc, uint16_t inst,
350                     uint32_t len)
351 {
352     struct hvm_save_descriptor *d
353         = (struct hvm_save_descriptor *)&h->data[h->cur];
354 
355     if ( h->size - h->cur < len + sizeof (*d) )
356     {
357         printk(XENLOG_G_WARNING "HVM save: no room for"
358                " %"PRIu32" + %zu bytes for typecode %"PRIu16"\n",
359                len, sizeof(*d), tc);
360         return -1;
361     }
362 
363     d->typecode = tc;
364     d->instance = inst;
365     d->length = len;
366     h->cur += sizeof(*d);
367 
368     return 0;
369 }
370 
_hvm_write_entry(struct hvm_domain_context * h,void * src,uint32_t src_len)371 void _hvm_write_entry(struct hvm_domain_context *h, void *src,
372                       uint32_t src_len)
373 {
374     memcpy(&h->data[h->cur], src, src_len);
375     h->cur += src_len;
376 }
377 
_hvm_check_entry(struct hvm_domain_context * h,uint16_t type,uint32_t len,bool strict_length)378 int _hvm_check_entry(struct hvm_domain_context *h, uint16_t type, uint32_t len,
379                      bool strict_length)
380 {
381     struct hvm_save_descriptor *d
382         = (struct hvm_save_descriptor *)&h->data[h->cur];
383 
384     if ( sizeof(*d) > h->size - h->cur)
385     {
386         printk(XENLOG_G_WARNING
387                "HVM restore: not enough data left to read %zu bytes "
388                "for type %u header\n", sizeof(*d), type);
389         return -1;
390     }
391 
392     if ( (type != d->typecode) ||
393          (strict_length ? (len != d->length) : (len < d->length)) ||
394          (d->length > (h->size - h->cur - sizeof(*d))) )
395     {
396         printk(XENLOG_G_WARNING
397                "HVM restore mismatch: expected %s type %u length %u, "
398                "saw type %u length %u.  %zu bytes remaining\n",
399                strict_length ? "strict" : "zeroextended", type, len,
400                d->typecode, d->length, h->size - h->cur - sizeof(*d));
401         return -1;
402     }
403 
404     h->cur += sizeof(*d);
405 
406     return 0;
407 }
408 
_hvm_read_entry(struct hvm_domain_context * h,void * dest,uint32_t dest_len)409 void _hvm_read_entry(struct hvm_domain_context *h, void *dest,
410                      uint32_t dest_len)
411 {
412     struct hvm_save_descriptor *d
413         = (struct hvm_save_descriptor *)&h->data[h->cur - sizeof(*d)];
414 
415     BUG_ON(d->length > dest_len);
416 
417     memcpy(dest, &h->data[h->cur], d->length);
418 
419     if ( d->length < dest_len )
420         memset(dest + d->length, 0, dest_len - d->length);
421 
422     h->cur += d->length;
423 }
424 
425 /*
426  * Local variables:
427  * mode: C
428  * c-file-style: "BSD"
429  * c-basic-offset: 4
430  * tab-width: 4
431  * indent-tabs-mode: nil
432  * End:
433  */
434