From: Madhav Suresh Date: Fri, 16 Sep 2011 19:39:20 +0000 (-0400) Subject: core checkpoint import X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=6ee36e0a7e4585bd0e4235eeb60644fffe230af3 core checkpoint import --- diff --git a/Kconfig b/Kconfig index 5397fec..9a7f7e7 100644 --- a/Kconfig +++ b/Kconfig @@ -169,6 +169,14 @@ config EXPERIMENTAL The purpose of this option is to allow features under development to be committed to the mainline to more easily track changes and provide access to multiple developers +config CHECKPOINT + bool "Enable Checkpointing" + default n + help + Temporary option to enable experimental checkpoint code + + + endmenu diff --git a/palacios/include/palacios/svm.h b/palacios/include/palacios/svm.h index 665b1c2..ed227fa 100644 --- a/palacios/include/palacios/svm.h +++ b/palacios/include/palacios/svm.h @@ -90,7 +90,8 @@ int v3_svm_enter(struct guest_info * info); int v3_start_svm_guest(struct guest_info *info); int v3_reset_svm_vm_core(struct guest_info * core, addr_t rip); - +int v3_svm_load_core(struct guest_info * core, void * ctx); +int v3_svm_save_core(struct guest_info * core, void * ctx); #endif diff --git a/palacios/include/palacios/vmm_checkpoint.h b/palacios/include/palacios/vmm_checkpoint.h new file mode 100644 index 0000000..cbb1b5d --- /dev/null +++ b/palacios/include/palacios/vmm_checkpoint.h @@ -0,0 +1,51 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2011, Madhav Suresh + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Authors: Madhav Suresh + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VMM_CHECKPOINT_H__ +#define __VMM_CHECKPOINT_H__ + +#ifdef __V3VEE__ + +#include +#include + +struct v3_chkpt; + + +struct v3_chkpt_ctx { + struct v3_chkpt * chkpt; + struct v3_chkpt_ctx * parent; + void * store_ctx; +}; + + +int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf); +int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf); + +int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx); +struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt_ctx * parent, char * name); + +int v3_load_vm(struct v3_vm_info * vm, char * store, char * url); +int v3_save_vm(struct v3_vm_info * vm); + + + +#endif + +#endif diff --git a/palacios/include/palacios/vmx.h b/palacios/include/palacios/vmx.h index acadf22..c3b3254 100644 --- a/palacios/include/palacios/vmx.h +++ b/palacios/include/palacios/vmx.h @@ -218,12 +218,19 @@ int v3_is_vmx_capable(); void v3_init_vmx_cpu(int cpu_id); void v3_deinit_vmx_cpu(int cpu_id); +int v3_init_vmx_vmcs(struct guest_info * info, v3_vm_class_t vm_class); +int v3_deinit_vmx_vmcs(struct guest_info * core); + int v3_start_vmx_guest(struct guest_info* info); int v3_reset_vmx_vm_core(struct guest_info * core, addr_t rip); int v3_vmx_enter(struct guest_info * info); -int v3_init_vmx_vmcs(struct guest_info * info, v3_vm_class_t vm_class); -int v3_deinit_vmx_vmcs(struct guest_info * core); +int v3_vmx_load_core(struct guest_info * core, void * ctx); +int v3_vmx_save_core(struct guest_info * core, void * ctx); + + + + #endif // ! __V3VEE__ diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index 63a822b..14a1c29 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -64,6 +64,7 @@ obj-$(V3_CONFIG_VMX) += vmx.o \ +obj-$(V3_CONFIG_CHECKPOINT) += vmm_checkpoint.o obj-$(V3_CONFIG_TELEMETRY) += vmm_telemetry.o diff --git a/palacios/src/palacios/svm.c b/palacios/src/palacios/svm.c index 1bf16cc..a6a6879 100644 --- a/palacios/src/palacios/svm.c +++ b/palacios/src/palacios/svm.c @@ -37,6 +37,9 @@ #include #include +#ifdef V3_CONFIG_CHECKPOINT +#include +#endif #include @@ -339,6 +342,63 @@ int v3_deinit_svm_vmcb(struct guest_info * core) { } +#ifdef V3_CONFIG_CHECKPOINT +int v3_svm_save_core(struct guest_info * core, void * ctx){ + + v3_chkpt_save(ctx, "vmcb_data", PAGE_SIZE, core->vmm_data); + + return 0; +} + +int v3_svm_patch_core(struct guest_info * core, void * chkpt_ctx){ + struct cr0_32 * shadow_cr0; + vmcb_saved_state_t * guest_state; + vmcb_ctrl_t * guest_ctrl; + + + + if (v3_chkpt_load(chkpt_ctx, "vmcb_data", PAGE_SIZE, core->vmm_data) == -1){ + return -1; + } + + guest_state = GET_VMCB_SAVE_STATE_AREA((vmcb_t *)(core->vmm_data)); + guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t *)(core->vmm_data)); + + + core->rip = guest_state->rip; + core->vm_regs.rsp = guest_state->rsp; + core->vm_regs.rax = guest_state->rax; + + core->cpl = guest_state->cpl; + + core->ctrl_regs.cr0 = guest_state->cr0; + core->ctrl_regs.cr2 = guest_state->cr2; + core->ctrl_regs.cr4 = guest_state->cr4; + core->dbg_regs.dr6 = guest_state->dr6; + core->dbg_regs.dr7 = guest_state->dr7; + core->ctrl_regs.cr8 = guest_ctrl->guest_ctrl.V_TPR; + core->ctrl_regs.rflags = guest_state->rflags; + core->ctrl_regs.efer = guest_state->efer; + + + shadow_cr0 = (struct cr0_32 *)&(core->ctrl_regs.cr0); + + + if (core->shdw_pg_mode == SHADOW_PAGING) { + if (shadow_cr0->pg){ + if (v3_activate_passthrough_pt(core) == -1) { + PrintError("Failed to activate passthrough page tables\n"); + return -1; + } + } + } + + + v3_get_vmcb_segments((vmcb_t*)(core->vmm_data), &(core->segments)); + return 0; +} +#endif + static int update_irq_exit_state(struct guest_info * info) { vmcb_ctrl_t * guest_ctrl = GET_VMCB_CTRL_AREA((vmcb_t*)(info->vmm_data)); diff --git a/palacios/src/palacios/vmm_checkpoint.c b/palacios/src/palacios/vmm_checkpoint.c new file mode 100644 index 0000000..ded6171 --- /dev/null +++ b/palacios/src/palacios/vmm_checkpoint.c @@ -0,0 +1,467 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2011, Madhav Suresh + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Author: Madhav Suresh + * Arefin Huq + * + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + + +static struct hashtable * store_table = NULL; + +struct v3_chkpt; + +typedef enum {SAVE, LOAD} chkpt_mode_t; + +struct chkpt_interface { + char name[128]; + void * (*open_chkpt)(char * url, chkpt_mode_t mode); + int (*close_chkpt)(void * store_data); + + void * (*open_ctx)(void * store_data, void * parent_ctx, char * name); + int (*close_ctx)(void * store_data, void * ctx); + + int (*save)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf); + int (*load)(void * store_data, void * ctx, char * tag, uint64_t len, void * buf); +}; + + +struct v3_chkpt { + struct v3_vm_info * vm; + + struct chkpt_interface * interface; + + void * store_data; +}; + + +#include "vmm_chkpt_stores.h" + + +static char svm_chkpt_header[] = "v3vee palacios checkpoint version: x.x, SVM x.x"; +static char vmx_chkpt_header[] = "v3vee palacios checkpoint version: x.x, VMX x.x"; + +static int chkpt_close(struct v3_chkpt * chkpt) { + chkpt->interface->close_chkpt(chkpt->store_data); + + V3_Free(chkpt); + + return 0; +} + + +static struct v3_chkpt * chkpt_open(char * store, char * url, chkpt_mode_t mode) { + + // search for checkpoint interface + + PrintError("Not yet implemented\n"); + return NULL; +} + +struct v3_chkpt_ctx * v3_chkpt_open_ctx(struct v3_chkpt * chkpt, struct v3_chkpt_ctx * parent, char * name) { + struct v3_chkpt_ctx * ctx = V3_Malloc(sizeof(struct v3_chkpt_ctx)); + + memset(ctx, 0, sizeof(struct v3_chkpt_ctx)); + + ctx->chkpt = chkpt; + ctx->parent = parent; + + ctx->store_ctx = chkpt->interface->open_ctx(chkpt->store_data, parent->store_ctx, name); + + return ctx; +} + +int v3_chkpt_close_ctx(struct v3_chkpt_ctx * ctx) { + struct v3_chkpt * chkpt = ctx->chkpt; + int ret = 0; + + ret = chkpt->interface->close_ctx(chkpt->store_data, ctx->store_ctx); + + V3_Free(ctx); + + return ret; +} + + +/* Temporary */ +#define V3_CHKPT_STD_SAVE(ctx,x) v3_chkpt_save(ctx,#x,sizeof(x),&(x)) +#define V3_CHKPT_STD_LOAD(ctx,x) v3_chkpt_load(ctx,#x,sizeof(x),&(x)) + + +int v3_chkpt_save(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) { + struct v3_chkpt * chkpt = ctx->chkpt; + return chkpt->interface->save(chkpt->store_data, ctx->store_ctx, tag, len, buf); +} + + +int v3_chkpt_load(struct v3_chkpt_ctx * ctx, char * tag, uint64_t len, void * buf) { + struct v3_chkpt * chkpt = ctx->chkpt; + return chkpt->interface->load(chkpt->store_data, ctx->store_ctx, tag, len, buf); +} + + + +static int load_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { + + void * guest_mem_base = NULL; + void * ctx = NULL; + uint64_t ret = 0; + + guest_mem_base = V3_VAddr((void *)vm->mem_map.base_region.host_addr); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, "memory_img"); + + ret = v3_chkpt_load(ctx, "memory_img", vm->mem_size, guest_mem_base); + v3_chkpt_close_ctx(ctx); + + if (ret == 0) { + PrintError("Error Loading VM Memory\n"); + return -1; + } + + return 0; +} + +/* +static int save_memory(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { + void * guest_mem_base = NULL; + void * ctx = NULL; + uint64_t ret = 0; + + guest_mem_base = V3_VAddr((void *)vm->mem_map.base_region.host_addr); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, "memory_img"); + + + ret = v3_chkpt_save(ctx, "memory_img", vm->mem_size, guest_mem_base); + v3_chkpt_close_ctx(ctx); + + if (ret == 0) { + PrintError("Error Saving VM Memory\n"); + return -1; + } + + return 0; +} + +int save_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { + v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); + void * ctx = NULL; + + ctx = v3_chkpt_open_ctx(chkpt, NULL, "header"); + + switch (cpu_type) { + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: { + v3_chkpt_save(ctx, "header", strlen(svm_chkpt_header), svm_chkpt_header); + break; + } + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: { + v3_chkpt_save(ctx, "header", strlen(vmx_chkpt_header), vmx_chkpt_header); + break; + } + default: + PrintError("checkpoint not supported on this architecture\n"); + v3_chkpt_close_ctx(ctx); + return -1; + } + + v3_chkpt_close_ctx(ctx); + + return 0; +} +*/ +static int load_header(struct v3_vm_info * vm, struct v3_chkpt * chkpt) { + v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); + void * ctx = NULL; + + ctx = v3_chkpt_open_ctx(chkpt, NULL, "header"); + + switch (cpu_type) { + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: { + char header[strlen(svm_chkpt_header) + 1]; + + v3_chkpt_load(ctx, "header", strlen(svm_chkpt_header), header); + + break; + } + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: { + char header[strlen(vmx_chkpt_header) + 1]; + + v3_chkpt_load(ctx, "header", strlen(vmx_chkpt_header), header); + + break; + } + default: + PrintError("checkpoint not supported on this architecture\n"); + v3_chkpt_close_ctx(ctx); + return -1; + } + + v3_chkpt_close_ctx(ctx); + + return 0; +} + + +static int load_core(struct guest_info * info, struct v3_chkpt * chkpt) { + v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); + void * ctx = NULL; + char key_name[16]; + memset(key_name, 0, 16); + + snprintf(key_name, 16, "guest_info%d", info->vcpu_id); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + V3_CHKPT_STD_LOAD(ctx, info->vm_regs); + + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr0); + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr2); + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr4); + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.cr8); + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.rflags); + V3_CHKPT_STD_LOAD(ctx, info->ctrl_regs.efer); + + V3_CHKPT_STD_LOAD(ctx, info->dbg_regs); + V3_CHKPT_STD_LOAD(ctx, info->segments); + V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_cr3); + V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_cr0); + V3_CHKPT_STD_LOAD(ctx, info->shdw_pg_state.guest_efer); + v3_chkpt_close_ctx(ctx); + + PrintDebug("Finished reading guest_info information\n"); + + info->cpu_mode = v3_get_vm_cpu_mode(info); + info->mem_mode = v3_get_vm_mem_mode(info); + + + switch (cpu_type) { + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: { + char key_name[16]; + + snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id); + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + if (v3_svm_load_core(info, ctx) == -1) { + PrintError("Failed to patch core %d\n", info->vcpu_id); + return -1; + } + + v3_chkpt_close_ctx(ctx); + + break; + } + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: { + char key_name[16]; + + snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id); + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + if (v3_vmx_load_core(info, ctx) < 0) { + PrintError("VMX checkpoint failed\n"); + return -1; + } + + v3_chkpt_close_ctx(ctx); + + break; + } + default: + PrintError("Invalid CPU Type (%d)\n", cpu_type); + return -1; + } + + return 0; +} + +/* +static int save_core(struct guest_info * info, struct v3_chkpt * chkpt) { + v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); + void * ctx = NULL; + char key_name[16]; + + memset(key_name, 0, 16); + + + snprintf(key_name, 16, "guest_info%d", info->vcpu_id); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + V3_CHKPT_STD_SAVE(ctx, info->vm_regs); + + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr0); + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr2); + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr4); + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.cr8); + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.rflags); + V3_CHKPT_STD_SAVE(ctx, info->ctrl_regs.efer); + + V3_CHKPT_STD_SAVE(ctx, info->dbg_regs); + V3_CHKPT_STD_SAVE(ctx, info->segments); + V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_cr3); + V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_cr0); + V3_CHKPT_STD_SAVE(ctx, info->shdw_pg_state.guest_efer); + + v3_chkpt_close_ctx(ctx); + + //Architechture specific code + switch (cpu_type) { + case V3_SVM_CPU: + case V3_SVM_REV3_CPU: { + char key_name[16]; + void * ctx = NULL; + + snprintf(key_name, 16, "vmcb_data%d", info->vcpu_id); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + if (v3_svm_save_core(info, ctx) == -1) { + PrintError("VMCB Unable to be written\n"); + v3_chkpt_close_ctx(ctx); + return -1; + } + + v3_chkpt_close_ctx(ctx); + break; + } + case V3_VMX_CPU: + case V3_VMX_EPT_CPU: + case V3_VMX_EPT_UG_CPU: { + char key_name[16]; + void * ctx = NULL; + + snprintf(key_name, 16, "vmcs_data%d", info->vcpu_id); + + ctx = v3_chkpt_open_ctx(chkpt, NULL, key_name); + + if (v3_vmx_save_core(info, ctx) == -1) { + PrintError("VMX checkpoint failed\n"); + v3_chkpt_close_ctx(ctx); + return -1; + } + + v3_chkpt_close_ctx(ctx); + + break; + } + default: + PrintError("Invalid CPU Type (%d)\n", cpu_type); + return -1; + } + + return 0; +} +*/ + +int v3_load_vm(struct v3_vm_info * vm, char * store, char * url) { + int i = 0; + struct v3_chkpt * chkpt = NULL; + + chkpt = chkpt_open(store, url, LOAD); + + + if (load_memory(vm, chkpt) == -1) { + PrintError("Unable to save memory\n"); + return -1; + } + + //raising the barrier requires VM to be in VM_RUNNING state + vm->run_state = VM_RUNNING; + + /* Don't handle devices just yet + if (v3_chkpt_load_dev(vm) == -1) { + PrintError("Unable to load devies\n"); + } + + */ + + if (load_header(vm, chkpt) == -1) { + PrintError("Unable to load header\n"); + } + + //per core cloning + for (i = 0; i < vm->num_cores; i++) { + if (load_core(&(vm->cores[i]), chkpt) == -1) { + return -1; + } + } + + chkpt_close(chkpt); + + return 0; +} + + + +static uint_t store_hash_fn(addr_t key) { + char * name = (char *)key; + return v3_hash_buffer((uint8_t *)name, strlen(name)); +} + +static int store_eq_fn(addr_t key1, addr_t key2) { + char * name1 = (char *)key1; + char * name2 = (char *)key2; + + return (strcmp(name1, name2) == 0); +} + + + +int V3_init_checkpoint() { + extern struct chkpt_interface * __start__v3_chkpt_stores[]; + extern struct chkpt_interface * __stop__v3_chkpt_stores[]; + struct chkpt_interface ** tmp_store = __start__v3_chkpt_stores; + int i = 0; + + store_table = v3_create_htable(0, store_hash_fn, store_eq_fn); + + while (tmp_store != __stop__v3_chkpt_stores) { + V3_Print("Registering Extension (%s)\n", (*tmp_store)->name); + + if (v3_htable_search(store_table, (addr_t)((*tmp_store)->name))) { + PrintError("Multiple instances of Extension (%s)\n", (*tmp_store)->name); + return -1; + } + + if (v3_htable_insert(store_table, (addr_t)((*tmp_store)->name), (addr_t)(*tmp_store)) == 0) { + PrintError("Could not register Extension (%s)\n", (*tmp_store)->name); + return -1; + } + + tmp_store = &(__start__v3_chkpt_stores[++i]); + } + + return 0; +} diff --git a/palacios/src/palacios/vmm_chkpt_stores.h b/palacios/src/palacios/vmm_chkpt_stores.h new file mode 100644 index 0000000..3e8fe1d --- /dev/null +++ b/palacios/src/palacios/vmm_chkpt_stores.h @@ -0,0 +1,107 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2011, Jack Lange + * Copyright (c) 2011, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + +#ifndef __VMM_CHKPT_STORES_H__ +#define __VMM_CHKPT_STORES_H__ + + +/* + * This is a place holder to ensure that the _v3_extensions section gets created by gcc + */ +static struct {} null_store __attribute__((__used__)) \ + __attribute__((unused, __section__ ("_v3_chkpt_stores"), \ + aligned(sizeof(addr_t)))); + + +#define register_chkpt_store(store) \ + static struct v3_chkpt_interface * _v3_store_#store \ + __attribute__((used)) \ + __attribute__((unused, __section__("_v3_chkpt_stores"), \ + aligned(sizeof(addr_t)))) \ + = store; + + + + +#ifdef V3_CONFIG_KEYED_STREAMS +#include + +static void * keyed_stream_open_chkpt(char * url) { + return v3_keyed_stream_open(url, V3_KS_WR_ONLY_CREATE); +} + + + +static int keyed_stream_close_chkpt(void * store_data) { + v3_keyed_stream_t stream = store_data; + + v3_keyed_stream_close(stream); + + return 0; +} + +static void * keyed_stream_open_ctx(void * store_data, + void * parent_ctx, + char * name) { + v3_keyed_stream_t stream = store_data; + + return v3_keyed_stream_open_key(stream, name); +} + +static int keyed_stream_close_ctx(void * store_data, void * ctx) { + v3_keyed_stream_t stream = store_data; + + v3_keyed_stream_close_key(stream, ctx); + + return 0; +} + +static uint64_t keyed_stream_save(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + return v3_keyed_stream_write_key(store_data, ctx, buf, len); +} + +static uint64_t keyed_stream_load(void * store_data, void * ctx, + char * tag, uint64_t len, void * buf) { + return v3_keyed_stream_read_key(store_data, ctx, buf, len); +} + + +static struct chkpt_interface keyed_stream_store = { + .name = "KEYED_STREAM", + .open_chkpt = keyed_stream_open_chkpt, + .close_chkpt = keyed_stream_close_chkpt, + .open_ctx = keyed_stream_open_ctx, + .close_ctx = keyed_stream_close_ctx, + .save = keyed_stream_save, + .load = keyed_stream_load +}; + +register_chkpt_store(&keyed_stream_store); + + + +#endif + + + + + + +#endif diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 11522f4..aa821da 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -34,6 +34,10 @@ #include #include +#ifdef V3_CONFIG_CHECKPOINT +#include +#endif + #include #include #include @@ -559,6 +563,50 @@ int v3_deinit_vmx_vmcs(struct guest_info * core) { } + +#ifdef V3_CONFIG_CHECKPOINT +/* + * JRL: This is broken + */ +int v3_vmx_save_core(struct guest_info * core, void * ctx){ + uint64_t vmcs_ptr = vmcs_store(); + + v3_chkpt_save(ctx, "vmcs_data", PAGE_SIZE, (void *)vmcs_ptr); + + return 0; +} + +int v3_vmx_load_core(struct guest_info * core, void * ctx){ + struct vmx_data * vmx_info = (struct vmx_data *)(core->vmm_data); + struct cr0_32 * shadow_cr0; + char vmcs[PAGE_SIZE_4KB]; + + v3_chkpt_load(ctx, "vmcs_data", PAGE_SIZE_4KB, vmcs); + + vmcs_clear(vmx_info->vmcs_ptr_phys); + vmcs_load((addr_t)vmcs); + + v3_vmx_save_vmcs(core); + + shadow_cr0 = (struct cr0_32 *)&(core->ctrl_regs.cr0); + + + /* Get the CPU mode to set the guest_ia32e entry ctrl */ + + if (core->shdw_pg_mode == SHADOW_PAGING) { + if (shadow_cr0->pg){ + if (v3_activate_passthrough_pt(core) == -1) { + PrintError("Failed to activate passthrough page tables\n"); + return -1; + } + } + } + + return 0; +} +#endif + + static int update_irq_exit_state(struct guest_info * info) { struct vmx_exit_idt_vec_info idt_vec_info;