X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_mem_hook.c;h=ef2ff349e764ae7ac2068f132b071d98849c0f94;hb=caf85567e859e58d73a0214ff2a89671692814a5;hp=6993c9ee4a16eaea8632ef89b5d5f8c4791c60de;hpb=0a4bd37f65c15fe50680e51b68f3f95ec8d347ea;p=palacios.releases.git diff --git a/palacios/src/palacios/vmm_mem_hook.c b/palacios/src/palacios/vmm_mem_hook.c index 6993c9e..ef2ff34 100644 --- a/palacios/src/palacios/vmm_mem_hook.c +++ b/palacios/src/palacios/vmm_mem_hook.c @@ -52,10 +52,28 @@ static int mem_eq_fn(addr_t key1, addr_t key2) { } int v3_init_mem_hooks(struct v3_vm_info * vm) { + void *temp; + struct v3_mem_hooks * hooks = &(vm->mem_hooks); - hooks->hook_hvas_1 = V3_VAddr(V3_AllocPages(vm->num_cores)); - hooks->hook_hvas_2 = V3_VAddr(V3_AllocPages(vm->num_cores)); + temp = V3_AllocPages(vm->num_cores); + + if (!temp) { + PrintError("Cannot allocate space for mem hooks\n"); + return -1; + } + + hooks->hook_hvas_1 = V3_VAddr(temp); + + temp = V3_AllocPages(vm->num_cores); + + if (!temp) { + PrintError("Cannot allocate space for mem hooks\n"); + V3_FreePages(hooks->hook_hvas_1,vm->num_cores); + return -1; + } + + hooks->hook_hvas_2 = V3_VAddr(temp); INIT_LIST_HEAD(&(hooks->hook_list)); @@ -135,7 +153,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue } if (ret == -1) { - PrintError("Could not translate Instruction Address (%p)\n", (void *)core->rip); + PrintError("Could not translate Instruction Address (%p)\n", (void *)(addr_t)core->rip); return -1; } @@ -145,6 +163,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue } + // Test source operand, if it's memory we need to do some translations, and handle a possible hook if (instr.src_operand.type == MEM_OPERAND) { struct v3_mem_region * src_reg = NULL; @@ -162,13 +181,13 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue } } - if ((guest_pa >= reg->guest_start) && - (guest_pa <= reg->guest_end)) { + if ((src_mem_op_gpa >= reg->guest_start) && + (src_mem_op_gpa < reg->guest_end)) { // Src address corresponds to faulted region src_reg = reg; } else { // Note that this should only trigger for string operations - src_reg = v3_get_mem_region(core->vm_info, core->cpu_id, src_mem_op_gpa); + src_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, src_mem_op_gpa); } if (src_reg == NULL) { @@ -181,7 +200,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue // We don't check whether the region is a hook here because it doesn't yet matter. // These hva calculations will be true regardless if (src_reg->flags.alloced == 0) { - src_mem_op_hva = (addr_t)(hooks->hook_hvas_1 + (PAGE_SIZE * core->cpu_id)); + src_mem_op_hva = (addr_t)(hooks->hook_hvas_1 + (PAGE_SIZE * core->vcpu_id)); } else { // We already have the region so we can do the conversion ourselves src_mem_op_hva = (addr_t)V3_VAddr((void *)((src_mem_op_gpa - src_reg->guest_start) + src_reg->host_addr)); @@ -208,13 +227,13 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue } } - if ((guest_pa >= reg->guest_start) && - (guest_pa <= reg->guest_end)) { + if ((dst_mem_op_gpa >= reg->guest_start) && + (dst_mem_op_gpa < reg->guest_end)) { // Dst address corresponds to faulted region dst_reg = reg; } else { // Note that this should only trigger for string operations - dst_reg = v3_get_mem_region(core->vm_info, core->cpu_id, dst_mem_op_gpa); + dst_reg = v3_get_mem_region(core->vm_info, core->vcpu_id, dst_mem_op_gpa); } if (dst_reg == NULL) { @@ -227,7 +246,7 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue // We don't check whether the region is a hook here because it doesn't yet matter. // These hva calculations will be true regardless if (dst_reg->flags.alloced == 0) { - dst_mem_op_hva = (addr_t)(hooks->hook_hvas_2 + (PAGE_SIZE * core->cpu_id)); + dst_mem_op_hva = (addr_t)(hooks->hook_hvas_2 + (PAGE_SIZE * core->vcpu_id)); } else { // We already have the region so we can do the conversion ourselves dst_mem_op_hva = (addr_t)V3_VAddr((void *)((dst_mem_op_gpa - dst_reg->guest_start) + dst_reg->host_addr)); @@ -239,6 +258,11 @@ static int handle_mem_hook(struct guest_info * core, addr_t guest_va, addr_t gue mem_op_size = ((uint_t)src_req_size < (uint_t)dst_req_size) ? src_req_size : dst_req_size; + if (mem_op_size == -1) { + PrintError("Error: Did not detect any memory operands...\n"); + return -1; + } + /* Now handle the hooks if necessary */ if ( (src_hook != NULL) && (src_hook->read != NULL) && @@ -311,6 +335,11 @@ int v3_hook_write_mem(struct v3_vm_info * vm, uint16_t core_id, struct mem_hook * hook = V3_Malloc(sizeof(struct mem_hook)); struct v3_mem_hooks * hooks = &(vm->mem_hooks); + if (!hook) { + PrintError("Cannot allocate in hooking memory for full access\n"); + return -1; + } + memset(hook, 0, sizeof(struct mem_hook)); hook->write = write; @@ -353,6 +382,11 @@ int v3_hook_full_mem(struct v3_vm_info * vm, uint16_t core_id, struct mem_hook * hook = V3_Malloc(sizeof(struct mem_hook)); struct v3_mem_hooks * hooks = &(vm->mem_hooks); + if (!hook) { + PrintError("Cannot allocate in hooking memory for writing\n"); + return -1; + } + memset(hook, 0, sizeof(struct mem_hook)); hook->write = write; @@ -360,12 +394,20 @@ int v3_hook_full_mem(struct v3_vm_info * vm, uint16_t core_id, hook->priv_data = priv_data; entry = v3_create_mem_region(vm, core_id, guest_addr_start, guest_addr_end); + + if (!entry) { + PrintError("Cannot create memory region\n"); + V3_Free(hook); + return -1; + } + hook->region = entry; entry->unhandled = handle_mem_hook; entry->priv_data = hook; if (v3_insert_mem_region(vm, entry)) { + PrintError("Cannot insert memory region\n"); V3_Free(entry); V3_Free(hook); return -1; @@ -393,7 +435,20 @@ static int free_hook(struct v3_vm_info * vm, struct mem_hook * hook) { // We do not support unhooking subregions int v3_unhook_mem(struct v3_vm_info * vm, uint16_t core_id, addr_t guest_addr_start) { struct v3_mem_region * reg = v3_get_mem_region(vm, core_id, guest_addr_start); - struct mem_hook * hook = reg->priv_data; + struct mem_hook * hook = NULL; + + if (reg == NULL) { + PrintError("Could not find region at %p\n", (void *)guest_addr_start); + return -1; + } + + hook = reg->priv_data; + + if (hook == NULL) { + PrintError("Trying to unhook region that is not a hook at %p\n", (void *)guest_addr_start); + return -1; + } + free_hook(vm, hook);