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.


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