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.


Error checking fixes, minor bug in keyed stream, minor bug in checkpoint
[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     if (!ctx) { 
719         PrintError(vm, VCORE_NONE, "Cannot open context to load header\n");
720         return -1;
721     }
722
723     switch (v3_mach_type) {
724         case V3_SVM_CPU:
725         case V3_SVM_REV3_CPU: {
726             char header[strlen(svm_chkpt_header) + 1];
727          
728             if (v3_chkpt_load(ctx, "header", strlen(svm_chkpt_header), header)) {
729                 PrintError(vm, VCORE_NONE, "Could not load all of SVM header\n");
730                 v3_chkpt_close_ctx(ctx);
731                 return -1;
732             }
733             
734             header[strlen(svm_chkpt_header)] = 0;
735
736             break;
737         }
738         case V3_VMX_CPU:
739         case V3_VMX_EPT_CPU:
740         case V3_VMX_EPT_UG_CPU: {
741             char header[strlen(vmx_chkpt_header) + 1];
742             
743             if (v3_chkpt_load(ctx, "header", strlen(vmx_chkpt_header), header)) {
744                 PrintError(vm, VCORE_NONE, "Could not load all of VMX header\n");
745                 v3_chkpt_close_ctx(ctx);
746                 return -1;
747             }
748             
749             header[strlen(vmx_chkpt_header)] = 0;
750             
751             break;
752         }
753         default:
754             PrintError(vm, VCORE_NONE, "checkpoint not supported on this architecture\n");
755             v3_chkpt_close_ctx(ctx);
756             return -1;
757     }
758     
759     v3_chkpt_close_ctx(ctx);
760     
761     return 0;
762 }
763
764
765 static int load_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
766     extern v3_cpu_arch_t v3_mach_type;
767     void * ctx = NULL;
768     char key_name[16];
769     v3_reg_t tempreg;
770
771     PrintDebug(info->vm_info, info, "Loading core\n");
772
773     memset(key_name, 0, 16);
774
775     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
776
777     ctx = v3_chkpt_open_ctx(chkpt, key_name);
778
779     if (!ctx) { 
780         PrintError(info->vm_info, info, "Could not open context to load core\n");
781         goto loadfailout;
782     }
783     
784     // Run state is needed to determine when AP cores need
785     // to be immediately run after resume
786     V3_CHKPT_LOAD(ctx,"run_state",info->core_run_state,loadfailout);
787
788     V3_CHKPT_LOAD(ctx, "RIP", info->rip, loadfailout);
789     
790     // GPRs
791     V3_CHKPT_LOAD(ctx,"RDI",info->vm_regs.rdi, loadfailout); 
792     V3_CHKPT_LOAD(ctx,"RSI",info->vm_regs.rsi, loadfailout); 
793     V3_CHKPT_LOAD(ctx,"RBP",info->vm_regs.rbp, loadfailout); 
794     V3_CHKPT_LOAD(ctx,"RSP",info->vm_regs.rsp, loadfailout); 
795     V3_CHKPT_LOAD(ctx,"RBX",info->vm_regs.rbx, loadfailout); 
796     V3_CHKPT_LOAD(ctx,"RDX",info->vm_regs.rdx, loadfailout); 
797     V3_CHKPT_LOAD(ctx,"RCX",info->vm_regs.rcx, loadfailout); 
798     V3_CHKPT_LOAD(ctx,"RAX",info->vm_regs.rax, loadfailout);
799     V3_CHKPT_LOAD(ctx,"R8",info->vm_regs.r8, loadfailout);
800     V3_CHKPT_LOAD(ctx,"R9",info->vm_regs.r9, loadfailout);
801     V3_CHKPT_LOAD(ctx,"R10",info->vm_regs.r10, loadfailout);
802     V3_CHKPT_LOAD(ctx,"R11",info->vm_regs.r11, loadfailout);
803     V3_CHKPT_LOAD(ctx,"R12",info->vm_regs.r12, loadfailout);
804     V3_CHKPT_LOAD(ctx,"R13",info->vm_regs.r13, loadfailout);
805     V3_CHKPT_LOAD(ctx,"R14",info->vm_regs.r14, loadfailout);
806     V3_CHKPT_LOAD(ctx,"R15",info->vm_regs.r15, loadfailout);
807
808     // Control registers
809     V3_CHKPT_LOAD(ctx, "CR0", info->ctrl_regs.cr0, loadfailout);
810     // there is no CR1
811     V3_CHKPT_LOAD(ctx, "CR2", info->ctrl_regs.cr2, loadfailout);
812     V3_CHKPT_LOAD(ctx, "CR3", info->ctrl_regs.cr3, loadfailout);
813     V3_CHKPT_LOAD(ctx, "CR4", info->ctrl_regs.cr4, loadfailout);
814     // There are no CR5,6,7
815     // CR8 is derived from apic_tpr
816     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
817     V3_CHKPT_LOAD(ctx, "CR8", tempreg, loadfailout);
818     V3_CHKPT_LOAD(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, loadfailout);
819     V3_CHKPT_LOAD(ctx, "RFLAGS", info->ctrl_regs.rflags, loadfailout);
820     V3_CHKPT_LOAD(ctx, "EFER", info->ctrl_regs.efer, loadfailout);
821
822     // Debug registers
823     V3_CHKPT_LOAD(ctx, "DR0", info->dbg_regs.dr0, loadfailout);
824     V3_CHKPT_LOAD(ctx, "DR1", info->dbg_regs.dr1, loadfailout);
825     V3_CHKPT_LOAD(ctx, "DR2", info->dbg_regs.dr2, loadfailout);
826     V3_CHKPT_LOAD(ctx, "DR3", info->dbg_regs.dr3, loadfailout);
827     // there is no DR4 or DR5
828     V3_CHKPT_LOAD(ctx, "DR6", info->dbg_regs.dr6, loadfailout);
829     V3_CHKPT_LOAD(ctx, "DR7", info->dbg_regs.dr7, loadfailout);
830
831     // Segment registers
832     V3_CHKPT_LOAD(ctx, "CS", info->segments.cs, loadfailout);
833     V3_CHKPT_LOAD(ctx, "DS", info->segments.ds, loadfailout);
834     V3_CHKPT_LOAD(ctx, "ES", info->segments.es, loadfailout);
835     V3_CHKPT_LOAD(ctx, "FS", info->segments.fs, loadfailout);
836     V3_CHKPT_LOAD(ctx, "GS", info->segments.gs, loadfailout);
837     V3_CHKPT_LOAD(ctx, "SS", info->segments.ss, loadfailout);
838     V3_CHKPT_LOAD(ctx, "LDTR", info->segments.ldtr, loadfailout);
839     V3_CHKPT_LOAD(ctx, "GDTR", info->segments.gdtr, loadfailout);
840     V3_CHKPT_LOAD(ctx, "IDTR", info->segments.idtr, loadfailout);
841     V3_CHKPT_LOAD(ctx, "TR", info->segments.tr, loadfailout);
842     
843     // several MSRs...
844     V3_CHKPT_LOAD(ctx, "STAR", info->msrs.star, loadfailout);
845     V3_CHKPT_LOAD(ctx, "LSTAR", info->msrs.lstar, loadfailout);
846     V3_CHKPT_LOAD(ctx, "SFMASK", info->msrs.sfmask, loadfailout);
847     V3_CHKPT_LOAD(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, loadfailout);
848         
849     // Some components of guest state captured in the shadow pager
850     V3_CHKPT_LOAD(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, loadfailout);
851     V3_CHKPT_LOAD(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, loadfailout);
852     V3_CHKPT_LOAD(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, loadfailout);
853
854     // floating point
855     if (v3_load_fp_state(ctx,info)) {
856       goto loadfailout;
857     }
858
859     v3_chkpt_close_ctx(ctx); ctx=0;
860
861     PrintDebug(info->vm_info, info, "Finished reading guest_info information\n");
862
863     info->cpu_mode = v3_get_vm_cpu_mode(info);
864     info->mem_mode = v3_get_vm_mem_mode(info);
865
866     if (info->shdw_pg_mode == SHADOW_PAGING) {
867         if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
868             if (v3_activate_shadow_pt(info) == -1) {
869                 PrintError(info->vm_info, info, "Failed to activate shadow page tables\n");
870                 goto loadfailout;
871             }
872         } else {
873             if (v3_activate_passthrough_pt(info) == -1) {
874                 PrintError(info->vm_info, info, "Failed to activate passthrough page tables\n");
875                 goto loadfailout;
876             }
877         }
878     }
879
880
881     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) { 
882       goto donearch;
883     }
884
885     switch (v3_mach_type) {
886         case V3_SVM_CPU:
887         case V3_SVM_REV3_CPU: {
888             char key_name[16];
889
890             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
891             ctx = v3_chkpt_open_ctx(chkpt, key_name);
892
893             if (!ctx) { 
894                 PrintError(info->vm_info, info, "Could not open context to load SVM core\n");
895                 goto loadfailout;
896             }
897             
898             if (v3_svm_load_core(info, ctx) < 0 ) {
899                 PrintError(info->vm_info, info, "Failed to patch core %d\n", info->vcpu_id);
900                 goto loadfailout;
901             }
902
903             v3_chkpt_close_ctx(ctx); ctx=0;
904
905             break;
906         }
907         case V3_VMX_CPU:
908         case V3_VMX_EPT_CPU:
909         case V3_VMX_EPT_UG_CPU: {
910             char key_name[16];
911
912             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
913
914             ctx = v3_chkpt_open_ctx(chkpt, key_name);
915
916             if (!ctx) { 
917                 PrintError(info->vm_info, info, "Could not open context to load VMX core\n");
918                 goto loadfailout;
919             }
920             
921             if (v3_vmx_load_core(info, ctx) < 0) {
922                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
923                 goto loadfailout;
924             }
925
926             v3_chkpt_close_ctx(ctx); ctx=0;
927
928             break;
929         }
930         default:
931             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
932             goto loadfailout;
933     }
934
935  donearch:
936
937     PrintDebug(info->vm_info, info, "Load of core succeeded\n");
938
939     v3_print_guest_state(info);
940
941     return 0;
942
943  loadfailout:
944     PrintError(info->vm_info, info, "Failed to load core\n");
945     if (ctx) { v3_chkpt_close_ctx(ctx);}
946     return -1;
947
948 }
949
950 // GEM5 - Hypercall for initiating transfer to gem5 (checkpoint)
951
952 static int save_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
953     extern v3_cpu_arch_t v3_mach_type;
954     void * ctx = NULL;
955     char key_name[16];
956     v3_reg_t tempreg;
957
958     PrintDebug(info->vm_info, info, "Saving core\n");
959
960     v3_print_guest_state(info);
961
962     memset(key_name, 0, 16);
963
964     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
965
966     ctx = v3_chkpt_open_ctx(chkpt, key_name);
967     
968     if (!ctx) { 
969         PrintError(info->vm_info, info, "Unable to open context to save core\n");
970         goto savefailout;
971     }
972
973     V3_CHKPT_SAVE(ctx,"run_state",info->core_run_state,savefailout);
974
975     V3_CHKPT_SAVE(ctx, "RIP", info->rip, savefailout);
976     
977     // GPRs
978     V3_CHKPT_SAVE(ctx,"RDI",info->vm_regs.rdi, savefailout); 
979     V3_CHKPT_SAVE(ctx,"RSI",info->vm_regs.rsi, savefailout); 
980     V3_CHKPT_SAVE(ctx,"RBP",info->vm_regs.rbp, savefailout); 
981     V3_CHKPT_SAVE(ctx,"RSP",info->vm_regs.rsp, savefailout); 
982     V3_CHKPT_SAVE(ctx,"RBX",info->vm_regs.rbx, savefailout); 
983     V3_CHKPT_SAVE(ctx,"RDX",info->vm_regs.rdx, savefailout); 
984     V3_CHKPT_SAVE(ctx,"RCX",info->vm_regs.rcx, savefailout); 
985     V3_CHKPT_SAVE(ctx,"RAX",info->vm_regs.rax, savefailout);
986     V3_CHKPT_SAVE(ctx,"R8",info->vm_regs.r8, savefailout);
987     V3_CHKPT_SAVE(ctx,"R9",info->vm_regs.r9, savefailout);
988     V3_CHKPT_SAVE(ctx,"R10",info->vm_regs.r10, savefailout);
989     V3_CHKPT_SAVE(ctx,"R11",info->vm_regs.r11, savefailout);
990     V3_CHKPT_SAVE(ctx,"R12",info->vm_regs.r12, savefailout);
991     V3_CHKPT_SAVE(ctx,"R13",info->vm_regs.r13, savefailout);
992     V3_CHKPT_SAVE(ctx,"R14",info->vm_regs.r14, savefailout);
993     V3_CHKPT_SAVE(ctx,"R15",info->vm_regs.r15, savefailout);
994
995     // Control registers
996     V3_CHKPT_SAVE(ctx, "CR0", info->ctrl_regs.cr0, savefailout);
997     // there is no CR1
998     V3_CHKPT_SAVE(ctx, "CR2", info->ctrl_regs.cr2, savefailout);
999     V3_CHKPT_SAVE(ctx, "CR3", info->ctrl_regs.cr3, savefailout);
1000     V3_CHKPT_SAVE(ctx, "CR4", info->ctrl_regs.cr4, savefailout);
1001     // There are no CR5,6,7
1002     // CR8 is derived from apic_tpr
1003     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
1004     V3_CHKPT_SAVE(ctx, "CR8", tempreg, savefailout);
1005     V3_CHKPT_SAVE(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, savefailout);
1006     V3_CHKPT_SAVE(ctx, "RFLAGS", info->ctrl_regs.rflags, savefailout);
1007     V3_CHKPT_SAVE(ctx, "EFER", info->ctrl_regs.efer, savefailout);
1008
1009     // Debug registers
1010     V3_CHKPT_SAVE(ctx, "DR0", info->dbg_regs.dr0, savefailout);
1011     V3_CHKPT_SAVE(ctx, "DR1", info->dbg_regs.dr1, savefailout);
1012     V3_CHKPT_SAVE(ctx, "DR2", info->dbg_regs.dr2, savefailout);
1013     V3_CHKPT_SAVE(ctx, "DR3", info->dbg_regs.dr3, savefailout);
1014     // there is no DR4 or DR5
1015     V3_CHKPT_SAVE(ctx, "DR6", info->dbg_regs.dr6, savefailout);
1016     V3_CHKPT_SAVE(ctx, "DR7", info->dbg_regs.dr7, savefailout);
1017
1018     // Segment registers
1019     V3_CHKPT_SAVE(ctx, "CS", info->segments.cs, savefailout);
1020     V3_CHKPT_SAVE(ctx, "DS", info->segments.ds, savefailout);
1021     V3_CHKPT_SAVE(ctx, "ES", info->segments.es, savefailout);
1022     V3_CHKPT_SAVE(ctx, "FS", info->segments.fs, savefailout);
1023     V3_CHKPT_SAVE(ctx, "GS", info->segments.gs, savefailout);
1024     V3_CHKPT_SAVE(ctx, "SS", info->segments.ss, savefailout);
1025     V3_CHKPT_SAVE(ctx, "LDTR", info->segments.ldtr, savefailout);
1026     V3_CHKPT_SAVE(ctx, "GDTR", info->segments.gdtr, savefailout);
1027     V3_CHKPT_SAVE(ctx, "IDTR", info->segments.idtr, savefailout);
1028     V3_CHKPT_SAVE(ctx, "TR", info->segments.tr, savefailout);
1029     
1030     // several MSRs...
1031     V3_CHKPT_SAVE(ctx, "STAR", info->msrs.star, savefailout);
1032     V3_CHKPT_SAVE(ctx, "LSTAR", info->msrs.lstar, savefailout);
1033     V3_CHKPT_SAVE(ctx, "SFMASK", info->msrs.sfmask, savefailout);
1034     V3_CHKPT_SAVE(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, savefailout);
1035         
1036     // Some components of guest state captured in the shadow pager
1037     V3_CHKPT_SAVE(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, savefailout);
1038     V3_CHKPT_SAVE(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, savefailout);
1039     V3_CHKPT_SAVE(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, savefailout);
1040
1041     // floating point
1042     if (v3_save_fp_state(ctx,info)) {
1043       goto savefailout;
1044     }
1045
1046     v3_chkpt_close_ctx(ctx); ctx=0;
1047
1048     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) {
1049       goto donearch;
1050     }
1051
1052     //Architechture specific code
1053     switch (v3_mach_type) {
1054         case V3_SVM_CPU:
1055         case V3_SVM_REV3_CPU: {
1056             char key_name[16];
1057             
1058             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
1059             
1060             ctx = v3_chkpt_open_ctx(chkpt, key_name);
1061
1062             if (!ctx) { 
1063                 PrintError(info->vm_info, info, "Could not open context to store SVM core\n");
1064                 goto savefailout;
1065             }
1066             
1067             if (v3_svm_save_core(info, ctx) < 0) {
1068                 PrintError(info->vm_info, info, "VMCB Unable to be written\n");
1069                 goto savefailout;
1070             }
1071             
1072             v3_chkpt_close_ctx(ctx); ctx=0;;
1073             break;
1074         }
1075         case V3_VMX_CPU:
1076         case V3_VMX_EPT_CPU:
1077         case V3_VMX_EPT_UG_CPU: {
1078             char key_name[16];
1079
1080             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
1081             
1082             ctx = v3_chkpt_open_ctx(chkpt, key_name);
1083             
1084             if (!ctx) { 
1085                 PrintError(info->vm_info, info, "Could not open context to store VMX core\n");
1086                 goto savefailout;
1087             }
1088
1089             if (v3_vmx_save_core(info, ctx) == -1) {
1090                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
1091                 goto savefailout;
1092             }
1093
1094             v3_chkpt_close_ctx(ctx); ctx=0;
1095
1096             break;
1097         }
1098         default:
1099             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
1100             goto savefailout;
1101             
1102     }
1103
1104  donearch:
1105     
1106     return 0;
1107
1108  savefailout:
1109     PrintError(info->vm_info, info, "Failed to save core\n");
1110     if (ctx) { v3_chkpt_close_ctx(ctx); }
1111     return -1;
1112
1113 }
1114
1115 //
1116 // GEM5 - Madhav has debug code here for printing instrucions
1117 //
1118
1119 int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1120     struct v3_chkpt * chkpt = NULL;
1121     int ret = 0;;
1122     int i = 0;
1123
1124
1125     chkpt = chkpt_open(vm, store, url, SAVE);
1126
1127     if (chkpt == NULL) {
1128         PrintError(vm, VCORE_NONE, "Error creating checkpoint store for url %s\n",url);
1129         return -1;
1130     }
1131
1132     /* If this guest is running we need to block it while the checkpoint occurs */
1133     if (vm->run_state == VM_RUNNING) {
1134         while (v3_raise_barrier(vm, NULL) == -1);
1135     }
1136
1137     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1138       if ((ret = save_memory(vm, chkpt)) == -1) {
1139         PrintError(vm, VCORE_NONE, "Unable to save memory\n");
1140         goto out;
1141       }
1142     }
1143     
1144     
1145     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1146       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1147         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1148         goto out;
1149       }
1150     }
1151
1152     if ((ret = save_header(vm, chkpt)) == -1) {
1153         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1154         goto out;
1155     }
1156
1157     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { 
1158       for (i = 0; i < vm->num_cores; i++){
1159         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1160           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1161           goto out;
1162         }
1163       }
1164     }
1165     
1166  out:
1167     
1168     /* Resume the guest if it was running */
1169     if (vm->run_state == VM_RUNNING) {
1170         v3_lower_barrier(vm);
1171     }
1172
1173     chkpt_close(chkpt);
1174
1175     return ret;
1176
1177 }
1178
1179 int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1180     struct v3_chkpt * chkpt = NULL;
1181     int i = 0;
1182     int ret = 0;
1183     
1184     chkpt = chkpt_open(vm, store, url, LOAD);
1185
1186     if (chkpt == NULL) {
1187         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1188         return -1;
1189     }
1190
1191     /* If this guest is running we need to block it while the checkpoint occurs */
1192     if (vm->run_state == VM_RUNNING) {
1193         while (v3_raise_barrier(vm, NULL) == -1);
1194     }
1195
1196     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1197       if ((ret = load_memory(vm, chkpt)) == -1) {
1198         PrintError(vm, VCORE_NONE, "Unable to load memory\n");
1199         goto out;
1200       }
1201     }
1202
1203     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1204       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1205         PrintError(vm, VCORE_NONE, "Unable to load devies\n");
1206         goto out;
1207       }
1208     }
1209
1210
1211     if ((ret = load_header(vm, chkpt)) == -1) {
1212         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1213         goto out;
1214     }
1215
1216     //per core cloning
1217     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1218       for (i = 0; i < vm->num_cores; i++) {
1219         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1220           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1221           goto out;
1222         }
1223       }
1224     }
1225
1226  out:
1227
1228     /* Resume the guest if it was running and we didn't just trash the state*/
1229     if (vm->run_state == VM_RUNNING) {
1230     
1231         if (ret == -1) {
1232             vm->run_state = VM_STOPPED;
1233         }
1234
1235         /* We check the run state of the VM after every barrier 
1236            So this will immediately halt the VM 
1237         */
1238         v3_lower_barrier(vm);
1239     }
1240
1241     chkpt_close(chkpt);
1242
1243     return ret;
1244
1245 }
1246
1247
1248 #ifdef V3_CONFIG_LIVE_MIGRATION
1249
1250 #define MOD_THRESHOLD   200  // pages below which we declare victory
1251 #define ITER_THRESHOLD  32   // iters below which we declare victory
1252
1253
1254
1255 int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1256     struct v3_chkpt * chkpt = NULL;
1257     int ret = 0;;
1258     int iter = 0;
1259     bool last_modpage_iteration=false;
1260     struct v3_bitmap modified_pages_to_send;
1261     uint64_t start_time;
1262     uint64_t stop_time;
1263     int num_mod_pages=0;
1264     struct mem_migration_state *mm_state;
1265     int i;
1266
1267     // Cores must all be in the same mode
1268     // or we must be skipping mmeory
1269     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1270       v3_paging_mode_t mode = vm->cores[0].shdw_pg_mode;
1271       for (i=1;i<vm->num_cores;i++) { 
1272         if (vm->cores[i].shdw_pg_mode != mode) { 
1273           PrintError(vm, VCORE_NONE, "Cores having different paging modes (nested and shadow) are not supported\n");
1274           return -1;
1275         }
1276       }
1277     }
1278     
1279     
1280     chkpt = chkpt_open(vm, store, url, SAVE);
1281     
1282     if (chkpt == NULL) {
1283         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1284         chkpt_close(chkpt);
1285         return -1;
1286     }
1287     
1288     if (opts & V3_CHKPT_OPT_SKIP_MEM) {
1289       goto memdone;
1290     }
1291
1292     // In a send, the memory is copied incrementally first,
1293     // followed by the remainder of the state
1294     
1295     if (v3_bitmap_init(&modified_pages_to_send,
1296                        vm->mem_size>>12 // number of pages in main region
1297                        ) == -1) {
1298         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1299         return -1;
1300     }
1301
1302     // 0. Initialize bitmap to all 1s
1303     for (i=0; i < modified_pages_to_send.num_bits; i++) {
1304         v3_bitmap_set(&modified_pages_to_send,i);
1305     }
1306
1307     iter = 0;
1308     while (!last_modpage_iteration) {
1309         PrintDebug(vm, VCORE_NONE, "Modified memory page iteration %d\n",i++);
1310         
1311         start_time = v3_get_host_time(&(vm->cores[0].time_state));
1312         
1313         // We will pause the VM for a short while
1314         // so that we can collect the set of changed pages
1315         if (v3_pause_vm(vm) == -1) {
1316             PrintError(vm, VCORE_NONE, "Could not pause VM\n");
1317             ret = -1;
1318             goto out;
1319         }
1320         
1321         if (iter==0) { 
1322             // special case, we already have the pages to send (all of them)
1323             // they are already in modified_pages_to_send
1324         } else {
1325             // normally, we are in the middle of a round
1326             // We need to copy from the current tracking bitmap
1327             // to our send bitmap
1328             v3_bitmap_copy(&modified_pages_to_send,&(mm_state->modified_pages));
1329             // and now we need to remove our tracking
1330             stop_page_tracking(mm_state);
1331         }
1332
1333         // are we done? (note that we are still paused)
1334         num_mod_pages = v3_bitmap_count(&modified_pages_to_send);
1335         if (num_mod_pages<MOD_THRESHOLD || iter>ITER_THRESHOLD) {
1336             // we are done, so we will not restart page tracking
1337             // the vm is paused, and so we should be able
1338             // to just send the data
1339             PrintDebug(vm, VCORE_NONE, "Last modified memory page iteration.\n");
1340             last_modpage_iteration = true;
1341         } else {
1342             // we are not done, so we will restart page tracking
1343             // to prepare for a second round of pages
1344             // we will resume the VM as this happens
1345             if (!(mm_state=start_page_tracking(vm))) { 
1346                 PrintError(vm, VCORE_NONE, "Error enabling page tracking.\n");
1347                 ret = -1;
1348                 goto out;
1349             }
1350             if (v3_continue_vm(vm) == -1) {
1351                 PrintError(vm, VCORE_NONE, "Error resuming the VM\n");
1352                 stop_page_tracking(mm_state);
1353                 ret = -1;
1354                 goto out;
1355             }
1356             
1357             stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1358             PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1359         }
1360         
1361
1362         // At this point, we are either paused and about to copy
1363         // the last chunk, or we are running, and will copy the last
1364         // round in parallel with current execution
1365         if (num_mod_pages>0) { 
1366             if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1367                 PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1368                 ret = -1;
1369                 goto out;
1370             }
1371         } // we don't want to copy an empty bitmap here
1372         
1373         iter++;
1374     }        
1375     
1376     if (v3_bitmap_reset(&modified_pages_to_send) == -1) {
1377         PrintError(vm, VCORE_NONE, "Error reseting bitmap.\n");
1378         ret = -1;
1379         goto out;
1380     }    
1381     
1382     // send bitmap of 0s to signal end of modpages
1383     if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1384         PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1385         ret = -1;
1386         goto out;
1387     }
1388
1389  memdone:    
1390     // save the non-memory state
1391     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1392       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1393         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1394         goto out;
1395       }
1396     }
1397
1398     if ((ret = save_header(vm, chkpt)) == -1) {
1399         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1400         goto out;
1401     }
1402     
1403     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1404       for (i = 0; i < vm->num_cores; i++){
1405         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1406           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1407           goto out;
1408         }
1409       }
1410     }
1411
1412     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1413       stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1414       PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1415       PrintDebug(vm, VCORE_NONE, "Done sending VM!\n"); 
1416     out:
1417       v3_bitmap_deinit(&modified_pages_to_send);
1418     }
1419
1420     chkpt_close(chkpt);
1421     
1422     return ret;
1423
1424 }
1425
1426 int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1427     struct v3_chkpt * chkpt = NULL;
1428     int i = 0;
1429     int ret = 0;
1430     struct v3_bitmap mod_pgs;
1431  
1432     // Currently will work only for shadow paging
1433     for (i=0;i<vm->num_cores;i++) { 
1434       if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1435         PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n");
1436         return -1;
1437       }
1438     }
1439     
1440     chkpt = chkpt_open(vm, store, url, LOAD);
1441     
1442     if (chkpt == NULL) {
1443         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1444         chkpt_close(chkpt);
1445         return -1;
1446     }
1447     
1448
1449     if (opts & V3_CHKPT_OPT_SKIP_MEM) { 
1450       goto memdone;
1451     }
1452
1453     if (v3_bitmap_init(&mod_pgs,vm->mem_size>>12) == -1) {
1454         chkpt_close(chkpt);
1455         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1456         return -1;
1457     }
1458     
1459     /* If this guest is running we need to block it while the checkpoint occurs */
1460     if (vm->run_state == VM_RUNNING) {
1461         while (v3_raise_barrier(vm, NULL) == -1);
1462     }
1463     
1464     i = 0;
1465     while(true) {
1466         // 1. Receive copy of bitmap
1467         // 2. Receive pages
1468         PrintDebug(vm, VCORE_NONE, "Memory page iteration %d\n",i++);
1469         int retval = load_inc_memory(vm, &mod_pgs, chkpt);
1470         if (retval == 1) {
1471             // end of receiving memory pages
1472             break;        
1473         } else if (retval == -1) {
1474             PrintError(vm, VCORE_NONE, "Error receiving incremental memory.\n");
1475             ret = -1;
1476             goto out;
1477         }
1478     }        
1479
1480  memdone:
1481     
1482     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { 
1483       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1484         PrintError(vm, VCORE_NONE, "Unable to load devices\n");
1485         ret = -1;
1486         goto out;
1487       }
1488     }
1489     
1490     if ((ret = load_header(vm, chkpt)) == -1) {
1491         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1492         ret = -1;
1493         goto out;
1494     }
1495     
1496     //per core cloning
1497     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1498       for (i = 0; i < vm->num_cores; i++) {
1499         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1500           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1501           goto out;
1502         }
1503       }
1504     }
1505
1506  out:
1507     if (ret==-1) { 
1508         PrintError(vm, VCORE_NONE, "Unable to receive VM\n");
1509     } else {
1510         PrintDebug(vm, VCORE_NONE, "Done receving the VM\n");
1511     }
1512         
1513         
1514     /* Resume the guest if it was running and we didn't just trash the state*/
1515     if (vm->run_state == VM_RUNNING) { 
1516         if (ret == -1) {
1517             PrintError(vm, VCORE_NONE, "VM was previously running.  It is now borked.  Pausing it. \n");
1518             vm->run_state = VM_STOPPED;
1519         }
1520             
1521         /* We check the run state of the VM after every barrier 
1522            So this will immediately halt the VM 
1523         */
1524         v3_lower_barrier(vm);
1525     } 
1526     
1527
1528     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1529       v3_bitmap_deinit(&mod_pgs);
1530     }
1531
1532     chkpt_close(chkpt);
1533
1534     return ret;
1535 }
1536
1537 #endif