Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Floating point context-switching and checkpoint/load
[palacios.git] / palacios / src / palacios / vmm_checkpoint.c
1 /* 
2  * This file is part of the Palacios Virtual Machine Monitor developed
3  * by the V3VEE Project with funding from the United States National 
4  * Science Foundation and the Department of Energy.  
5  *
6  * The V3VEE Project is a joint project between Northwestern University
7  * and the University of New Mexico.  You can find out more at 
8  * http://www.v3vee.org
9  *
10  * Copyright (c) 2011, Madhav Suresh <madhav@u.northwestern.edu> 
11  * Copyright (c) 2011, The V3VEE Project <http://www.v3vee.org> 
12  * All rights reserved.
13  *
14  * Author: Madhav Suresh <madhav@u.northwestern.edu>
15  *         Arefin Huq <fig@arefin.net>
16  *         Peter Dinda <pdinda@northwestern.edu> (store interface changes)
17  *
18  *
19  * This is free software.  You are permitted to use,
20  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
21  */
22
23 #include <palacios/vmm.h>
24 #include <palacios/vmm_sprintf.h>
25 #include <palacios/vm_guest.h>
26 #include <palacios/svm.h>
27 #include <palacios/vmx.h>
28 #include <palacios/vmm_checkpoint.h>
29 #include <palacios/vmm_hashtable.h>
30 #include <palacios/vmm_direct_paging.h>
31 #include <palacios/vmm_debug.h>
32
33 #include <palacios/vmm_dev_mgr.h>
34
35 #ifdef V3_CONFIG_LIVE_MIGRATION
36 #include <palacios/vmm_time.h>
37 #include <palacios/vm_guest_mem.h>
38 #include <palacios/vmm_shadow_paging.h>
39 #endif
40
41 #ifndef V3_CONFIG_DEBUG_CHECKPOINT
42 #undef PrintDebug
43 #define PrintDebug(fmt, args...)
44 #endif
45
46
47 static struct hashtable * store_table = NULL;
48
49 struct v3_chkpt;
50
51 typedef enum {SAVE, LOAD} chkpt_mode_t;
52
53 struct chkpt_interface {
54   char name[128];
55   // Opening a checkpoint should return a pointer to the internal representation
56   // of the checkpoint in the store.  This will be passed back
57   // as "store_data".  Return NULL if the context cannot be opened
58   void * (*open_chkpt)(char * url, chkpt_mode_t mode);
59   // Closing the checkpoint should return -1 on failure, 0 on success
60   int    (*close_chkpt)(void * store_data);
61   
62   // Opening a context on the checkpoint with a given name should return
63   // a pointer to an internal representation of the context.  This pointer
64   // is then passed back as "ctx". 
65   // We will open only a single context at a time.  
66   void * (*open_ctx)(void * store_data, char *name);
67   // Closing the context should return -1 on failure, 0 on success
68   int    (*close_ctx)(void * store_data, void * ctx);
69   
70   // Save and load include a tagged data buffer.  These are 
71   // "all or nothing" writes and reads.  
72   // return -1 on failure, and 0 on success
73   // 
74   int (*save)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf);
75   int (*load)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf);
76 };
77
78
79 struct v3_chkpt {
80   struct v3_vm_info * vm;
81   
82   struct v3_chkpt_ctx *current_ctx;
83   
84   struct chkpt_interface * interface;
85   
86   void * store_data;
87 };
88
89
90
91
92 static uint_t store_hash_fn(addr_t key) {
93     char * name = (char *)key;
94     return v3_hash_buffer((uint8_t *)name, strlen(name));
95 }
96
97 static int store_eq_fn(addr_t key1, addr_t key2) {
98     char * name1 = (char *)key1;
99     char * name2 = (char *)key2;
100
101     return (strcmp(name1, name2) == 0);
102 }
103
104
105
106 #include "vmm_chkpt_stores.h"
107
108
109 int V3_init_checkpoint() {
110     extern struct chkpt_interface * __start__v3_chkpt_stores[];
111     extern struct chkpt_interface * __stop__v3_chkpt_stores[];
112     struct chkpt_interface ** tmp_store = __start__v3_chkpt_stores;
113     int i = 0;
114
115     store_table = v3_create_htable(0, store_hash_fn, store_eq_fn);
116
117     while (tmp_store != __stop__v3_chkpt_stores) {
118         V3_Print(VM_NONE, VCORE_NONE, "Registering Checkpoint Backing Store (%s)\n", (*tmp_store)->name);
119
120         if (v3_htable_search(store_table, (addr_t)((*tmp_store)->name))) {
121             PrintError(VM_NONE, VCORE_NONE, "Multiple instances of Checkpoint backing Store (%s)\n", (*tmp_store)->name);
122             return -1;
123         }
124
125         if (v3_htable_insert(store_table, (addr_t)((*tmp_store)->name), (addr_t)(*tmp_store)) == 0) {
126             PrintError(VM_NONE, VCORE_NONE, "Could not register Checkpoint backing store (%s)\n", (*tmp_store)->name);
127             return -1;
128         }
129
130         tmp_store = &(__start__v3_chkpt_stores[++i]);
131     }
132
133     return 0;
134 }
135
136 int V3_deinit_checkpoint() {
137     v3_free_htable(store_table, 0, 0);
138     return 0;
139 }
140
141
142 static char svm_chkpt_header[] = "v3vee palacios checkpoint version: x.x, SVM x.x";
143 static char vmx_chkpt_header[] = "v3vee palacios checkpoint version: x.x, VMX x.x";
144
145 static int chkpt_close(struct v3_chkpt * chkpt) {
146   if (chkpt) { 
147     int rc;
148
149     rc = chkpt->interface->close_chkpt(chkpt->store_data);
150
151     V3_Free(chkpt);
152
153     if (rc!=0) { 
154       PrintError(VM_NONE, VCORE_NONE, "Internal store failed to close valid checkpoint\n");
155       return -1;
156     } else {
157       return 0;
158     }
159   } else {
160     PrintError(VM_NONE, VCORE_NONE, "Attempt to close null checkpoint\n");
161     return -1;
162   }
163 }
164
165
166 static struct v3_chkpt * chkpt_open(struct v3_vm_info * vm, char * store, char * url, chkpt_mode_t mode) {
167     struct chkpt_interface * iface = NULL;
168     struct v3_chkpt * chkpt = NULL;
169     void * store_data = NULL;
170
171     iface = (void *)v3_htable_search(store_table, (addr_t)store);
172     
173     if (iface == NULL) {
174         V3_Print(vm, VCORE_NONE, "Error: Could not locate Checkpoint interface for store (%s)\n", store);
175         return NULL;
176     }
177
178     store_data = iface->open_chkpt(url, mode);
179
180     if (store_data == NULL) {
181         PrintError(vm, VCORE_NONE, "Could not open url (%s) for backing store (%s)\n", url, store);
182         return NULL;
183     }
184
185
186     chkpt = V3_Malloc(sizeof(struct v3_chkpt));
187     
188     if (!chkpt) {
189         PrintError(vm, VCORE_NONE, "Could not allocate checkpoint state, closing checkpoint\n");
190         iface->close_chkpt(store_data);
191         return NULL;
192     }
193
194     memset(chkpt,0,sizeof(struct v3_chkpt));
195
196     chkpt->interface = iface;
197     chkpt->vm = vm;
198     chkpt->store_data = store_data;
199     chkpt->current_ctx = NULL;
200     
201     return chkpt;
202 }
203
204 struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, char * name) {
205   struct v3_chkpt_ctx * ctx;
206
207   if (chkpt->current_ctx) { 
208     PrintError(VM_NONE, VCORE_NONE, "Attempt to open context %s before old context has been closed\n", name);
209     return NULL;
210   }
211
212   ctx = V3_Malloc(sizeof(struct v3_chkpt_ctx));
213
214   if (!ctx) { 
215     PrintError(VM_NONE, VCORE_NONE, "Unable to allocate context\n");
216     return 0;
217   }
218   
219   memset(ctx, 0, sizeof(struct v3_chkpt_ctx));
220   
221   ctx->chkpt = chkpt;
222   ctx->store_ctx = chkpt->interface->open_ctx(chkpt->store_data, name);
223
224   if (!(ctx->store_ctx)) {
225     PrintError(VM_NONE, VCORE_NONE, "Underlying store failed to open context %s\n",name);
226     V3_Free(ctx);
227     return NULL;
228   }
229
230   chkpt->current_ctx = ctx;
231
232   return ctx;
233 }
234
235 int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx) {
236     struct v3_chkpt * chkpt = ctx->chkpt;
237     int ret = 0;
238
239     if (chkpt->current_ctx != ctx) { 
240       PrintError(VM_NONE, VCORE_NONE, "Attempt to close a context that is not the current context on the store\n");
241       return -1;
242     }
243
244     ret = chkpt->interface->close_ctx(chkpt->store_data, ctx->store_ctx);
245
246     if (ret) { 
247       PrintError(VM_NONE, VCORE_NONE, "Failed to close context on store, closing device-independent context anyway - bad\n");
248       ret = -1;
249     }
250
251     chkpt->current_ctx=NULL;
252
253     V3_Free(ctx);
254
255     return ret;
256 }
257
258
259
260
261
262 int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) {
263     struct v3_chkpt * chkpt = ctx->chkpt;    
264     int rc;
265
266     if (!ctx) { 
267       PrintError(VM_NONE, VCORE_NONE, "Attempt to save tag %s on null context\n",tag);
268       return -1;
269     }
270
271     if (chkpt->current_ctx != ctx) { 
272       PrintError(VM_NONE, VCORE_NONE, "Attempt to save on context that is not the current context for the store\n");
273       return -1;
274     }
275
276     rc = chkpt->interface->save(chkpt->store_data, ctx->store_ctx, tag , len, buf);
277
278     if (rc) { 
279       PrintError(VM_NONE, VCORE_NONE, "Underlying store failed to save tag %s on valid context\n",tag);
280       return -1;
281     } else {
282       return 0;
283     }
284 }
285
286
287 int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) {
288     struct v3_chkpt * chkpt = ctx->chkpt;    
289     int rc;
290
291     if (!ctx) { 
292       PrintError(VM_NONE, VCORE_NONE, "Attempt to load tag %s from null context\n",tag);
293       return -1;
294     }
295     
296     if (chkpt->current_ctx != ctx) { 
297       PrintError(VM_NONE, VCORE_NONE, "Attempt to load from context that is not the current context for the store\n");
298       return -1;
299     }
300
301     rc = chkpt->interface->load(chkpt->store_data, ctx->store_ctx, tag, len, buf);
302
303     if (rc) { 
304       PrintError(VM_NONE, VCORE_NONE, "Underlying store failed to load tag %s from valid context\n",tag);
305       return -1;
306     } else {
307       return 0;
308     }
309 }
310
311
312
313 static int load_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
314
315     void * guest_mem_base = NULL;
316     void * ctx = NULL;
317     uint64_t ret = 0;
318     uint64_t saved_mem_block_size;
319     uint32_t saved_num_base_regions;
320     char buf[128];
321     int i;
322     extern uint64_t v3_mem_block_size;
323
324     ctx = v3_chkpt_open_ctx(chkpt, "memory_img");
325     
326     if (!ctx) { 
327         PrintError(vm, VCORE_NONE, "Unable to open context for memory load\n");
328         return -1;
329     }
330                      
331     if (V3_CHKPT_LOAD(ctx, "region_size",saved_mem_block_size)) { 
332         PrintError(vm, VCORE_NONE, "Unable to load memory region size\n");
333         return -1;
334     }
335     
336     if (V3_CHKPT_LOAD(ctx, "num_regions",saved_num_base_regions)) {
337         PrintError(vm, VCORE_NONE, "Unable to load number of regions\n");
338         return -1;
339     }
340
341     if (saved_mem_block_size != v3_mem_block_size) { 
342         PrintError(vm, VCORE_NONE, "Unable to load as memory block size differs\n");
343         return -1;
344     } // support will eventually be added for this
345
346     if (saved_num_base_regions != vm->mem_map.num_base_regions) { 
347         PrintError(vm, VCORE_NONE, "Unable to laod as number of base regions differs\n");
348         return -1;
349     } // support will eventually be added for this
350
351     for (i=0;i<vm->mem_map.num_base_regions;i++) {
352         guest_mem_base = V3_VAddr((void *)vm->mem_map.base_regions[i].host_addr);
353         sprintf(buf,"memory_img%d",i);
354         if (v3_chkpt_load(ctx, buf, v3_mem_block_size, guest_mem_base)) {
355             PrintError(vm, VCORE_NONE, "Unable to load all of memory (region %d) (requested=%llu bytes, result=%llu bytes\n",i,(uint64_t)(vm->mem_size),ret);
356             v3_chkpt_close_ctx(ctx);
357             return -1;
358         }
359     }
360     
361     v3_chkpt_close_ctx(ctx);
362
363     return 0;
364 }
365
366
367 static int save_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
368     void * guest_mem_base = NULL;
369     void * ctx = NULL;
370     char buf[128]; // region name
371     uint64_t ret = 0;
372     extern uint64_t v3_mem_block_size;
373     int i;
374
375
376     ctx = v3_chkpt_open_ctx(chkpt, "memory_img");
377
378     if (!ctx) { 
379         PrintError(vm, VCORE_NONE, "Unable to open context to save memory\n");
380         return -1;
381     }
382
383     if (V3_CHKPT_SAVE(ctx, "region_size",v3_mem_block_size)) { 
384         PrintError(vm, VCORE_NONE, "Unable to save memory region size\n");
385         return -1;
386     }
387
388     if (V3_CHKPT_SAVE(ctx, "num_regions",vm->mem_map.num_base_regions)) {
389         PrintError(vm, VCORE_NONE, "Unable to save number of regions\n");
390         return -1;
391     }
392
393     for (i=0;i<vm->mem_map.num_base_regions;i++) {
394         guest_mem_base = V3_VAddr((void *)vm->mem_map.base_regions[i].host_addr);
395         sprintf(buf,"memory_img%d",i);
396         if (v3_chkpt_save(ctx, buf, v3_mem_block_size, guest_mem_base)) {
397             PrintError(vm, VCORE_NONE, "Unable to save all of memory (region %d) (requested=%llu, received=%llu)\n",i,(uint64_t)(vm->mem_size),ret);
398             v3_chkpt_close_ctx(ctx);  
399             return -1;
400         }
401     }
402
403     v3_chkpt_close_ctx(ctx);
404
405     return 0;
406 }
407
408 #ifdef V3_CONFIG_LIVE_MIGRATION
409
410 struct mem_migration_state {
411     struct v3_vm_info *vm;
412     struct v3_bitmap  modified_pages; 
413 };
414
415 static int shadow_paging_callback(struct guest_info *core, 
416                                   struct v3_shdw_pg_event *event,
417                                   void      *priv_data)
418 {
419     struct mem_migration_state *m = (struct mem_migration_state *)priv_data;
420     
421     if (event->event_type==SHADOW_PAGEFAULT &&
422         event->event_order==SHADOW_PREIMPL &&
423         event->error_code.write) { // Note, assumes VTLB behavior where we will see the write even if preceded by a read
424         addr_t gpa;
425         if (!v3_gva_to_gpa(core,event->gva,&gpa)) {
426             // write to this page
427             v3_bitmap_set(&(m->modified_pages),gpa>>12);
428         } else {
429             // no worries, this isn't physical memory
430         }
431     } else {
432         // we don't care about other events
433     }
434     
435     return 0;
436 }
437
438
439 /*
440 static int nested_paging_callback(struct guest_info *core, 
441                                   struct v3_nested_pg_event *event,
442                                   void      *priv_data)
443 {
444     struct mem_migration_state *m = (struct mem_migration_state *)priv_data;
445     
446     if (event->event_type==NESTED_PAGEFAULT &&
447         event->event_order==NESTED_PREIMPL &&
448         event->error_code.write) { // Assumes we will see a write after reads
449         if (event->gpa<core->vm_info->mem_size) { 
450           v3_bitmap_set(&(m->modified_pages),(event->gpa)>>12);
451         } else {
452           // no worries, this isn't physical memory
453         }
454     } else {
455       // we don't care about other events
456     }
457     
458     return 0;
459 }
460 */      
461
462
463 static struct mem_migration_state *start_page_tracking(struct v3_vm_info *vm)
464 {
465     struct mem_migration_state *m;
466     int i;
467
468     m = (struct mem_migration_state *)V3_Malloc(sizeof(struct mem_migration_state));
469
470     if (!m) { 
471         PrintError(vm, VCORE_NONE, "Cannot allocate\n");
472         return NULL;
473     }
474
475     m->vm=vm;
476     
477     if (v3_bitmap_init(&(m->modified_pages),vm->mem_size >> 12) == -1) { 
478         PrintError(vm, VCORE_NONE, "Failed to initialize modified_pages bit vector");
479         V3_Free(m);
480     }
481
482     // We assume that the migrator has already verified that all cores are
483     // using the identical model (shadow or nested)
484     // This must not change over the execution of the migration
485
486     if (vm->cores[0].shdw_pg_mode==SHADOW_PAGING) { 
487       v3_register_shadow_paging_event_callback(vm,shadow_paging_callback,m);
488
489       for (i=0;i<vm->num_cores;i++) {
490         v3_invalidate_shadow_pts(&(vm->cores[i]));
491       }
492     } else if (vm->cores[0].shdw_pg_mode==NESTED_PAGING) { 
493       //v3_register_nested_paging_event_callback(vm,nested_paging_callback,m);
494       
495       for (i=0;i<vm->num_cores;i++) {
496         //v3_invalidate_nested_addr_range(&(vm->cores[i]),0,vm->mem_size-1);
497       }
498     } else {
499       PrintError(vm, VCORE_NONE, "Unsupported paging mode\n");
500       v3_bitmap_deinit(&(m->modified_pages));
501       V3_Free(m);
502       return 0;
503     }
504     
505     // and now we should get callbacks as writes happen
506
507     return m;
508 }
509
510 static void stop_page_tracking(struct mem_migration_state *m)
511 {
512   if (m->vm->cores[0].shdw_pg_mode==SHADOW_PAGING) { 
513     v3_unregister_shadow_paging_event_callback(m->vm,shadow_paging_callback,m);
514   } else {
515     //v3_unregister_nested_paging_event_callback(m->vm,nested_paging_callback,m);
516   }
517     
518   v3_bitmap_deinit(&(m->modified_pages));
519   
520   V3_Free(m);
521 }
522
523             
524                 
525                                                             
526
527
528 //
529 // Returns
530 //  negative: error
531 //  zero: done with this round
532 static int save_inc_memory(struct v3_vm_info * vm, 
533                            struct v3_bitmap * mod_pgs_to_send, 
534                            struct v3_chkpt * chkpt) {
535     int page_size_bytes = 1 << 12; // assuming 4k pages right now
536     void * ctx = NULL;
537     int i = 0; 
538     int bitmap_num_bytes = (mod_pgs_to_send->num_bits / 8) 
539                            + ((mod_pgs_to_send->num_bits % 8) > 0);
540
541    
542     PrintDebug(vm, VCORE_NONE, "Saving incremental memory.\n");
543
544     ctx = v3_chkpt_open_ctx(chkpt,"memory_bitmap_bits");
545
546     if (!ctx) { 
547         PrintError(vm, VCORE_NONE, "Cannot open context for dirty memory bitmap\n");
548         return -1;
549     }
550         
551
552     if (v3_chkpt_save(ctx,
553                       "memory_bitmap_bits",
554                       bitmap_num_bytes,
555                       mod_pgs_to_send->bits)) {
556         PrintError(vm, VCORE_NONE, "Unable to write all of the dirty memory bitmap\n");
557         v3_chkpt_close_ctx(ctx);
558         return -1;
559     }
560
561     v3_chkpt_close_ctx(ctx);
562
563     PrintDebug(vm, VCORE_NONE, "Sent bitmap bits.\n");
564
565     // Dirty memory pages are sent in bitmap order
566     for (i = 0; i < mod_pgs_to_send->num_bits; i++) {
567         if (v3_bitmap_check(mod_pgs_to_send, i)) {
568             struct v3_mem_region *region = v3_get_base_region(vm,page_size_bytes * i);
569             if (!region) { 
570                 PrintError(vm, VCORE_NONE, "Failed to find base region for page %d\n",i);
571                 return -1;
572             }
573             // PrintDebug(vm, VCORE_NONE, "Sending memory page %d.\n",i);
574             ctx = v3_chkpt_open_ctx(chkpt, "memory_page");
575             if (!ctx) { 
576                 PrintError(vm, VCORE_NONE, "Unable to open context to send memory page\n");
577                 return -1;
578             }
579             if (v3_chkpt_save(ctx, 
580                               "memory_page", 
581                               page_size_bytes,
582                               (void*)(region->host_addr + page_size_bytes * i - region->guest_start))) {
583                 PrintError(vm, VCORE_NONE, "Unable to send a memory page\n");
584                 v3_chkpt_close_ctx(ctx);
585                 return -1;
586             }
587             
588             v3_chkpt_close_ctx(ctx);
589         }
590     } 
591     
592     return 0;
593 }
594
595
596 //
597 // returns:
598 //  negative: error
599 //  zero: ok, but not done
600 //  positive: ok, and also done
601 static int load_inc_memory(struct v3_vm_info * vm, 
602                            struct v3_bitmap * mod_pgs,
603                            struct v3_chkpt * chkpt) {
604     int page_size_bytes = 1 << 12; // assuming 4k pages right now
605     void * ctx = NULL;
606     int i = 0; 
607     bool empty_bitmap = true;
608     int bitmap_num_bytes = (mod_pgs->num_bits / 8) 
609                            + ((mod_pgs->num_bits % 8) > 0);
610
611
612     ctx = v3_chkpt_open_ctx(chkpt, "memory_bitmap_bits");
613
614     if (!ctx) { 
615         PrintError(vm, VCORE_NONE, "Cannot open context to receive memory bitmap\n");
616         return -1;
617     }
618
619     if (v3_chkpt_load(ctx,
620                       "memory_bitmap_bits",
621                       bitmap_num_bytes,
622                       mod_pgs->bits)) {
623         PrintError(vm, VCORE_NONE, "Did not receive all of memory bitmap\n");
624         v3_chkpt_close_ctx(ctx);
625         return -1;
626     }
627     
628     v3_chkpt_close_ctx(ctx);
629
630     // Receive also follows bitmap order
631     for (i = 0; i < mod_pgs->num_bits; i ++) {
632         if (v3_bitmap_check(mod_pgs, i)) {
633             struct v3_mem_region *region = v3_get_base_region(vm,page_size_bytes * i);
634             if (!region) { 
635                 PrintError(vm, VCORE_NONE, "Failed to find base region for page %d\n",i);
636                 return -1;
637             }
638             //PrintDebug(vm, VCORE_NONE, "Loading page %d\n", i);
639             empty_bitmap = false;
640             ctx = v3_chkpt_open_ctx(chkpt, "memory_page");
641             if (!ctx) { 
642                 PrintError(vm, VCORE_NONE, "Cannot open context to receive memory page\n");
643                 return -1;
644             }
645             
646             if (v3_chkpt_load(ctx, 
647                               "memory_page", 
648                               page_size_bytes,
649                               (void*)(region->host_addr + page_size_bytes * i - region->guest_start))) {
650                 PrintError(vm, VCORE_NONE, "Did not receive all of memory page\n");
651                 v3_chkpt_close_ctx(ctx);
652                 return -1;
653             }
654             v3_chkpt_close_ctx(ctx);
655         }
656     } 
657     
658     if (empty_bitmap) {
659         // signal end of receiving pages
660         PrintDebug(vm, VCORE_NONE, "Finished receiving pages.\n");
661         return 1;
662     } else {
663         // need to run again
664         return 0;
665     }
666
667 }
668
669 #endif
670
671 int save_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
672     extern v3_cpu_arch_t v3_mach_type;
673     void * ctx = NULL;
674     
675     ctx = v3_chkpt_open_ctx(chkpt, "header");
676     if (!ctx) { 
677         PrintError(vm, VCORE_NONE, "Cannot open context to save header\n");
678         return -1;
679     }
680
681     switch (v3_mach_type) {
682         case V3_SVM_CPU:
683         case V3_SVM_REV3_CPU: {
684             if (v3_chkpt_save(ctx, "header", strlen(svm_chkpt_header), svm_chkpt_header)) { 
685                 PrintError(vm, VCORE_NONE, "Could not save all of SVM header\n");
686                 v3_chkpt_close_ctx(ctx);
687                 return -1;
688             }
689             break;
690         }
691         case V3_VMX_CPU:
692         case V3_VMX_EPT_CPU:
693         case V3_VMX_EPT_UG_CPU: {
694             if (v3_chkpt_save(ctx, "header", strlen(vmx_chkpt_header), vmx_chkpt_header)) { 
695                 PrintError(vm, VCORE_NONE, "Could not save all of VMX header\n");
696                 v3_chkpt_close_ctx(ctx);
697                 return -1;
698             }
699             break;
700         }
701         default:
702             PrintError(vm, VCORE_NONE, "checkpoint not supported on this architecture\n");
703             v3_chkpt_close_ctx(ctx);
704             return -1;
705     }
706
707     v3_chkpt_close_ctx(ctx);
708             
709     return 0;
710 }
711
712 static int load_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
713     extern v3_cpu_arch_t v3_mach_type;
714     void * ctx = NULL;
715     
716     ctx = v3_chkpt_open_ctx(chkpt, "header");
717
718     switch (v3_mach_type) {
719         case V3_SVM_CPU:
720         case V3_SVM_REV3_CPU: {
721             char header[strlen(svm_chkpt_header) + 1];
722          
723             if (v3_chkpt_load(ctx, "header", strlen(svm_chkpt_header), header)) {
724                 PrintError(vm, VCORE_NONE, "Could not load all of SVM header\n");
725                 v3_chkpt_close_ctx(ctx);
726                 return -1;
727             }
728             
729             header[strlen(svm_chkpt_header)] = 0;
730
731             break;
732         }
733         case V3_VMX_CPU:
734         case V3_VMX_EPT_CPU:
735         case V3_VMX_EPT_UG_CPU: {
736             char header[strlen(vmx_chkpt_header) + 1];
737             
738             if (v3_chkpt_load(ctx, "header", strlen(vmx_chkpt_header), header)) {
739                 PrintError(vm, VCORE_NONE, "Could not load all of VMX header\n");
740                 v3_chkpt_close_ctx(ctx);
741                 return -1;
742             }
743             
744             header[strlen(vmx_chkpt_header)] = 0;
745             
746             break;
747         }
748         default:
749             PrintError(vm, VCORE_NONE, "checkpoint not supported on this architecture\n");
750             v3_chkpt_close_ctx(ctx);
751             return -1;
752     }
753     
754     v3_chkpt_close_ctx(ctx);
755     
756     return 0;
757 }
758
759
760 static int load_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
761     extern v3_cpu_arch_t v3_mach_type;
762     void * ctx = NULL;
763     char key_name[16];
764     v3_reg_t tempreg;
765
766     PrintDebug(info->vm_info, info, "Loading core\n");
767
768     memset(key_name, 0, 16);
769
770     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
771
772     ctx = v3_chkpt_open_ctx(chkpt, key_name);
773
774     if (!ctx) { 
775         PrintError(info->vm_info, info, "Could not open context to load core\n");
776         goto loadfailout;
777     }
778     
779     // Run state is needed to determine when AP cores need
780     // to be immediately run after resume
781     V3_CHKPT_LOAD(ctx,"run_state",info->core_run_state,loadfailout);
782
783     V3_CHKPT_LOAD(ctx, "RIP", info->rip, loadfailout);
784     
785     // GPRs
786     V3_CHKPT_LOAD(ctx,"RDI",info->vm_regs.rdi, loadfailout); 
787     V3_CHKPT_LOAD(ctx,"RSI",info->vm_regs.rsi, loadfailout); 
788     V3_CHKPT_LOAD(ctx,"RBP",info->vm_regs.rbp, loadfailout); 
789     V3_CHKPT_LOAD(ctx,"RSP",info->vm_regs.rsp, loadfailout); 
790     V3_CHKPT_LOAD(ctx,"RBX",info->vm_regs.rbx, loadfailout); 
791     V3_CHKPT_LOAD(ctx,"RDX",info->vm_regs.rdx, loadfailout); 
792     V3_CHKPT_LOAD(ctx,"RCX",info->vm_regs.rcx, loadfailout); 
793     V3_CHKPT_LOAD(ctx,"RAX",info->vm_regs.rax, loadfailout);
794     V3_CHKPT_LOAD(ctx,"R8",info->vm_regs.r8, loadfailout);
795     V3_CHKPT_LOAD(ctx,"R9",info->vm_regs.r9, loadfailout);
796     V3_CHKPT_LOAD(ctx,"R10",info->vm_regs.r10, loadfailout);
797     V3_CHKPT_LOAD(ctx,"R11",info->vm_regs.r11, loadfailout);
798     V3_CHKPT_LOAD(ctx,"R12",info->vm_regs.r12, loadfailout);
799     V3_CHKPT_LOAD(ctx,"R13",info->vm_regs.r13, loadfailout);
800     V3_CHKPT_LOAD(ctx,"R14",info->vm_regs.r14, loadfailout);
801     V3_CHKPT_LOAD(ctx,"R15",info->vm_regs.r15, loadfailout);
802
803     // Control registers
804     V3_CHKPT_LOAD(ctx, "CR0", info->ctrl_regs.cr0, loadfailout);
805     // there is no CR1
806     V3_CHKPT_LOAD(ctx, "CR2", info->ctrl_regs.cr2, loadfailout);
807     V3_CHKPT_LOAD(ctx, "CR3", info->ctrl_regs.cr3, loadfailout);
808     V3_CHKPT_LOAD(ctx, "CR4", info->ctrl_regs.cr4, loadfailout);
809     // There are no CR5,6,7
810     // CR8 is derived from apic_tpr
811     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
812     V3_CHKPT_LOAD(ctx, "CR8", tempreg, loadfailout);
813     V3_CHKPT_LOAD(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, loadfailout);
814     V3_CHKPT_LOAD(ctx, "RFLAGS", info->ctrl_regs.rflags, loadfailout);
815     V3_CHKPT_LOAD(ctx, "EFER", info->ctrl_regs.efer, loadfailout);
816
817     // Debug registers
818     V3_CHKPT_LOAD(ctx, "DR0", info->dbg_regs.dr0, loadfailout);
819     V3_CHKPT_LOAD(ctx, "DR1", info->dbg_regs.dr1, loadfailout);
820     V3_CHKPT_LOAD(ctx, "DR2", info->dbg_regs.dr2, loadfailout);
821     V3_CHKPT_LOAD(ctx, "DR3", info->dbg_regs.dr3, loadfailout);
822     // there is no DR4 or DR5
823     V3_CHKPT_LOAD(ctx, "DR6", info->dbg_regs.dr6, loadfailout);
824     V3_CHKPT_LOAD(ctx, "DR7", info->dbg_regs.dr7, loadfailout);
825
826     // Segment registers
827     V3_CHKPT_LOAD(ctx, "CS", info->segments.cs, loadfailout);
828     V3_CHKPT_LOAD(ctx, "DS", info->segments.ds, loadfailout);
829     V3_CHKPT_LOAD(ctx, "ES", info->segments.es, loadfailout);
830     V3_CHKPT_LOAD(ctx, "FS", info->segments.fs, loadfailout);
831     V3_CHKPT_LOAD(ctx, "GS", info->segments.gs, loadfailout);
832     V3_CHKPT_LOAD(ctx, "SS", info->segments.ss, loadfailout);
833     V3_CHKPT_LOAD(ctx, "LDTR", info->segments.ldtr, loadfailout);
834     V3_CHKPT_LOAD(ctx, "GDTR", info->segments.gdtr, loadfailout);
835     V3_CHKPT_LOAD(ctx, "IDTR", info->segments.idtr, loadfailout);
836     V3_CHKPT_LOAD(ctx, "TR", info->segments.tr, loadfailout);
837     
838     // several MSRs...
839     V3_CHKPT_LOAD(ctx, "STAR", info->msrs.star, loadfailout);
840     V3_CHKPT_LOAD(ctx, "LSTAR", info->msrs.lstar, loadfailout);
841     V3_CHKPT_LOAD(ctx, "SFMASK", info->msrs.sfmask, loadfailout);
842     V3_CHKPT_LOAD(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, loadfailout);
843         
844     // Some components of guest state captured in the shadow pager
845     V3_CHKPT_LOAD(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, loadfailout);
846     V3_CHKPT_LOAD(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, loadfailout);
847     V3_CHKPT_LOAD(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, loadfailout);
848
849     // floating point
850     if (v3_load_fp_state(ctx,info)) {
851       goto loadfailout;
852     }
853
854     v3_chkpt_close_ctx(ctx); ctx=0;
855
856     PrintDebug(info->vm_info, info, "Finished reading guest_info information\n");
857
858     info->cpu_mode = v3_get_vm_cpu_mode(info);
859     info->mem_mode = v3_get_vm_mem_mode(info);
860
861     if (info->shdw_pg_mode == SHADOW_PAGING) {
862         if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
863             if (v3_activate_shadow_pt(info) == -1) {
864                 PrintError(info->vm_info, info, "Failed to activate shadow page tables\n");
865                 goto loadfailout;
866             }
867         } else {
868             if (v3_activate_passthrough_pt(info) == -1) {
869                 PrintError(info->vm_info, info, "Failed to activate passthrough page tables\n");
870                 goto loadfailout;
871             }
872         }
873     }
874
875
876     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) { 
877       goto donearch;
878     }
879
880     switch (v3_mach_type) {
881         case V3_SVM_CPU:
882         case V3_SVM_REV3_CPU: {
883             char key_name[16];
884
885             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
886             ctx = v3_chkpt_open_ctx(chkpt, key_name);
887
888             if (!ctx) { 
889                 PrintError(info->vm_info, info, "Could not open context to load SVM core\n");
890                 goto loadfailout;
891             }
892             
893             if (v3_svm_load_core(info, ctx) < 0 ) {
894                 PrintError(info->vm_info, info, "Failed to patch core %d\n", info->vcpu_id);
895                 goto loadfailout;
896             }
897
898             v3_chkpt_close_ctx(ctx); ctx=0;
899
900             break;
901         }
902         case V3_VMX_CPU:
903         case V3_VMX_EPT_CPU:
904         case V3_VMX_EPT_UG_CPU: {
905             char key_name[16];
906
907             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
908
909             ctx = v3_chkpt_open_ctx(chkpt, key_name);
910
911             if (!ctx) { 
912                 PrintError(info->vm_info, info, "Could not open context to load VMX core\n");
913                 goto loadfailout;
914             }
915             
916             if (v3_vmx_load_core(info, ctx) < 0) {
917                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
918                 goto loadfailout;
919             }
920
921             v3_chkpt_close_ctx(ctx); ctx=0;
922
923             break;
924         }
925         default:
926             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
927             goto loadfailout;
928     }
929
930  donearch:
931
932     PrintDebug(info->vm_info, info, "Load of core succeeded\n");
933
934     v3_print_guest_state(info);
935
936     return 0;
937
938  loadfailout:
939     PrintError(info->vm_info, info, "Failed to load core\n");
940     if (ctx) { v3_chkpt_close_ctx(ctx);}
941     return -1;
942
943 }
944
945 // GEM5 - Hypercall for initiating transfer to gem5 (checkpoint)
946
947 static int save_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
948     extern v3_cpu_arch_t v3_mach_type;
949     void * ctx = NULL;
950     char key_name[16];
951     v3_reg_t tempreg;
952
953     PrintDebug(info->vm_info, info, "Saving core\n");
954
955     v3_print_guest_state(info);
956
957     memset(key_name, 0, 16);
958
959     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
960
961     ctx = v3_chkpt_open_ctx(chkpt, key_name);
962     
963     if (!ctx) { 
964         PrintError(info->vm_info, info, "Unable to open context to save core\n");
965         goto savefailout;
966     }
967
968     V3_CHKPT_SAVE(ctx,"run_state",info->core_run_state,savefailout);
969
970     V3_CHKPT_SAVE(ctx, "RIP", info->rip, savefailout);
971     
972     // GPRs
973     V3_CHKPT_SAVE(ctx,"RDI",info->vm_regs.rdi, savefailout); 
974     V3_CHKPT_SAVE(ctx,"RSI",info->vm_regs.rsi, savefailout); 
975     V3_CHKPT_SAVE(ctx,"RBP",info->vm_regs.rbp, savefailout); 
976     V3_CHKPT_SAVE(ctx,"RSP",info->vm_regs.rsp, savefailout); 
977     V3_CHKPT_SAVE(ctx,"RBX",info->vm_regs.rbx, savefailout); 
978     V3_CHKPT_SAVE(ctx,"RDX",info->vm_regs.rdx, savefailout); 
979     V3_CHKPT_SAVE(ctx,"RCX",info->vm_regs.rcx, savefailout); 
980     V3_CHKPT_SAVE(ctx,"RAX",info->vm_regs.rax, savefailout);
981     V3_CHKPT_SAVE(ctx,"R8",info->vm_regs.r8, savefailout);
982     V3_CHKPT_SAVE(ctx,"R9",info->vm_regs.r9, savefailout);
983     V3_CHKPT_SAVE(ctx,"R10",info->vm_regs.r10, savefailout);
984     V3_CHKPT_SAVE(ctx,"R11",info->vm_regs.r11, savefailout);
985     V3_CHKPT_SAVE(ctx,"R12",info->vm_regs.r12, savefailout);
986     V3_CHKPT_SAVE(ctx,"R13",info->vm_regs.r13, savefailout);
987     V3_CHKPT_SAVE(ctx,"R14",info->vm_regs.r14, savefailout);
988     V3_CHKPT_SAVE(ctx,"R15",info->vm_regs.r15, savefailout);
989
990     // Control registers
991     V3_CHKPT_SAVE(ctx, "CR0", info->ctrl_regs.cr0, savefailout);
992     // there is no CR1
993     V3_CHKPT_SAVE(ctx, "CR2", info->ctrl_regs.cr2, savefailout);
994     V3_CHKPT_SAVE(ctx, "CR3", info->ctrl_regs.cr3, savefailout);
995     V3_CHKPT_SAVE(ctx, "CR4", info->ctrl_regs.cr4, savefailout);
996     // There are no CR5,6,7
997     // CR8 is derived from apic_tpr
998     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
999     V3_CHKPT_SAVE(ctx, "CR8", tempreg, savefailout);
1000     V3_CHKPT_SAVE(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, savefailout);
1001     V3_CHKPT_SAVE(ctx, "RFLAGS", info->ctrl_regs.rflags, savefailout);
1002     V3_CHKPT_SAVE(ctx, "EFER", info->ctrl_regs.efer, savefailout);
1003
1004     // Debug registers
1005     V3_CHKPT_SAVE(ctx, "DR0", info->dbg_regs.dr0, savefailout);
1006     V3_CHKPT_SAVE(ctx, "DR1", info->dbg_regs.dr1, savefailout);
1007     V3_CHKPT_SAVE(ctx, "DR2", info->dbg_regs.dr2, savefailout);
1008     V3_CHKPT_SAVE(ctx, "DR3", info->dbg_regs.dr3, savefailout);
1009     // there is no DR4 or DR5
1010     V3_CHKPT_SAVE(ctx, "DR6", info->dbg_regs.dr6, savefailout);
1011     V3_CHKPT_SAVE(ctx, "DR7", info->dbg_regs.dr7, savefailout);
1012
1013     // Segment registers
1014     V3_CHKPT_SAVE(ctx, "CS", info->segments.cs, savefailout);
1015     V3_CHKPT_SAVE(ctx, "DS", info->segments.ds, savefailout);
1016     V3_CHKPT_SAVE(ctx, "ES", info->segments.es, savefailout);
1017     V3_CHKPT_SAVE(ctx, "FS", info->segments.fs, savefailout);
1018     V3_CHKPT_SAVE(ctx, "GS", info->segments.gs, savefailout);
1019     V3_CHKPT_SAVE(ctx, "SS", info->segments.ss, savefailout);
1020     V3_CHKPT_SAVE(ctx, "LDTR", info->segments.ldtr, savefailout);
1021     V3_CHKPT_SAVE(ctx, "GDTR", info->segments.gdtr, savefailout);
1022     V3_CHKPT_SAVE(ctx, "IDTR", info->segments.idtr, savefailout);
1023     V3_CHKPT_SAVE(ctx, "TR", info->segments.tr, savefailout);
1024     
1025     // several MSRs...
1026     V3_CHKPT_SAVE(ctx, "STAR", info->msrs.star, savefailout);
1027     V3_CHKPT_SAVE(ctx, "LSTAR", info->msrs.lstar, savefailout);
1028     V3_CHKPT_SAVE(ctx, "SFMASK", info->msrs.sfmask, savefailout);
1029     V3_CHKPT_SAVE(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, savefailout);
1030         
1031     // Some components of guest state captured in the shadow pager
1032     V3_CHKPT_SAVE(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, savefailout);
1033     V3_CHKPT_SAVE(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, savefailout);
1034     V3_CHKPT_SAVE(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, savefailout);
1035
1036     // floating point
1037     if (v3_save_fp_state(ctx,info)) {
1038       goto savefailout;
1039     }
1040
1041     v3_chkpt_close_ctx(ctx); ctx=0;
1042
1043     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) {
1044       goto donearch;
1045     }
1046
1047     //Architechture specific code
1048     switch (v3_mach_type) {
1049         case V3_SVM_CPU:
1050         case V3_SVM_REV3_CPU: {
1051             char key_name[16];
1052             
1053             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
1054             
1055             ctx = v3_chkpt_open_ctx(chkpt, key_name);
1056
1057             if (!ctx) { 
1058                 PrintError(info->vm_info, info, "Could not open context to store SVM core\n");
1059                 goto savefailout;
1060             }
1061             
1062             if (v3_svm_save_core(info, ctx) < 0) {
1063                 PrintError(info->vm_info, info, "VMCB Unable to be written\n");
1064                 goto savefailout;
1065             }
1066             
1067             v3_chkpt_close_ctx(ctx); ctx=0;;
1068             break;
1069         }
1070         case V3_VMX_CPU:
1071         case V3_VMX_EPT_CPU:
1072         case V3_VMX_EPT_UG_CPU: {
1073             char key_name[16];
1074
1075             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
1076             
1077             ctx = v3_chkpt_open_ctx(chkpt, key_name);
1078             
1079             if (!ctx) { 
1080                 PrintError(info->vm_info, info, "Could not open context to store VMX core\n");
1081                 goto savefailout;
1082             }
1083
1084             if (v3_vmx_save_core(info, ctx) == -1) {
1085                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
1086                 goto savefailout;
1087             }
1088
1089             v3_chkpt_close_ctx(ctx); ctx=0;
1090
1091             break;
1092         }
1093         default:
1094             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
1095             goto savefailout;
1096             
1097     }
1098
1099  donearch:
1100     
1101     return 0;
1102
1103  savefailout:
1104     PrintError(info->vm_info, info, "Failed to save core\n");
1105     if (ctx) { v3_chkpt_close_ctx(ctx); }
1106     return -1;
1107
1108 }
1109
1110 //
1111 // GEM5 - Madhav has debug code here for printing instrucions
1112 //
1113
1114 int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1115     struct v3_chkpt * chkpt = NULL;
1116     int ret = 0;;
1117     int i = 0;
1118
1119
1120     chkpt = chkpt_open(vm, store, url, SAVE);
1121
1122     if (chkpt == NULL) {
1123         PrintError(vm, VCORE_NONE, "Error creating checkpoint store for url %s\n",url);
1124         return -1;
1125     }
1126
1127     /* If this guest is running we need to block it while the checkpoint occurs */
1128     if (vm->run_state == VM_RUNNING) {
1129         while (v3_raise_barrier(vm, NULL) == -1);
1130     }
1131
1132     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1133       if ((ret = save_memory(vm, chkpt)) == -1) {
1134         PrintError(vm, VCORE_NONE, "Unable to save memory\n");
1135         goto out;
1136       }
1137     }
1138     
1139     
1140     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1141       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1142         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1143         goto out;
1144       }
1145     }
1146
1147     if ((ret = save_header(vm, chkpt)) == -1) {
1148         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1149         goto out;
1150     }
1151
1152     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { 
1153       for (i = 0; i < vm->num_cores; i++){
1154         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1155           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1156           goto out;
1157         }
1158       }
1159     }
1160     
1161  out:
1162     
1163     /* Resume the guest if it was running */
1164     if (vm->run_state == VM_RUNNING) {
1165         v3_lower_barrier(vm);
1166     }
1167
1168     chkpt_close(chkpt);
1169
1170     return ret;
1171
1172 }
1173
1174 int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1175     struct v3_chkpt * chkpt = NULL;
1176     int i = 0;
1177     int ret = 0;
1178     
1179     chkpt = chkpt_open(vm, store, url, LOAD);
1180
1181     if (chkpt == NULL) {
1182         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1183         return -1;
1184     }
1185
1186     /* If this guest is running we need to block it while the checkpoint occurs */
1187     if (vm->run_state == VM_RUNNING) {
1188         while (v3_raise_barrier(vm, NULL) == -1);
1189     }
1190
1191     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1192       if ((ret = load_memory(vm, chkpt)) == -1) {
1193         PrintError(vm, VCORE_NONE, "Unable to load memory\n");
1194         goto out;
1195       }
1196     }
1197
1198     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1199       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1200         PrintError(vm, VCORE_NONE, "Unable to load devies\n");
1201         goto out;
1202       }
1203     }
1204
1205
1206     if ((ret = load_header(vm, chkpt)) == -1) {
1207         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1208         goto out;
1209     }
1210
1211     //per core cloning
1212     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1213       for (i = 0; i < vm->num_cores; i++) {
1214         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1215           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1216           goto out;
1217         }
1218       }
1219     }
1220
1221  out:
1222
1223     /* Resume the guest if it was running and we didn't just trash the state*/
1224     if (vm->run_state == VM_RUNNING) {
1225     
1226         if (ret == -1) {
1227             vm->run_state = VM_STOPPED;
1228         }
1229
1230         /* We check the run state of the VM after every barrier 
1231            So this will immediately halt the VM 
1232         */
1233         v3_lower_barrier(vm);
1234     }
1235
1236     chkpt_close(chkpt);
1237
1238     return ret;
1239
1240 }
1241
1242
1243 #ifdef V3_CONFIG_LIVE_MIGRATION
1244
1245 #define MOD_THRESHOLD   200  // pages below which we declare victory
1246 #define ITER_THRESHOLD  32   // iters below which we declare victory
1247
1248
1249
1250 int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1251     struct v3_chkpt * chkpt = NULL;
1252     int ret = 0;;
1253     int iter = 0;
1254     bool last_modpage_iteration=false;
1255     struct v3_bitmap modified_pages_to_send;
1256     uint64_t start_time;
1257     uint64_t stop_time;
1258     int num_mod_pages=0;
1259     struct mem_migration_state *mm_state;
1260     int i;
1261
1262     // Cores must all be in the same mode
1263     // or we must be skipping mmeory
1264     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1265       v3_paging_mode_t mode = vm->cores[0].shdw_pg_mode;
1266       for (i=1;i<vm->num_cores;i++) { 
1267         if (vm->cores[i].shdw_pg_mode != mode) { 
1268           PrintError(vm, VCORE_NONE, "Cores having different paging modes (nested and shadow) are not supported\n");
1269           return -1;
1270         }
1271       }
1272     }
1273     
1274     
1275     chkpt = chkpt_open(vm, store, url, SAVE);
1276     
1277     if (chkpt == NULL) {
1278         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1279         chkpt_close(chkpt);
1280         return -1;
1281     }
1282     
1283     if (opts & V3_CHKPT_OPT_SKIP_MEM) {
1284       goto memdone;
1285     }
1286
1287     // In a send, the memory is copied incrementally first,
1288     // followed by the remainder of the state
1289     
1290     if (v3_bitmap_init(&modified_pages_to_send,
1291                        vm->mem_size>>12 // number of pages in main region
1292                        ) == -1) {
1293         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1294         return -1;
1295     }
1296
1297     // 0. Initialize bitmap to all 1s
1298     for (i=0; i < modified_pages_to_send.num_bits; i++) {
1299         v3_bitmap_set(&modified_pages_to_send,i);
1300     }
1301
1302     iter = 0;
1303     while (!last_modpage_iteration) {
1304         PrintDebug(vm, VCORE_NONE, "Modified memory page iteration %d\n",i++);
1305         
1306         start_time = v3_get_host_time(&(vm->cores[0].time_state));
1307         
1308         // We will pause the VM for a short while
1309         // so that we can collect the set of changed pages
1310         if (v3_pause_vm(vm) == -1) {
1311             PrintError(vm, VCORE_NONE, "Could not pause VM\n");
1312             ret = -1;
1313             goto out;
1314         }
1315         
1316         if (iter==0) { 
1317             // special case, we already have the pages to send (all of them)
1318             // they are already in modified_pages_to_send
1319         } else {
1320             // normally, we are in the middle of a round
1321             // We need to copy from the current tracking bitmap
1322             // to our send bitmap
1323             v3_bitmap_copy(&modified_pages_to_send,&(mm_state->modified_pages));
1324             // and now we need to remove our tracking
1325             stop_page_tracking(mm_state);
1326         }
1327
1328         // are we done? (note that we are still paused)
1329         num_mod_pages = v3_bitmap_count(&modified_pages_to_send);
1330         if (num_mod_pages<MOD_THRESHOLD || iter>ITER_THRESHOLD) {
1331             // we are done, so we will not restart page tracking
1332             // the vm is paused, and so we should be able
1333             // to just send the data
1334             PrintDebug(vm, VCORE_NONE, "Last modified memory page iteration.\n");
1335             last_modpage_iteration = true;
1336         } else {
1337             // we are not done, so we will restart page tracking
1338             // to prepare for a second round of pages
1339             // we will resume the VM as this happens
1340             if (!(mm_state=start_page_tracking(vm))) { 
1341                 PrintError(vm, VCORE_NONE, "Error enabling page tracking.\n");
1342                 ret = -1;
1343                 goto out;
1344             }
1345             if (v3_continue_vm(vm) == -1) {
1346                 PrintError(vm, VCORE_NONE, "Error resuming the VM\n");
1347                 stop_page_tracking(mm_state);
1348                 ret = -1;
1349                 goto out;
1350             }
1351             
1352             stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1353             PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1354         }
1355         
1356
1357         // At this point, we are either paused and about to copy
1358         // the last chunk, or we are running, and will copy the last
1359         // round in parallel with current execution
1360         if (num_mod_pages>0) { 
1361             if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1362                 PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1363                 ret = -1;
1364                 goto out;
1365             }
1366         } // we don't want to copy an empty bitmap here
1367         
1368         iter++;
1369     }        
1370     
1371     if (v3_bitmap_reset(&modified_pages_to_send) == -1) {
1372         PrintError(vm, VCORE_NONE, "Error reseting bitmap.\n");
1373         ret = -1;
1374         goto out;
1375     }    
1376     
1377     // send bitmap of 0s to signal end of modpages
1378     if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1379         PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1380         ret = -1;
1381         goto out;
1382     }
1383
1384  memdone:    
1385     // save the non-memory state
1386     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1387       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1388         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1389         goto out;
1390       }
1391     }
1392
1393     if ((ret = save_header(vm, chkpt)) == -1) {
1394         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1395         goto out;
1396     }
1397     
1398     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1399       for (i = 0; i < vm->num_cores; i++){
1400         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1401           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1402           goto out;
1403         }
1404       }
1405     }
1406
1407     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1408       stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1409       PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1410       PrintDebug(vm, VCORE_NONE, "Done sending VM!\n"); 
1411     out:
1412       v3_bitmap_deinit(&modified_pages_to_send);
1413     }
1414
1415     chkpt_close(chkpt);
1416     
1417     return ret;
1418
1419 }
1420
1421 int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1422     struct v3_chkpt * chkpt = NULL;
1423     int i = 0;
1424     int ret = 0;
1425     struct v3_bitmap mod_pgs;
1426  
1427     // Currently will work only for shadow paging
1428     for (i=0;i<vm->num_cores;i++) { 
1429       if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1430         PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n");
1431         return -1;
1432       }
1433     }
1434     
1435     chkpt = chkpt_open(vm, store, url, LOAD);
1436     
1437     if (chkpt == NULL) {
1438         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1439         chkpt_close(chkpt);
1440         return -1;
1441     }
1442     
1443
1444     if (opts & V3_CHKPT_OPT_SKIP_MEM) { 
1445       goto memdone;
1446     }
1447
1448     if (v3_bitmap_init(&mod_pgs,vm->mem_size>>12) == -1) {
1449         chkpt_close(chkpt);
1450         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1451         return -1;
1452     }
1453     
1454     /* If this guest is running we need to block it while the checkpoint occurs */
1455     if (vm->run_state == VM_RUNNING) {
1456         while (v3_raise_barrier(vm, NULL) == -1);
1457     }
1458     
1459     i = 0;
1460     while(true) {
1461         // 1. Receive copy of bitmap
1462         // 2. Receive pages
1463         PrintDebug(vm, VCORE_NONE, "Memory page iteration %d\n",i++);
1464         int retval = load_inc_memory(vm, &mod_pgs, chkpt);
1465         if (retval == 1) {
1466             // end of receiving memory pages
1467             break;        
1468         } else if (retval == -1) {
1469             PrintError(vm, VCORE_NONE, "Error receiving incremental memory.\n");
1470             ret = -1;
1471             goto out;
1472         }
1473     }        
1474
1475  memdone:
1476     
1477     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { 
1478       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1479         PrintError(vm, VCORE_NONE, "Unable to load devices\n");
1480         ret = -1;
1481         goto out;
1482       }
1483     }
1484     
1485     if ((ret = load_header(vm, chkpt)) == -1) {
1486         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1487         ret = -1;
1488         goto out;
1489     }
1490     
1491     //per core cloning
1492     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1493       for (i = 0; i < vm->num_cores; i++) {
1494         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1495           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1496           goto out;
1497         }
1498       }
1499     }
1500
1501  out:
1502     if (ret==-1) { 
1503         PrintError(vm, VCORE_NONE, "Unable to receive VM\n");
1504     } else {
1505         PrintDebug(vm, VCORE_NONE, "Done receving the VM\n");
1506     }
1507         
1508         
1509     /* Resume the guest if it was running and we didn't just trash the state*/
1510     if (vm->run_state == VM_RUNNING) { 
1511         if (ret == -1) {
1512             PrintError(vm, VCORE_NONE, "VM was previously running.  It is now borked.  Pausing it. \n");
1513             vm->run_state = VM_STOPPED;
1514         }
1515             
1516         /* We check the run state of the VM after every barrier 
1517            So this will immediately halt the VM 
1518         */
1519         v3_lower_barrier(vm);
1520     } 
1521     
1522
1523     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1524       v3_bitmap_deinit(&mod_pgs);
1525     }
1526
1527     chkpt_close(chkpt);
1528
1529     return ret;
1530 }
1531
1532 #endif