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.


added dedicated debugging framework with associated interface
[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  *
17  *
18  * This is free software.  You are permitted to use,
19  * redistribute, and modify it as specified in the file "V3VEE_LICENSE".
20  */
21
22 #include <palacios/vmm.h>
23 #include <palacios/vmm_sprintf.h>
24 #include <palacios/vm_guest.h>
25 #include <palacios/svm.h>
26 #include <palacios/vmx.h>
27 #include <palacios/vmm_checkpoint.h>
28 #include <palacios/vmm_hashtable.h>
29 #include <palacios/vmm_direct_paging.h>
30 #include <palacios/vmm_debug.h>
31
32 #include <palacios/vmm_dev_mgr.h>
33
34
35 static struct hashtable * store_table = NULL;
36
37 struct v3_chkpt;
38
39 typedef enum {SAVE, LOAD} chkpt_mode_t;
40
41 struct chkpt_interface {
42     char name[128];
43     void * (*open_chkpt)(char * url, chkpt_mode_t mode);
44     int (*close_chkpt)(void * store_data);
45     
46     void * (*open_ctx)(void * store_data, void * parent_ctx, char * name);
47     int (*close_ctx)(void * store_data, void * ctx);
48     
49     int (*save)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf);
50     int (*load)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf);
51 };
52
53
54 struct v3_chkpt {
55     struct v3_vm_info * vm;
56
57     struct chkpt_interface * interface;
58
59     void * store_data;
60 };
61
62
63
64
65 static uint_t store_hash_fn(addr_t key) {
66     char * name = (char *)key;
67     return v3_hash_buffer((uint8_t *)name, strlen(name));
68 }
69
70 static int store_eq_fn(addr_t key1, addr_t key2) {
71     char * name1 = (char *)key1;
72     char * name2 = (char *)key2;
73
74     return (strcmp(name1, name2) == 0);
75 }
76
77
78
79 #include "vmm_chkpt_stores.h"
80
81
82 int V3_init_checkpoint() {
83     extern struct chkpt_interface * __start__v3_chkpt_stores[];
84     extern struct chkpt_interface * __stop__v3_chkpt_stores[];
85     struct chkpt_interface ** tmp_store = __start__v3_chkpt_stores;
86     int i = 0;
87
88     store_table = v3_create_htable(0, store_hash_fn, store_eq_fn);
89
90     while (tmp_store != __stop__v3_chkpt_stores) {
91         V3_Print("Registering Checkpoint Backing Store (%s)\n", (*tmp_store)->name);
92
93         if (v3_htable_search(store_table, (addr_t)((*tmp_store)->name))) {
94             PrintError("Multiple instances of Checkpoint backing Store (%s)\n", (*tmp_store)->name);
95             return -1;
96         }
97
98         if (v3_htable_insert(store_table, (addr_t)((*tmp_store)->name), (addr_t)(*tmp_store)) == 0) {
99             PrintError("Could not register Checkpoint backing store (%s)\n", (*tmp_store)->name);
100             return -1;
101         }
102
103         tmp_store = &(__start__v3_chkpt_stores[++i]);
104     }
105
106     return 0;
107 }
108
109 int V3_deinit_checkpoint() {
110     v3_free_htable(store_table, 0, 0);
111     return 0;
112 }
113
114
115 static char svm_chkpt_header[] = "v3vee palacios checkpoint version: x.x, SVM x.x";
116 static char vmx_chkpt_header[] = "v3vee palacios checkpoint version: x.x, VMX x.x";
117
118 static int chkpt_close(struct v3_chkpt * chkpt) {
119     chkpt->interface->close_chkpt(chkpt->store_data);
120
121     V3_Free(chkpt);
122
123     return 0;
124 }
125
126
127 static struct v3_chkpt * chkpt_open(struct v3_vm_info * vm, char * store, char * url, chkpt_mode_t mode) {
128     struct chkpt_interface * iface = NULL;
129     struct v3_chkpt * chkpt = NULL;
130     void * store_data = NULL;
131
132     iface = (void *)v3_htable_search(store_table, (addr_t)store);
133     
134     if (iface == NULL) {
135         V3_Print("Error: Could not locate Checkpoint interface for store (%s)\n", store);
136         return NULL;
137     }
138
139     store_data = iface->open_chkpt(url, mode);
140
141     if (store_data == NULL) {
142         PrintError("Could not open url (%s) for backing store (%s)\n", url, store);
143         return NULL;
144     }
145
146
147     chkpt = V3_Malloc(sizeof(struct v3_chkpt));
148
149     if (!chkpt) {
150         PrintError("Could not allocate checkpoint state\n");
151         return NULL;
152     }
153
154     chkpt->interface = iface;
155     chkpt->vm = vm;
156     chkpt->store_data = store_data;
157     
158     return chkpt;
159 }
160
161 struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt_ctx * parent, char * name) {
162     struct v3_chkpt_ctx * ctx = V3_Malloc(sizeof(struct v3_chkpt_ctx));
163     void * parent_store_ctx = NULL;
164
165
166     if (!ctx) { 
167         PrintError("Unable to allocate context\n");
168         return 0;
169     }
170
171     memset(ctx, 0, sizeof(struct v3_chkpt_ctx));
172
173     ctx->chkpt = chkpt;
174     ctx->parent = parent;
175
176     if (parent) {
177         parent_store_ctx = parent->store_ctx;
178     }
179
180     ctx->store_ctx = chkpt->interface->open_ctx(chkpt->store_data, parent_store_ctx, name);
181
182     if (!(ctx->store_ctx)) {
183         PrintError("Warning: opening underlying representation returned null\n");
184     }
185
186     return ctx;
187 }
188
189 int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx) {
190     struct v3_chkpt * chkpt = ctx->chkpt;
191     int ret = 0;
192
193     ret = chkpt->interface->close_ctx(chkpt->store_data, ctx->store_ctx);
194
195     V3_Free(ctx);
196
197     return ret;
198 }
199
200
201
202
203
204 int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) {
205     struct v3_chkpt * chkpt = ctx->chkpt;    
206     
207     return  chkpt->interface->save(chkpt->store_data, ctx->store_ctx, tag, len, buf);
208
209 }
210
211
212 int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) {
213     struct v3_chkpt * chkpt = ctx->chkpt;    
214     
215     return chkpt->interface->load(chkpt->store_data, ctx->store_ctx, tag, len, buf);
216 }
217
218
219
220 static int load_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
221
222     void * guest_mem_base = NULL;
223     void * ctx = NULL;
224     uint64_t ret = 0;
225
226     guest_mem_base = V3_VAddr((void *)vm->mem_map.base_region.host_addr);
227
228     ctx = v3_chkpt_open_ctx(chkpt, NULL, "memory_img");
229     
230     if (!ctx) { 
231         PrintError("Unable to open context for memory load\n");
232         return -1;
233     }
234                      
235     if (v3_chkpt_load(ctx, "memory_img", vm->mem_size, guest_mem_base) == -1) {
236         PrintError("Unable to load all of memory (requested=%llu bytes, result=%llu bytes\n",(uint64_t)(vm->mem_size),ret);
237         v3_chkpt_close_ctx(ctx);
238         return -1;
239     }
240     
241     v3_chkpt_close_ctx(ctx);
242
243     return 0;
244 }
245
246
247 static int save_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
248     void * guest_mem_base = NULL;
249     void * ctx = NULL;
250     uint64_t ret = 0;
251
252     guest_mem_base = V3_VAddr((void *)vm->mem_map.base_region.host_addr);
253
254     ctx = v3_chkpt_open_ctx(chkpt, NULL,"memory_img");
255
256     if (!ctx) { 
257         PrintError("Unable to open context to save memory\n");
258         return -1;
259     }
260
261     if (v3_chkpt_save(ctx, "memory_img", vm->mem_size, guest_mem_base) == -1) {
262         PrintError("Unable to load all of memory (requested=%llu, received=%llu)\n",(uint64_t)(vm->mem_size),ret);
263         v3_chkpt_close_ctx(ctx);  
264         return -1;
265     }
266
267     v3_chkpt_close_ctx(ctx);
268
269     return 0;
270 }
271
272 int save_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
273     extern v3_cpu_arch_t v3_mach_type;
274     void * ctx = NULL;
275     
276     ctx = v3_chkpt_open_ctx(chkpt, NULL, "header");
277     if (!ctx) { 
278         PrintError("Cannot open context to save header\n");
279         return -1;
280     }
281
282     switch (v3_mach_type) {
283         case V3_SVM_CPU:
284         case V3_SVM_REV3_CPU: {
285             if (v3_chkpt_save(ctx, "header", strlen(svm_chkpt_header), svm_chkpt_header) == -1) { 
286                 PrintError("Could not save all of SVM header\n");
287                 v3_chkpt_close_ctx(ctx);
288                 return -1;
289             }
290             break;
291         }
292         case V3_VMX_CPU:
293         case V3_VMX_EPT_CPU:
294         case V3_VMX_EPT_UG_CPU: {
295             if (v3_chkpt_save(ctx, "header", strlen(vmx_chkpt_header), vmx_chkpt_header) == -1) { 
296                 PrintError("Could not save all of VMX header\n");
297                 v3_chkpt_close_ctx(ctx);
298                 return -1;
299             }
300             break;
301         }
302         default:
303             PrintError("checkpoint not supported on this architecture\n");
304             v3_chkpt_close_ctx(ctx);
305             return -1;
306     }
307
308     v3_chkpt_close_ctx(ctx);
309             
310     return 0;
311 }
312
313 static int load_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) {
314     extern v3_cpu_arch_t v3_mach_type;
315     void * ctx = NULL;
316     
317     ctx = v3_chkpt_open_ctx(chkpt, NULL, "header");
318
319     switch (v3_mach_type) {
320         case V3_SVM_CPU:
321         case V3_SVM_REV3_CPU: {
322             char header[strlen(svm_chkpt_header) + 1];
323          
324             if (v3_chkpt_load(ctx, "header", strlen(svm_chkpt_header), header) == -1) {
325                 PrintError("Could not load all of SVM header\n");
326                 v3_chkpt_close_ctx(ctx);
327                 return -1;
328             }
329             
330             header[strlen(svm_chkpt_header)] = 0;
331
332             break;
333         }
334         case V3_VMX_CPU:
335         case V3_VMX_EPT_CPU:
336         case V3_VMX_EPT_UG_CPU: {
337             char header[strlen(vmx_chkpt_header) + 1];
338             
339             if (v3_chkpt_load(ctx, "header", strlen(vmx_chkpt_header), header) == -1) {
340                 PrintError("Could not load all of VMX header\n");
341                 v3_chkpt_close_ctx(ctx);
342                 return -1;
343             }
344             
345             header[strlen(vmx_chkpt_header)] = 0;
346             
347             break;
348         }
349         default:
350             PrintError("checkpoint not supported on this architecture\n");
351             v3_chkpt_close_ctx(ctx);
352             return -1;
353     }
354     
355     v3_chkpt_close_ctx(ctx);
356     
357     return 0;
358 }
359
360
361 static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) {
362     extern v3_cpu_arch_t v3_mach_type;
363     void * ctx = NULL;
364     char key_name[16];
365
366     memset(key_name, 0, 16);
367
368     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
369
370     ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
371
372     if (!ctx) { 
373         PrintError("Could not open context to load core\n");
374         return -1;
375     }
376
377     // These really need to have error checking
378
379     v3_chkpt_load_64(ctx, "RIP", &(info->rip));
380
381     V3_CHKPT_STD_LOAD(ctx, info->vm_regs);
382
383     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr0);
384     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr2);
385     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr4);
386     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr8);
387     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.rflags);
388     V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.efer);
389
390     V3_CHKPT_STD_LOAD(ctx, info->dbg_regs);
391     V3_CHKPT_STD_LOAD(ctx, info->segments);
392     V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_cr3);
393     V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_cr0);
394     V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_efer);
395
396     v3_chkpt_close_ctx(ctx);
397
398     PrintDebug("Finished reading guest_info information\n");
399
400     info->cpu_mode = v3_get_vm_cpu_mode(info);
401     info->mem_mode = v3_get_vm_mem_mode(info);
402
403     if (info->shdw_pg_mode == SHADOW_PAGING) {
404         if (v3_get_vm_mem_mode(info) == VIRTUAL_MEM) {
405             if (v3_activate_shadow_pt(info) == -1) {
406                 PrintError("Failed to activate shadow page tables\n");
407                 return -1;
408             }
409         } else {
410             if (v3_activate_passthrough_pt(info) == -1) {
411                 PrintError("Failed to activate passthrough page tables\n");
412                 return -1;
413             }
414         }
415     }
416
417
418     switch (v3_mach_type) {
419         case V3_SVM_CPU:
420         case V3_SVM_REV3_CPU: {
421             char key_name[16];
422
423             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
424             ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
425
426             if (!ctx) { 
427                 PrintError("Could not open context to load SVM core\n");
428                 return -1;
429             }
430             
431             if (v3_svm_load_core(info, ctx) == -1) {
432                 PrintError("Failed to patch core %d\n", info->vcpu_id);
433                 v3_chkpt_close_ctx(ctx);
434                 return -1;
435             }
436
437             v3_chkpt_close_ctx(ctx);
438
439             break;
440         }
441         case V3_VMX_CPU:
442         case V3_VMX_EPT_CPU:
443         case V3_VMX_EPT_UG_CPU: {
444             char key_name[16];
445
446             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
447
448             ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
449
450             if (!ctx) { 
451                 PrintError("Could not open context to load VMX core\n");
452                 return -1;
453             }
454             
455             if (v3_vmx_load_core(info, ctx) < 0) {
456                 PrintError("VMX checkpoint failed\n");
457                 v3_chkpt_close_ctx(ctx);
458                 return -1;
459             }
460
461             v3_chkpt_close_ctx(ctx);
462
463             break;
464         }
465         default:
466             PrintError("Invalid CPU Type (%d)\n", v3_mach_type);
467             return -1;
468     }
469
470     v3_print_guest_state(info);
471
472     return 0;
473 }
474
475
476 static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) {
477     extern v3_cpu_arch_t v3_mach_type;
478     void * ctx = NULL;
479     char key_name[16];
480
481     memset(key_name, 0, 16);
482
483     v3_print_guest_state(info);
484
485
486     snprintf(key_name, 16, "guest_info%d", info->vcpu_id);
487
488     ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
489     
490     if (!ctx) { 
491         PrintError("Unable to open context to save core\n");
492         return -1;
493     }
494
495
496     // Error checking of all this needs to happen
497     v3_chkpt_save_64(ctx, "RIP", &(info->rip));
498
499     V3_CHKPT_STD_SAVE(ctx, info->vm_regs);
500
501     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr0);
502     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr2);
503     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr4);
504     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr8);
505     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.rflags);
506     V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.efer);
507
508     V3_CHKPT_STD_SAVE(ctx, info->dbg_regs);
509     V3_CHKPT_STD_SAVE(ctx, info->segments);
510     V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_cr3);
511     V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_cr0);
512     V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_efer);
513
514     v3_chkpt_close_ctx(ctx);
515
516     //Architechture specific code
517     switch (v3_mach_type) {
518         case V3_SVM_CPU:
519         case V3_SVM_REV3_CPU: {
520             char key_name[16];
521             void * ctx = NULL;
522             
523             snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id);
524             
525             ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
526
527             if (!ctx) { 
528                 PrintError("Could not open context to store SVM core\n");
529                 return -1;
530             }
531             
532             if (v3_svm_save_core(info, ctx) == -1) {
533                 PrintError("VMCB Unable to be written\n");
534                 v3_chkpt_close_ctx(ctx);
535                 return -1;
536             }
537             
538             v3_chkpt_close_ctx(ctx);
539             break;
540         }
541         case V3_VMX_CPU:
542         case V3_VMX_EPT_CPU:
543         case V3_VMX_EPT_UG_CPU: {
544             char key_name[16];
545             void * ctx = NULL;
546
547             snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id);
548             
549             ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name);
550             
551             if (!ctx) { 
552                 PrintError("Could not open context to store VMX core\n");
553                 return -1;
554             }
555
556             if (v3_vmx_save_core(info, ctx) == -1) {
557                 PrintError("VMX checkpoint failed\n");
558                 v3_chkpt_close_ctx(ctx);
559                 return -1;
560             }
561
562             v3_chkpt_close_ctx(ctx);
563
564             break;
565         }
566         default:
567             PrintError("Invalid CPU Type (%d)\n", v3_mach_type);
568             return -1;
569     }
570     
571     return 0;
572 }
573
574
575 int v3_chkpt_save_vm(struct v3_vm_info * vm, char * store, char * url) {
576     struct v3_chkpt * chkpt = NULL;
577     int ret = 0;;
578     int i = 0;
579     
580     chkpt = chkpt_open(vm, store, url, SAVE);
581
582     if (chkpt == NULL) {
583         PrintError("Error creating checkpoint store for url %s\n",url);
584         return -1;
585     }
586
587     /* If this guest is running we need to block it while the checkpoint occurs */
588     if (vm->run_state == VM_RUNNING) {
589         while (v3_raise_barrier(vm, NULL) == -1);
590     }
591
592     if ((ret = save_memory(vm, chkpt)) == -1) {
593         PrintError("Unable to save memory\n");
594         goto out;
595     }
596     
597     
598     if ((ret = v3_save_vm_devices(vm, chkpt)) == -1) {
599         PrintError("Unable to save devices\n");
600         goto out;
601     }
602     
603
604     if ((ret = save_header(vm, chkpt)) == -1) {
605         PrintError("Unable to save header\n");
606         goto out;
607     }
608     
609     for (i = 0; i < vm->num_cores; i++){
610         if ((ret = save_core(&(vm->cores[i]), chkpt)) == -1) {
611             PrintError("chkpt of core %d failed\n", i);
612             goto out;
613         }
614     }
615     
616  out:
617     
618     /* Resume the guest if it was running */
619     if (vm->run_state == VM_RUNNING) {
620         v3_lower_barrier(vm);
621     }
622
623     chkpt_close(chkpt);
624
625     return ret;
626
627 }
628
629 int v3_chkpt_load_vm(struct v3_vm_info * vm, char * store, char * url) {
630     struct v3_chkpt * chkpt = NULL;
631     int i = 0;
632     int ret = 0;
633     
634     chkpt = chkpt_open(vm, store, url, LOAD);
635
636     if (chkpt == NULL) {
637         PrintError("Error creating checkpoint store\n");
638         return -1;
639     }
640
641     /* If this guest is running we need to block it while the checkpoint occurs */
642     if (vm->run_state == VM_RUNNING) {
643         while (v3_raise_barrier(vm, NULL) == -1);
644     }
645
646     if ((ret = load_memory(vm, chkpt)) == -1) {
647         PrintError("Unable to save memory\n");
648         goto out;
649     }
650
651
652     if ((ret = v3_load_vm_devices(vm, chkpt)) == -1) {
653         PrintError("Unable to load devies\n");
654         goto out;
655     }
656
657
658     if ((ret = load_header(vm, chkpt)) == -1) {
659         PrintError("Unable to load header\n");
660         goto out;
661     }
662
663     //per core cloning
664     for (i = 0; i < vm->num_cores; i++) {
665         if ((ret = load_core(&(vm->cores[i]), chkpt)) == -1) {
666             PrintError("Error loading core state (core=%d)\n", i);
667             goto out;
668         }
669     }
670
671  out:
672
673     /* Resume the guest if it was running and we didn't just trash the state*/
674     if (vm->run_state == VM_RUNNING) {
675     
676         if (ret == -1) {
677             vm->run_state = VM_STOPPED;
678         }
679
680         /* We check the run state of the VM after every barrier 
681            So this will immediately halt the VM 
682         */
683         v3_lower_barrier(vm);
684     }
685
686     chkpt_close(chkpt);
687
688     return ret;
689 }
690
691
692