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.


Further changes to support new non-contiguous memory model (checkpointing, vm informa...
[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     int i;
319
320     ctx = v3_chkpt_open_ctx(chkpt, "memory_img");
321     
322     if (!ctx) { 
323         PrintError(vm, VCORE_NONE, "Unable to open context for memory load\n");
324         return -1;
325     }
326                      
327
328     for (i=0;i<vm->mem_map.num_base_regions;i++) {
329         guest_mem_base = V3_VAddr((void *)vm->mem_map.base_regions[i].host_addr);
330         if (v3_chkpt_load(ctx, "memory_img", V3_CONFIG_MEM_BLOCK_SIZE, guest_mem_base)) {
331             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);
332             v3_chkpt_close_ctx(ctx);
333             return -1;
334         }
335     }
336     
337     v3_chkpt_close_ctx(ctx);
338
339     return 0;
340 }
341
342
343 static int save_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
344     void * guest_mem_base = NULL;
345     void * ctx = NULL;
346     uint64_t ret = 0;
347     int i;
348
349
350     ctx = v3_chkpt_open_ctx(chkpt, "memory_img");
351
352     if (!ctx) { 
353         PrintError(vm, VCORE_NONE, "Unable to open context to save memory\n");
354         return -1;
355     }
356
357     for (i=0;i<vm->mem_map.num_base_regions;i++) {
358         guest_mem_base = V3_VAddr((void *)vm->mem_map.base_regions[i].host_addr);
359         if (v3_chkpt_save(ctx, "memory_img", V3_CONFIG_MEM_BLOCK_SIZE, guest_mem_base)) {
360             PrintError(vm, VCORE_NONE, "Unable to save all of memory (region %d) (requested=%llu, received=%llu)\n",i,(uint64_t)(vm->mem_size),ret);
361             v3_chkpt_close_ctx(ctx);  
362             return -1;
363         }
364     }
365
366     v3_chkpt_close_ctx(ctx);
367
368     return 0;
369 }
370
371 #ifdef V3_CONFIG_LIVE_MIGRATION
372
373 struct mem_migration_state {
374     struct v3_vm_info *vm;
375     struct v3_bitmap  modified_pages; 
376 };
377
378 static int paging_callback(struct guest_info *core, 
379                            struct v3_shdw_pg_event *event,
380                            void      *priv_data)
381 {
382     struct mem_migration_state *m = (struct mem_migration_state *)priv_data;
383     
384     if (event->event_type==SHADOW_PAGEFAULT &&
385         event->event_order==SHADOW_PREIMPL &&
386         event->error_code.write) { 
387         addr_t gpa;
388         if (!v3_gva_to_gpa(core,event->gva,&gpa)) {
389             // write to this page
390             v3_bitmap_set(&(m->modified_pages),gpa>>12);
391         } else {
392             // no worries, this isn't physical memory
393         }
394     } else {
395         // we don't care about other events
396     }
397     
398     return 0;
399 }
400         
401
402
403 static struct mem_migration_state *start_page_tracking(struct v3_vm_info *vm)
404 {
405     struct mem_migration_state *m;
406     int i;
407
408     m = (struct mem_migration_state *)V3_Malloc(sizeof(struct mem_migration_state));
409
410     if (!m) { 
411         PrintError(vm, VCORE_NONE, "Cannot allocate\n");
412         return NULL;
413     }
414
415     m->vm=vm;
416     
417     if (v3_bitmap_init(&(m->modified_pages),vm->mem_size >> 12) == -1) { 
418         PrintError(vm, VCORE_NONE, "Failed to initialize modified_pages bit vector");
419         V3_Free(m);
420     }
421
422     v3_register_shadow_paging_event_callback(vm,paging_callback,m);
423
424     for (i=0;i<vm->num_cores;i++) {
425         v3_invalidate_shadow_pts(&(vm->cores[i]));
426     }
427     
428     // and now we should get callbacks as writes happen
429
430     return m;
431 }
432
433 static void stop_page_tracking(struct mem_migration_state *m)
434 {
435     v3_unregister_shadow_paging_event_callback(m->vm,paging_callback,m);
436     
437     v3_bitmap_deinit(&(m->modified_pages));
438     
439     V3_Free(m);
440 }
441
442             
443                 
444                                                             
445
446
447 //
448 // Returns
449 //  negative: error
450 //  zero: done with this round
451 static int save_inc_memory(struct v3_vm_info * vm, 
452                            struct v3_bitmap * mod_pgs_to_send, 
453                            struct v3_chkpt * chkpt) {
454     int page_size_bytes = 1 << 12; // assuming 4k pages right now
455     void * ctx = NULL;
456     int i = 0; 
457     int bitmap_num_bytes = (mod_pgs_to_send->num_bits / 8) 
458                            + ((mod_pgs_to_send->num_bits % 8) > 0);
459
460    
461     PrintDebug(vm, VCORE_NONE, "Saving incremental memory.\n");
462
463     ctx = v3_chkpt_open_ctx(chkpt,"memory_bitmap_bits");
464
465     if (!ctx) { 
466         PrintError(vm, VCORE_NONE, "Cannot open context for dirty memory bitmap\n");
467         return -1;
468     }
469         
470
471     if (v3_chkpt_save(ctx,
472                       "memory_bitmap_bits",
473                       bitmap_num_bytes,
474                       mod_pgs_to_send->bits)) {
475         PrintError(vm, VCORE_NONE, "Unable to write all of the dirty memory bitmap\n");
476         v3_chkpt_close_ctx(ctx);
477         return -1;
478     }
479
480     v3_chkpt_close_ctx(ctx);
481
482     PrintDebug(vm, VCORE_NONE, "Sent bitmap bits.\n");
483
484     // Dirty memory pages are sent in bitmap order
485     for (i = 0; i < mod_pgs_to_send->num_bits; i++) {
486         if (v3_bitmap_check(mod_pgs_to_send, i)) {
487             struct v3_mem_region *region = v3_get_base_region(vm,page_size_bytes * i);
488             if (!region) { 
489                 PrintError(vm, VCORE_NONE, "Failed to find base region for page %d\n",i);
490                 return -1;
491             }
492             // PrintDebug(vm, VCORE_NONE, "Sending memory page %d.\n",i);
493             ctx = v3_chkpt_open_ctx(chkpt, "memory_page");
494             if (!ctx) { 
495                 PrintError(vm, VCORE_NONE, "Unable to open context to send memory page\n");
496                 return -1;
497             }
498             if (v3_chkpt_save(ctx, 
499                               "memory_page", 
500                               page_size_bytes,
501                               (void*)(region->host_addr + page_size_bytes * i - region->guest_start))) {
502                 PrintError(vm, VCORE_NONE, "Unable to send a memory page\n");
503                 v3_chkpt_close_ctx(ctx);
504                 return -1;
505             }
506             
507             v3_chkpt_close_ctx(ctx);
508         }
509     } 
510     
511     return 0;
512 }
513
514
515 //
516 // returns:
517 //  negative: error
518 //  zero: ok, but not done
519 //  positive: ok, and also done
520 static int load_inc_memory(struct v3_vm_info * vm, 
521                            struct v3_bitmap * mod_pgs,
522                            struct v3_chkpt * chkpt) {
523     int page_size_bytes = 1 << 12; // assuming 4k pages right now
524     void * ctx = NULL;
525     int i = 0; 
526     bool empty_bitmap = true;
527     int bitmap_num_bytes = (mod_pgs->num_bits / 8) 
528                            + ((mod_pgs->num_bits % 8) > 0);
529
530
531     ctx = v3_chkpt_open_ctx(chkpt, "memory_bitmap_bits");
532
533     if (!ctx) { 
534         PrintError(vm, VCORE_NONE, "Cannot open context to receive memory bitmap\n");
535         return -1;
536     }
537
538     if (v3_chkpt_load(ctx,
539                       "memory_bitmap_bits",
540                       bitmap_num_bytes,
541                       mod_pgs->bits)) {
542         PrintError(vm, VCORE_NONE, "Did not receive all of memory bitmap\n");
543         v3_chkpt_close_ctx(ctx);
544         return -1;
545     }
546     
547     v3_chkpt_close_ctx(ctx);
548
549     // Receive also follows bitmap order
550     for (i = 0; i < mod_pgs->num_bits; i ++) {
551         if (v3_bitmap_check(mod_pgs, i)) {
552             struct v3_mem_region *region = v3_get_base_region(vm,page_size_bytes * i);
553             if (!region) { 
554                 PrintError(vm, VCORE_NONE, "Failed to find base region for page %d\n",i);
555                 return -1;
556             }
557             //PrintDebug(vm, VCORE_NONE, "Loading page %d\n", i);
558             empty_bitmap = false;
559             ctx = v3_chkpt_open_ctx(chkpt, "memory_page");
560             if (!ctx) { 
561                 PrintError(vm, VCORE_NONE, "Cannot open context to receive memory page\n");
562                 return -1;
563             }
564             
565             if (v3_chkpt_load(ctx, 
566                               "memory_page", 
567                               page_size_bytes,
568                               (void*)(region->host_addr + page_size_bytes * i - region->guest_start))) {
569                 PrintError(vm, VCORE_NONE, "Did not receive all of memory page\n");
570                 v3_chkpt_close_ctx(ctx);
571                 return -1;
572             }
573             v3_chkpt_close_ctx(ctx);
574         }
575     } 
576     
577     if (empty_bitmap) {
578         // signal end of receiving pages
579         PrintDebug(vm, VCORE_NONE, "Finished receiving pages.\n");
580         return 1;
581     } else {
582         // need to run again
583         return 0;
584     }
585
586 }
587
588 #endif
589
590 int save_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
591     extern v3_cpu_arch_t v3_mach_type;
592     void * ctx = NULL;
593     
594     ctx = v3_chkpt_open_ctx(chkpt, "header");
595     if (!ctx) { 
596         PrintError(vm, VCORE_NONE, "Cannot open context to save header\n");
597         return -1;
598     }
599
600     switch (v3_mach_type) {
601         case V3_SVM_CPU:
602         case V3_SVM_REV3_CPU: {
603             if (v3_chkpt_save(ctx, "header", strlen(svm_chkpt_header), svm_chkpt_header)) { 
604                 PrintError(vm, VCORE_NONE, "Could not save all of SVM header\n");
605                 v3_chkpt_close_ctx(ctx);
606                 return -1;
607             }
608             break;
609         }
610         case V3_VMX_CPU:
611         case V3_VMX_EPT_CPU:
612         case V3_VMX_EPT_UG_CPU: {
613             if (v3_chkpt_save(ctx, "header", strlen(vmx_chkpt_header), vmx_chkpt_header)) { 
614                 PrintError(vm, VCORE_NONE, "Could not save all of VMX header\n");
615                 v3_chkpt_close_ctx(ctx);
616                 return -1;
617             }
618             break;
619         }
620         default:
621             PrintError(vm, VCORE_NONE, "checkpoint not supported on this architecture\n");
622             v3_chkpt_close_ctx(ctx);
623             return -1;
624     }
625
626     v3_chkpt_close_ctx(ctx);
627             
628     return 0;
629 }
630
631 static int load_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
632     extern v3_cpu_arch_t v3_mach_type;
633     void * ctx = NULL;
634     
635     ctx = v3_chkpt_open_ctx(chkpt, "header");
636
637     switch (v3_mach_type) {
638         case V3_SVM_CPU:
639         case V3_SVM_REV3_CPU: {
640             char header[strlen(svm_chkpt_header) + 1];
641          
642             if (v3_chkpt_load(ctx, "header", strlen(svm_chkpt_header), header)) {
643                 PrintError(vm, VCORE_NONE, "Could not load all of SVM header\n");
644                 v3_chkpt_close_ctx(ctx);
645                 return -1;
646             }
647             
648             header[strlen(svm_chkpt_header)] = 0;
649
650             break;
651         }
652         case V3_VMX_CPU:
653         case V3_VMX_EPT_CPU:
654         case V3_VMX_EPT_UG_CPU: {
655             char header[strlen(vmx_chkpt_header) + 1];
656             
657             if (v3_chkpt_load(ctx, "header", strlen(vmx_chkpt_header), header)) {
658                 PrintError(vm, VCORE_NONE, "Could not load all of VMX header\n");
659                 v3_chkpt_close_ctx(ctx);
660                 return -1;
661             }
662             
663             header[strlen(vmx_chkpt_header)] = 0;
664             
665             break;
666         }
667         default:
668             PrintError(vm, VCORE_NONE, "checkpoint not supported on this architecture\n");
669             v3_chkpt_close_ctx(ctx);
670             return -1;
671     }
672     
673     v3_chkpt_close_ctx(ctx);
674     
675     return 0;
676 }
677
678
679 static int load_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
680     extern v3_cpu_arch_t v3_mach_type;
681     void * ctx = NULL;
682     char key_name[16];
683     v3_reg_t tempreg;
684
685     PrintDebug(info->vm_info, info, "Loading core\n");
686
687     memset(key_name, 0, 16);
688
689     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
690
691     ctx = v3_chkpt_open_ctx(chkpt, key_name);
692
693     if (!ctx) { 
694         PrintError(info->vm_info, info, "Could not open context to load core\n");
695         goto loadfailout;
696     }
697
698     V3_CHKPT_LOAD(ctx, "RIP", info->rip, loadfailout);
699     
700     // GPRs
701     V3_CHKPT_LOAD(ctx,"RDI",info->vm_regs.rdi, loadfailout); 
702     V3_CHKPT_LOAD(ctx,"RSI",info->vm_regs.rsi, loadfailout); 
703     V3_CHKPT_LOAD(ctx,"RBP",info->vm_regs.rbp, loadfailout); 
704     V3_CHKPT_LOAD(ctx,"RSP",info->vm_regs.rsp, loadfailout); 
705     V3_CHKPT_LOAD(ctx,"RBX",info->vm_regs.rbx, loadfailout); 
706     V3_CHKPT_LOAD(ctx,"RDX",info->vm_regs.rdx, loadfailout); 
707     V3_CHKPT_LOAD(ctx,"RCX",info->vm_regs.rcx, loadfailout); 
708     V3_CHKPT_LOAD(ctx,"RAX",info->vm_regs.rax, loadfailout);
709     V3_CHKPT_LOAD(ctx,"R8",info->vm_regs.r8, loadfailout);
710     V3_CHKPT_LOAD(ctx,"R9",info->vm_regs.r9, loadfailout);
711     V3_CHKPT_LOAD(ctx,"R10",info->vm_regs.r10, loadfailout);
712     V3_CHKPT_LOAD(ctx,"R11",info->vm_regs.r11, loadfailout);
713     V3_CHKPT_LOAD(ctx,"R12",info->vm_regs.r12, loadfailout);
714     V3_CHKPT_LOAD(ctx,"R13",info->vm_regs.r13, loadfailout);
715     V3_CHKPT_LOAD(ctx,"R14",info->vm_regs.r14, loadfailout);
716     V3_CHKPT_LOAD(ctx,"R15",info->vm_regs.r15, loadfailout);
717
718     // Control registers
719     V3_CHKPT_LOAD(ctx, "CR0", info->ctrl_regs.cr0, loadfailout);
720     // there is no CR1
721     V3_CHKPT_LOAD(ctx, "CR2", info->ctrl_regs.cr2, loadfailout);
722     V3_CHKPT_LOAD(ctx, "CR3", info->ctrl_regs.cr3, loadfailout);
723     V3_CHKPT_LOAD(ctx, "CR4", info->ctrl_regs.cr4, loadfailout);
724     // There are no CR5,6,7
725     // CR8 is derived from apic_tpr
726     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
727     V3_CHKPT_LOAD(ctx, "CR8", tempreg, loadfailout);
728     V3_CHKPT_LOAD(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, loadfailout);
729     V3_CHKPT_LOAD(ctx, "RFLAGS", info->ctrl_regs.rflags, loadfailout);
730     V3_CHKPT_LOAD(ctx, "EFER", info->ctrl_regs.efer, loadfailout);
731
732     // Debug registers
733     V3_CHKPT_LOAD(ctx, "DR0", info->dbg_regs.dr0, loadfailout);
734     V3_CHKPT_LOAD(ctx, "DR1", info->dbg_regs.dr1, loadfailout);
735     V3_CHKPT_LOAD(ctx, "DR2", info->dbg_regs.dr2, loadfailout);
736     V3_CHKPT_LOAD(ctx, "DR3", info->dbg_regs.dr3, loadfailout);
737     // there is no DR4 or DR5
738     V3_CHKPT_LOAD(ctx, "DR6", info->dbg_regs.dr6, loadfailout);
739     V3_CHKPT_LOAD(ctx, "DR7", info->dbg_regs.dr7, loadfailout);
740
741     // Segment registers
742     V3_CHKPT_LOAD(ctx, "CS", info->segments.cs, loadfailout);
743     V3_CHKPT_LOAD(ctx, "DS", info->segments.ds, loadfailout);
744     V3_CHKPT_LOAD(ctx, "ES", info->segments.es, loadfailout);
745     V3_CHKPT_LOAD(ctx, "FS", info->segments.fs, loadfailout);
746     V3_CHKPT_LOAD(ctx, "GS", info->segments.gs, loadfailout);
747     V3_CHKPT_LOAD(ctx, "SS", info->segments.ss, loadfailout);
748     V3_CHKPT_LOAD(ctx, "LDTR", info->segments.ldtr, loadfailout);
749     V3_CHKPT_LOAD(ctx, "GDTR", info->segments.gdtr, loadfailout);
750     V3_CHKPT_LOAD(ctx, "IDTR", info->segments.idtr, loadfailout);
751     V3_CHKPT_LOAD(ctx, "TR", info->segments.tr, loadfailout);
752     
753     // several MSRs...
754     V3_CHKPT_LOAD(ctx, "STAR", info->msrs.star, loadfailout);
755     V3_CHKPT_LOAD(ctx, "LSTAR", info->msrs.lstar, loadfailout);
756     V3_CHKPT_LOAD(ctx, "SFMASK", info->msrs.sfmask, loadfailout);
757     V3_CHKPT_LOAD(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, loadfailout);
758         
759     // Some components of guest state captured in the shadow pager
760     V3_CHKPT_LOAD(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, loadfailout);
761     V3_CHKPT_LOAD(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, loadfailout);
762     V3_CHKPT_LOAD(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, loadfailout);
763
764     v3_chkpt_close_ctx(ctx); ctx=0;
765
766     PrintDebug(info->vm_info, info, "Finished reading guest_info information\n");
767
768     info->cpu_mode = v3_get_vm_cpu_mode(info);
769     info->mem_mode = v3_get_vm_mem_mode(info);
770
771     if (info->shdw_pg_mode == SHADOW_PAGING) {
772         if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
773             if (v3_activate_shadow_pt(info) == -1) {
774                 PrintError(info->vm_info, info, "Failed to activate shadow page tables\n");
775                 goto loadfailout;
776             }
777         } else {
778             if (v3_activate_passthrough_pt(info) == -1) {
779                 PrintError(info->vm_info, info, "Failed to activate passthrough page tables\n");
780                 goto loadfailout;
781             }
782         }
783     }
784
785
786     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) { 
787       goto donearch;
788     }
789
790     switch (v3_mach_type) {
791         case V3_SVM_CPU:
792         case V3_SVM_REV3_CPU: {
793             char key_name[16];
794
795             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
796             ctx = v3_chkpt_open_ctx(chkpt, key_name);
797
798             if (!ctx) { 
799                 PrintError(info->vm_info, info, "Could not open context to load SVM core\n");
800                 goto loadfailout;
801             }
802             
803             if (v3_svm_load_core(info, ctx) < 0 ) {
804                 PrintError(info->vm_info, info, "Failed to patch core %d\n", info->vcpu_id);
805                 goto loadfailout;
806             }
807
808             v3_chkpt_close_ctx(ctx); ctx=0;
809
810             break;
811         }
812         case V3_VMX_CPU:
813         case V3_VMX_EPT_CPU:
814         case V3_VMX_EPT_UG_CPU: {
815             char key_name[16];
816
817             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
818
819             ctx = v3_chkpt_open_ctx(chkpt, key_name);
820
821             if (!ctx) { 
822                 PrintError(info->vm_info, info, "Could not open context to load VMX core\n");
823                 goto loadfailout;
824             }
825             
826             if (v3_vmx_load_core(info, ctx) < 0) {
827                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
828                 goto loadfailout;
829             }
830
831             v3_chkpt_close_ctx(ctx); ctx=0;
832
833             break;
834         }
835         default:
836             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
837             goto loadfailout;
838     }
839
840  donearch:
841
842     PrintDebug(info->vm_info, info, "Load of core succeeded\n");
843
844     v3_print_guest_state(info);
845
846     return 0;
847
848  loadfailout:
849     PrintError(info->vm_info, info, "Failed to load core\n");
850     if (ctx) { v3_chkpt_close_ctx(ctx);}
851     return -1;
852
853 }
854
855 // GEM5 - Hypercall for initiating transfer to gem5 (checkpoint)
856
857 static int save_core(struct guest_info * info, struct v3_chkpt * chkpt, v3_chkpt_options_t opts) {
858     extern v3_cpu_arch_t v3_mach_type;
859     void * ctx = NULL;
860     char key_name[16];
861     v3_reg_t tempreg;
862
863     PrintDebug(info->vm_info, info, "Saving core\n");
864
865     v3_print_guest_state(info);
866
867     memset(key_name, 0, 16);
868
869     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
870
871     ctx = v3_chkpt_open_ctx(chkpt, key_name);
872     
873     if (!ctx) { 
874         PrintError(info->vm_info, info, "Unable to open context to save core\n");
875         goto savefailout;
876     }
877
878
879     V3_CHKPT_SAVE(ctx, "RIP", info->rip, savefailout);
880     
881     // GPRs
882     V3_CHKPT_SAVE(ctx,"RDI",info->vm_regs.rdi, savefailout); 
883     V3_CHKPT_SAVE(ctx,"RSI",info->vm_regs.rsi, savefailout); 
884     V3_CHKPT_SAVE(ctx,"RBP",info->vm_regs.rbp, savefailout); 
885     V3_CHKPT_SAVE(ctx,"RSP",info->vm_regs.rsp, savefailout); 
886     V3_CHKPT_SAVE(ctx,"RBX",info->vm_regs.rbx, savefailout); 
887     V3_CHKPT_SAVE(ctx,"RDX",info->vm_regs.rdx, savefailout); 
888     V3_CHKPT_SAVE(ctx,"RCX",info->vm_regs.rcx, savefailout); 
889     V3_CHKPT_SAVE(ctx,"RAX",info->vm_regs.rax, savefailout);
890     V3_CHKPT_SAVE(ctx,"R8",info->vm_regs.r8, savefailout);
891     V3_CHKPT_SAVE(ctx,"R9",info->vm_regs.r9, savefailout);
892     V3_CHKPT_SAVE(ctx,"R10",info->vm_regs.r10, savefailout);
893     V3_CHKPT_SAVE(ctx,"R11",info->vm_regs.r11, savefailout);
894     V3_CHKPT_SAVE(ctx,"R12",info->vm_regs.r12, savefailout);
895     V3_CHKPT_SAVE(ctx,"R13",info->vm_regs.r13, savefailout);
896     V3_CHKPT_SAVE(ctx,"R14",info->vm_regs.r14, savefailout);
897     V3_CHKPT_SAVE(ctx,"R15",info->vm_regs.r15, savefailout);
898
899     // Control registers
900     V3_CHKPT_SAVE(ctx, "CR0", info->ctrl_regs.cr0, savefailout);
901     // there is no CR1
902     V3_CHKPT_SAVE(ctx, "CR2", info->ctrl_regs.cr2, savefailout);
903     V3_CHKPT_SAVE(ctx, "CR3", info->ctrl_regs.cr3, savefailout);
904     V3_CHKPT_SAVE(ctx, "CR4", info->ctrl_regs.cr4, savefailout);
905     // There are no CR5,6,7
906     // CR8 is derived from apic_tpr
907     tempreg = (info->ctrl_regs.apic_tpr >> 4) & 0xf;
908     V3_CHKPT_SAVE(ctx, "CR8", tempreg, savefailout);
909     V3_CHKPT_SAVE(ctx, "APIC_TPR", info->ctrl_regs.apic_tpr, savefailout);
910     V3_CHKPT_SAVE(ctx, "RFLAGS", info->ctrl_regs.rflags, savefailout);
911     V3_CHKPT_SAVE(ctx, "EFER", info->ctrl_regs.efer, savefailout);
912
913     // Debug registers
914     V3_CHKPT_SAVE(ctx, "DR0", info->dbg_regs.dr0, savefailout);
915     V3_CHKPT_SAVE(ctx, "DR1", info->dbg_regs.dr1, savefailout);
916     V3_CHKPT_SAVE(ctx, "DR2", info->dbg_regs.dr2, savefailout);
917     V3_CHKPT_SAVE(ctx, "DR3", info->dbg_regs.dr3, savefailout);
918     // there is no DR4 or DR5
919     V3_CHKPT_SAVE(ctx, "DR6", info->dbg_regs.dr6, savefailout);
920     V3_CHKPT_SAVE(ctx, "DR7", info->dbg_regs.dr7, savefailout);
921
922     // Segment registers
923     V3_CHKPT_SAVE(ctx, "CS", info->segments.cs, savefailout);
924     V3_CHKPT_SAVE(ctx, "DS", info->segments.ds, savefailout);
925     V3_CHKPT_SAVE(ctx, "ES", info->segments.es, savefailout);
926     V3_CHKPT_SAVE(ctx, "FS", info->segments.fs, savefailout);
927     V3_CHKPT_SAVE(ctx, "GS", info->segments.gs, savefailout);
928     V3_CHKPT_SAVE(ctx, "SS", info->segments.ss, savefailout);
929     V3_CHKPT_SAVE(ctx, "LDTR", info->segments.ldtr, savefailout);
930     V3_CHKPT_SAVE(ctx, "GDTR", info->segments.gdtr, savefailout);
931     V3_CHKPT_SAVE(ctx, "IDTR", info->segments.idtr, savefailout);
932     V3_CHKPT_SAVE(ctx, "TR", info->segments.tr, savefailout);
933     
934     // several MSRs...
935     V3_CHKPT_SAVE(ctx, "STAR", info->msrs.star, savefailout);
936     V3_CHKPT_SAVE(ctx, "LSTAR", info->msrs.lstar, savefailout);
937     V3_CHKPT_SAVE(ctx, "SFMASK", info->msrs.sfmask, savefailout);
938     V3_CHKPT_SAVE(ctx, "KERN_GS_BASE", info->msrs.kern_gs_base, savefailout);
939         
940     // Some components of guest state captured in the shadow pager
941     V3_CHKPT_SAVE(ctx, "GUEST_CR3", info->shdw_pg_state.guest_cr3, savefailout);
942     V3_CHKPT_SAVE(ctx, "GUEST_CR0", info->shdw_pg_state.guest_cr0, savefailout);
943     V3_CHKPT_SAVE(ctx, "GUEST_EFER", info->shdw_pg_state.guest_efer, savefailout);
944
945     v3_chkpt_close_ctx(ctx); ctx=0;
946
947     if (opts & V3_CHKPT_OPT_SKIP_ARCHDEP) {
948       goto donearch;
949     }
950
951     //Architechture specific code
952     switch (v3_mach_type) {
953         case V3_SVM_CPU:
954         case V3_SVM_REV3_CPU: {
955             char key_name[16];
956             
957             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
958             
959             ctx = v3_chkpt_open_ctx(chkpt, key_name);
960
961             if (!ctx) { 
962                 PrintError(info->vm_info, info, "Could not open context to store SVM core\n");
963                 goto savefailout;
964             }
965             
966             if (v3_svm_save_core(info, ctx) < 0) {
967                 PrintError(info->vm_info, info, "VMCB Unable to be written\n");
968                 goto savefailout;
969             }
970             
971             v3_chkpt_close_ctx(ctx); ctx=0;;
972             break;
973         }
974         case V3_VMX_CPU:
975         case V3_VMX_EPT_CPU:
976         case V3_VMX_EPT_UG_CPU: {
977             char key_name[16];
978
979             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
980             
981             ctx = v3_chkpt_open_ctx(chkpt, key_name);
982             
983             if (!ctx) { 
984                 PrintError(info->vm_info, info, "Could not open context to store VMX core\n");
985                 goto savefailout;
986             }
987
988             if (v3_vmx_save_core(info, ctx) == -1) {
989                 PrintError(info->vm_info, info, "VMX checkpoint failed\n");
990                 goto savefailout;
991             }
992
993             v3_chkpt_close_ctx(ctx); ctx=0;
994
995             break;
996         }
997         default:
998             PrintError(info->vm_info, info, "Invalid CPU Type (%d)\n", v3_mach_type);
999             goto savefailout;
1000             
1001     }
1002
1003  donearch:
1004     
1005     return 0;
1006
1007  savefailout:
1008     PrintError(info->vm_info, info, "Failed to save core\n");
1009     if (ctx) { v3_chkpt_close_ctx(ctx); }
1010     return -1;
1011
1012 }
1013
1014 //
1015 // GEM5 - Madhav has debug code here for printing instrucions
1016 //
1017
1018 int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1019     struct v3_chkpt * chkpt = NULL;
1020     int ret = 0;;
1021     int i = 0;
1022
1023
1024     chkpt = chkpt_open(vm, store, url, SAVE);
1025
1026     if (chkpt == NULL) {
1027         PrintError(vm, VCORE_NONE, "Error creating checkpoint store for url %s\n",url);
1028         return -1;
1029     }
1030
1031     /* If this guest is running we need to block it while the checkpoint occurs */
1032     if (vm->run_state == VM_RUNNING) {
1033         while (v3_raise_barrier(vm, NULL) == -1);
1034     }
1035
1036     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1037       if ((ret = save_memory(vm, chkpt)) == -1) {
1038         PrintError(vm, VCORE_NONE, "Unable to save memory\n");
1039         goto out;
1040       }
1041     }
1042     
1043     
1044     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1045       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1046         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1047         goto out;
1048       }
1049     }
1050
1051     if ((ret = save_header(vm, chkpt)) == -1) {
1052         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1053         goto out;
1054     }
1055
1056     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) { 
1057       for (i = 0; i < vm->num_cores; i++){
1058         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1059           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1060           goto out;
1061         }
1062       }
1063     }
1064     
1065  out:
1066     
1067     /* Resume the guest if it was running */
1068     if (vm->run_state == VM_RUNNING) {
1069         v3_lower_barrier(vm);
1070     }
1071
1072     chkpt_close(chkpt);
1073
1074     return ret;
1075
1076 }
1077
1078 int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1079     struct v3_chkpt * chkpt = NULL;
1080     int i = 0;
1081     int ret = 0;
1082     
1083     chkpt = chkpt_open(vm, store, url, LOAD);
1084
1085     if (chkpt == NULL) {
1086         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1087         return -1;
1088     }
1089
1090     /* If this guest is running we need to block it while the checkpoint occurs */
1091     if (vm->run_state == VM_RUNNING) {
1092         while (v3_raise_barrier(vm, NULL) == -1);
1093     }
1094
1095     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1096       if ((ret = load_memory(vm, chkpt)) == -1) {
1097         PrintError(vm, VCORE_NONE, "Unable to load memory\n");
1098         goto out;
1099       }
1100     }
1101
1102     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1103       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1104         PrintError(vm, VCORE_NONE, "Unable to load devies\n");
1105         goto out;
1106       }
1107     }
1108
1109
1110     if ((ret = load_header(vm, chkpt)) == -1) {
1111         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1112         goto out;
1113     }
1114
1115     //per core cloning
1116     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1117       for (i = 0; i < vm->num_cores; i++) {
1118         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1119           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1120           goto out;
1121         }
1122       }
1123     }
1124
1125  out:
1126
1127     /* Resume the guest if it was running and we didn't just trash the state*/
1128     if (vm->run_state == VM_RUNNING) {
1129     
1130         if (ret == -1) {
1131             vm->run_state = VM_STOPPED;
1132         }
1133
1134         /* We check the run state of the VM after every barrier 
1135            So this will immediately halt the VM 
1136         */
1137         v3_lower_barrier(vm);
1138     }
1139
1140     chkpt_close(chkpt);
1141
1142     return ret;
1143
1144 }
1145
1146
1147 #ifdef V3_CONFIG_LIVE_MIGRATION
1148
1149 #define MOD_THRESHOLD   200  // pages below which we declare victory
1150 #define ITER_THRESHOLD  32   // iters below which we declare victory
1151
1152
1153
1154 int v3_chkpt_send_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1155     struct v3_chkpt * chkpt = NULL;
1156     int ret = 0;;
1157     int iter = 0;
1158     bool last_modpage_iteration=false;
1159     struct v3_bitmap modified_pages_to_send;
1160     uint64_t start_time;
1161     uint64_t stop_time;
1162     int num_mod_pages=0;
1163     struct mem_migration_state *mm_state;
1164     int i;
1165
1166     // Currently will work only for shadow paging
1167     for (i=0;i<vm->num_cores;i++) { 
1168       if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1169         PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n");
1170         return -1;
1171       }
1172     }
1173     
1174     
1175     chkpt = chkpt_open(vm, store, url, SAVE);
1176     
1177     if (chkpt == NULL) {
1178         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1179         chkpt_close(chkpt);
1180         return -1;
1181     }
1182     
1183     if (opts & V3_CHKPT_OPT_SKIP_MEM) {
1184       goto memdone;
1185     }
1186
1187     // In a send, the memory is copied incrementally first,
1188     // followed by the remainder of the state
1189     
1190     if (v3_bitmap_init(&modified_pages_to_send,
1191                        vm->mem_size>>12 // number of pages in main region
1192                        ) == -1) {
1193         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1194         return -1;
1195     }
1196
1197     // 0. Initialize bitmap to all 1s
1198     for (i=0; i < modified_pages_to_send.num_bits; i++) {
1199         v3_bitmap_set(&modified_pages_to_send,i);
1200     }
1201
1202     iter = 0;
1203     while (!last_modpage_iteration) {
1204         PrintDebug(vm, VCORE_NONE, "Modified memory page iteration %d\n",i++);
1205         
1206         start_time = v3_get_host_time(&(vm->cores[0].time_state));
1207         
1208         // We will pause the VM for a short while
1209         // so that we can collect the set of changed pages
1210         if (v3_pause_vm(vm) == -1) {
1211             PrintError(vm, VCORE_NONE, "Could not pause VM\n");
1212             ret = -1;
1213             goto out;
1214         }
1215         
1216         if (iter==0) { 
1217             // special case, we already have the pages to send (all of them)
1218             // they are already in modified_pages_to_send
1219         } else {
1220             // normally, we are in the middle of a round
1221             // We need to copy from the current tracking bitmap
1222             // to our send bitmap
1223             v3_bitmap_copy(&modified_pages_to_send,&(mm_state->modified_pages));
1224             // and now we need to remove our tracking
1225             stop_page_tracking(mm_state);
1226         }
1227
1228         // are we done? (note that we are still paused)
1229         num_mod_pages = v3_bitmap_count(&modified_pages_to_send);
1230         if (num_mod_pages<MOD_THRESHOLD || iter>ITER_THRESHOLD) {
1231             // we are done, so we will not restart page tracking
1232             // the vm is paused, and so we should be able
1233             // to just send the data
1234             PrintDebug(vm, VCORE_NONE, "Last modified memory page iteration.\n");
1235             last_modpage_iteration = true;
1236         } else {
1237             // we are not done, so we will restart page tracking
1238             // to prepare for a second round of pages
1239             // we will resume the VM as this happens
1240             if (!(mm_state=start_page_tracking(vm))) { 
1241                 PrintError(vm, VCORE_NONE, "Error enabling page tracking.\n");
1242                 ret = -1;
1243                 goto out;
1244             }
1245             if (v3_continue_vm(vm) == -1) {
1246                 PrintError(vm, VCORE_NONE, "Error resuming the VM\n");
1247                 stop_page_tracking(mm_state);
1248                 ret = -1;
1249                 goto out;
1250             }
1251             
1252             stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1253             PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1254         }
1255         
1256
1257         // At this point, we are either paused and about to copy
1258         // the last chunk, or we are running, and will copy the last
1259         // round in parallel with current execution
1260         if (num_mod_pages>0) { 
1261             if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1262                 PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1263                 ret = -1;
1264                 goto out;
1265             }
1266         } // we don't want to copy an empty bitmap here
1267         
1268         iter++;
1269     }        
1270     
1271     if (v3_bitmap_reset(&modified_pages_to_send) == -1) {
1272         PrintError(vm, VCORE_NONE, "Error reseting bitmap.\n");
1273         ret = -1;
1274         goto out;
1275     }    
1276     
1277     // send bitmap of 0s to signal end of modpages
1278     if (save_inc_memory(vm, &modified_pages_to_send, chkpt) == -1) {
1279         PrintError(vm, VCORE_NONE, "Error sending incremental memory.\n");
1280         ret = -1;
1281         goto out;
1282     }
1283
1284  memdone:    
1285     // save the non-memory state
1286     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) {
1287       if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
1288         PrintError(vm, VCORE_NONE, "Unable to save devices\n");
1289         goto out;
1290       }
1291     }
1292
1293     if ((ret = save_header(vm, chkpt)) == -1) {
1294         PrintError(vm, VCORE_NONE, "Unable to save header\n");
1295         goto out;
1296     }
1297     
1298     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1299       for (i = 0; i < vm->num_cores; i++){
1300         if ((ret = save_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1301           PrintError(vm, VCORE_NONE, "chkpt of core %d failed\n", i);
1302           goto out;
1303         }
1304       }
1305     }
1306
1307     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) {
1308       stop_time = v3_get_host_time(&(vm->cores[0].time_state));
1309       PrintDebug(vm, VCORE_NONE, "num_mod_pages=%d\ndowntime=%llu\n",num_mod_pages,stop_time-start_time);
1310       PrintDebug(vm, VCORE_NONE, "Done sending VM!\n"); 
1311     out:
1312       v3_bitmap_deinit(&modified_pages_to_send);
1313     }
1314
1315     chkpt_close(chkpt);
1316     
1317     return ret;
1318
1319 }
1320
1321 int v3_chkpt_receive_vm(struct v3_vm_info * vm, char * store, char * url, v3_chkpt_options_t opts) {
1322     struct v3_chkpt * chkpt = NULL;
1323     int i = 0;
1324     int ret = 0;
1325     struct v3_bitmap mod_pgs;
1326  
1327     // Currently will work only for shadow paging
1328     for (i=0;i<vm->num_cores;i++) { 
1329       if (vm->cores[i].shdw_pg_mode!=SHADOW_PAGING && !(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1330         PrintError(vm, VCORE_NONE, "Cannot currently handle nested paging\n");
1331         return -1;
1332       }
1333     }
1334     
1335     chkpt = chkpt_open(vm, store, url, LOAD);
1336     
1337     if (chkpt == NULL) {
1338         PrintError(vm, VCORE_NONE, "Error creating checkpoint store\n");
1339         chkpt_close(chkpt);
1340         return -1;
1341     }
1342     
1343
1344     if (opts & V3_CHKPT_OPT_SKIP_MEM) { 
1345       goto memdone;
1346     }
1347
1348     if (v3_bitmap_init(&mod_pgs,vm->mem_size>>12) == -1) {
1349         chkpt_close(chkpt);
1350         PrintError(vm, VCORE_NONE, "Could not intialize bitmap.\n");
1351         return -1;
1352     }
1353     
1354     /* If this guest is running we need to block it while the checkpoint occurs */
1355     if (vm->run_state == VM_RUNNING) {
1356         while (v3_raise_barrier(vm, NULL) == -1);
1357     }
1358     
1359     i = 0;
1360     while(true) {
1361         // 1. Receive copy of bitmap
1362         // 2. Receive pages
1363         PrintDebug(vm, VCORE_NONE, "Memory page iteration %d\n",i++);
1364         int retval = load_inc_memory(vm, &mod_pgs, chkpt);
1365         if (retval == 1) {
1366             // end of receiving memory pages
1367             break;        
1368         } else if (retval == -1) {
1369             PrintError(vm, VCORE_NONE, "Error receiving incremental memory.\n");
1370             ret = -1;
1371             goto out;
1372         }
1373     }        
1374
1375  memdone:
1376     
1377     if (!(opts & V3_CHKPT_OPT_SKIP_DEVS)) { 
1378       if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
1379         PrintError(vm, VCORE_NONE, "Unable to load devices\n");
1380         ret = -1;
1381         goto out;
1382       }
1383     }
1384     
1385     if ((ret = load_header(vm, chkpt)) == -1) {
1386         PrintError(vm, VCORE_NONE, "Unable to load header\n");
1387         ret = -1;
1388         goto out;
1389     }
1390     
1391     //per core cloning
1392     if (!(opts & V3_CHKPT_OPT_SKIP_CORES)) {
1393       for (i = 0; i < vm->num_cores; i++) {
1394         if ((ret = load_core(&(vm->cores[i]), chkpt, opts)) == -1) {
1395           PrintError(vm, VCORE_NONE, "Error loading core state (core=%d)\n", i);
1396           goto out;
1397         }
1398       }
1399     }
1400
1401  out:
1402     if (ret==-1) { 
1403         PrintError(vm, VCORE_NONE, "Unable to receive VM\n");
1404     } else {
1405         PrintDebug(vm, VCORE_NONE, "Done receving the VM\n");
1406     }
1407         
1408         
1409     /* Resume the guest if it was running and we didn't just trash the state*/
1410     if (vm->run_state == VM_RUNNING) { 
1411         if (ret == -1) {
1412             PrintError(vm, VCORE_NONE, "VM was previously running.  It is now borked.  Pausing it. \n");
1413             vm->run_state = VM_STOPPED;
1414         }
1415             
1416         /* We check the run state of the VM after every barrier 
1417            So this will immediately halt the VM 
1418         */
1419         v3_lower_barrier(vm);
1420     } 
1421     
1422
1423     if (!(opts & V3_CHKPT_OPT_SKIP_MEM)) { 
1424       v3_bitmap_deinit(&mod_pgs);
1425     }
1426
1427     chkpt_close(chkpt);
1428
1429     return ret;
1430 }
1431
1432 #endif