#include <palacios/vmm_util.h>
#include <palacios/vmm_emulator.h>
+#include <palacios/vmm_shadow_paging.h>
+#include <palacios/vmm_direct_paging.h>
-#define MEM_OFFSET_HCALL 0x1000
+#define MEM_OFFSET_HCALL 0x1000
static inline
map->hook_hva = (addr_t)V3_VAddr(V3_AllocPages(1));
// There is an underlying region that contains all of the guest memory
+ // PrintDebug("Mapping %d pages of memory (%u bytes)\n", (int)mem_pages, (uint_t)info->mem_size);
+
map->base_region.guest_start = 0;
- map->base_region.guest_end = info->mem_size;
+ map->base_region.guest_end = mem_pages * PAGE_SIZE_4KB;
map->base_region.host_type = SHDW_REGION_ALLOCATED;
map->base_region.host_addr = (addr_t)V3_AllocPages(mem_pages);
+ //memset(V3_VAddr((void *)map->base_region.host_addr), 0xffffffff, map->base_region.guest_end);
+
v3_register_hypercall(info, MEM_OFFSET_HCALL, mem_offset_hypercall, NULL);
}
v3_delete_shadow_region(info, reg);
}
+
+ V3_FreePage((void *)(info->mem_map.base_region.host_addr));
+ V3_FreePage(V3_PAddr((void *)(info->mem_map.hook_hva)));
}
}
+// This will unhook the memory hook registered at start address
+// We do not support unhooking subregions
+int v3_unhook_mem(struct guest_info * info, addr_t guest_addr_start) {
+ struct v3_shadow_region * reg = v3_get_shadow_region(info, guest_addr_start);
+
+ if ((reg->host_type != SHDW_REGION_FULL_HOOK) ||
+ (reg->host_type != SHDW_REGION_WRITE_HOOK)) {
+ PrintError("Trying to unhook a non hooked memory region (addr=%p)\n", (void *)guest_addr_start);
+ return -1;
+ }
+
+ v3_delete_shadow_region(info, reg);
+
+ return 0;
+}
+
static inline
v3_rb_insert_color(&(region->tree_node), &(info->mem_map.shdw_regions));
+
+
+ // flush virtual page tables
+ // 3 cases shadow, shadow passthrough, and nested
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
+
+ if (mem_mode == PHYSICAL_MEM) {
+ addr_t cur_addr;
+
+ for (cur_addr = region->guest_start;
+ cur_addr < region->guest_end;
+ cur_addr += PAGE_SIZE_4KB) {
+ v3_invalidate_passthrough_addr(info, cur_addr);
+ }
+ } else {
+ v3_invalidate_shadow_pts(info);
+ }
+
+ } else if (info->shdw_pg_mode == NESTED_PAGING) {
+ addr_t cur_addr;
+
+ for (cur_addr = region->guest_start;
+ cur_addr < region->guest_end;
+ cur_addr += PAGE_SIZE_4KB) {
+
+ v3_invalidate_nested_addr(info, cur_addr);
+ }
+ }
+
return NULL;
}
addr_t dst_addr = (addr_t)V3_VAddr((void *)v3_get_shadow_addr(reg, guest_pa));
- if (v3_emulate_write_op(info, guest_va, guest_pa, dst_addr, reg->write_hook, reg->priv_data) == -1) {
+ if (v3_emulate_write_op(info, guest_va, guest_pa, dst_addr,
+ reg->write_hook, reg->priv_data) == -1) {
PrintError("Write hook emulation failed\n");
return -1;
}
addr_t op_addr = info->mem_map.hook_hva;
if (access_info.write == 1) {
- if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr, reg->write_hook, reg->priv_data) == -1) {
+ if (v3_emulate_write_op(info, guest_va, guest_pa, op_addr,
+ reg->write_hook, reg->priv_data) == -1) {
PrintError("Write Full Hook emulation failed\n");
return -1;
}
} else {
- if (v3_emulate_read_op(info, guest_va, guest_pa, op_addr, reg->read_hook, reg->write_hook, reg->priv_data) == -1) {
+ if (v3_emulate_read_op(info, guest_va, guest_pa, op_addr,
+ reg->read_hook, reg->write_hook,
+ reg->priv_data) == -1) {
PrintError("Read Full Hook emulation failed\n");
return -1;
}
void v3_delete_shadow_region(struct guest_info * info, struct v3_shadow_region * reg) {
- if (reg != NULL) {
- v3_rb_erase(&(reg->tree_node), &(info->mem_map.shdw_regions));
+ if (reg == NULL) {
+ return;
+ }
- V3_Free(reg);
+ // flush virtual page tables
+ // 3 cases shadow, shadow passthrough, and nested
+ if (info->shdw_pg_mode == SHADOW_PAGING) {
+ v3_mem_mode_t mem_mode = v3_get_vm_mem_mode(info);
+
+ if (mem_mode == PHYSICAL_MEM) {
+ addr_t cur_addr;
+
+ for (cur_addr = reg->guest_start;
+ cur_addr < reg->guest_end;
+ cur_addr += PAGE_SIZE_4KB) {
+ v3_invalidate_passthrough_addr(info, cur_addr);
+ }
+ } else {
+ v3_invalidate_shadow_pts(info);
+ }
+
+ } else if (info->shdw_pg_mode == NESTED_PAGING) {
+ addr_t cur_addr;
+
+ for (cur_addr = reg->guest_start;
+ cur_addr < reg->guest_end;
+ cur_addr += PAGE_SIZE_4KB) {
+
+ v3_invalidate_nested_addr(info, cur_addr);
+ }
}
+
+
+ v3_rb_erase(&(reg->tree_node), &(info->mem_map.shdw_regions));
+
+ V3_Free(reg);
+
+ // flush virtual page tables
+ // 3 cases shadow, shadow passthrough, and nested
+
}
(reg->host_type != SHDW_REGION_FULL_HOOK)) {
return (guest_addr - reg->guest_start) + reg->host_addr;
} else {
- PrintDebug("MEM Region Invalid\n");
+ PrintError("MEM Region Invalid\n");
return 0;
}