From: Peter Dinda Date: Sun, 22 Mar 2015 23:06:04 +0000 (-0500) Subject: Basic HVM data structures and functions X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=3586c3bd6260bf79c57baebf66a26d7e8158d411 Basic HVM data structures and functions --- diff --git a/Kconfig b/Kconfig index 853c1e7..5288b22 100644 --- a/Kconfig +++ b/Kconfig @@ -185,7 +185,7 @@ config LAZY_FP_SWITCH and restored on each entry---this save/restore is entirely done in Palacios. - + endmenu source "palacios/src/extensions/Kconfig" @@ -416,6 +416,28 @@ endmenu source "palacios/src/gears/Kconfig" + +menu "HVM" + +config HVM + bool "Support Hybrid Virtual Machines" + default n + help + If set, it is possible to make VMs that are partitioned + (cores, memory, devices, hardware access, etc) into + a part ("the ROS") that supports normal VM operation and + a part ("the HRT") that supports Hybrid Run-Times, + for example Nautilus-based HRTs for parallel languages. + +config DEBUG_HVM + depends on HVM + bool "Enable HVM debugging in Palacios" + default n + help + Enable HVM debugging output + +endmenu + menu "Debug configuration" ## Is unwind information useful diff --git a/palacios/include/palacios/vmm_hvm.h b/palacios/include/palacios/vmm_hvm.h new file mode 100644 index 0000000..423b80d --- /dev/null +++ b/palacios/include/palacios/vmm_hvm.h @@ -0,0 +1,66 @@ +/* + * 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) 2015, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +#ifndef __VMM_HVM_H +#define __VMM_HVM_H + + +#ifdef __V3VEE__ + +#include + +struct v3_vm_hvm { + uint8_t is_hvm; + uint32_t first_hrt_core; + uint64_t first_hrt_gpa; + struct v3_cfg_file *hrt_file; +}; + +struct v3_core_hvm { + uint8_t is_hrt; +}; + +struct v3_xml; + +int v3_init_hvm(); +int v3_deinit_hvm(); + +int v3_init_hvm_vm(struct v3_vm_info *vm, struct v3_xml *config); +int v3_deinit_hvm_vm(struct v3_vm_info *vm); + + +int v3_init_hvm_core(struct guest_info *core); +int v3_deinit_hvm_core(struct guest_info *core); + + +uint64_t v3_get_hvm_ros_memsize(struct v3_vm_info *vm); +uint64_t v3_get_hvm_hrt_memsize(struct v3_vm_info *vm); +int v3_is_hvm_ros_mem_gpa(struct v3_vm_info *vm, addr_t gpa); +int v3_is_hvm_hrt_mem_gpa(struct v3_vm_info *vm, addr_t gpa); + +uint32_t v3_get_hvm_ros_cores(struct v3_vm_info *vm); +uint32_t v3_get_hvm_hrt_cores(struct v3_vm_info *vm); +int v3_is_hvm_ros_core(struct guest_info *core); +int v3_is_hvm_hrt_core(struct guest_info *core); + + +#endif /* ! __V3VEE__ */ + + +#endif diff --git a/palacios/src/palacios/Makefile b/palacios/src/palacios/Makefile index dee8c0d..dd40f40 100644 --- a/palacios/src/palacios/Makefile +++ b/palacios/src/palacios/Makefile @@ -93,4 +93,6 @@ obj-$(V3_CONFIG_SYMMOD) += vmm_symmod.o obj-$(V3_CONFIG_MEM_TRACK) += vmm_mem_track.o +obj-$(V3_CONFIG_HVM) += vmm_hvm.o + obj-y += mmu/ diff --git a/palacios/src/palacios/vmm_hvm.c b/palacios/src/palacios/vmm_hvm.c new file mode 100644 index 0000000..20c2408 --- /dev/null +++ b/palacios/src/palacios/vmm_hvm.c @@ -0,0 +1,258 @@ +/* + * 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) 2015, The V3VEE Project + * All rights reserved. + * + * Author: Peter Dinda + * + * 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 +#include + +/* + + MEM = Total size of memory in the GPA (in MB) + ROS_MEM = Total size of memory for the ROS (in MB) ( + + + + RAM (MB) Note these are + backward compatible + + + (MB) + + + +*/ + +#ifndef V3_CONFIG_DEBUG_HVM +#undef PrintDebug +#define PrintDebug(fmt, args...) +#endif + +int v3_init_hvm() +{ + PrintDebug(VM_NONE,VCORE_NONE, "hvm: init\n"); + return 0; +} + +int v3_deinit_hvm() +{ + PrintDebug(VM_NONE,VCORE_NONE, "hvm: deinit\n"); + return 0; +} + + +#define CEIL_DIV(x,y) (((x)/(y)) + !!((x)%(y))) + +int v3_init_hvm_vm(struct v3_vm_info *vm, struct v3_xml *config) +{ + v3_cfg_tree_t *hvm_config; + v3_cfg_tree_t *ros_config; + v3_cfg_tree_t *hrt_config; + char *enable; + char *ros_cores; + char *ros_mem; + char *hrt_file_id; + + PrintDebug(vm, VCORE_NONE, "hvm: vm init\n"); + + /* + Defaults - all ROS + */ + memset(&vm->hvm_state,0,sizeof(struct v3_vm_hvm)); + vm->hvm_state.is_hvm=0; + vm->hvm_state.first_hrt_core=vm->num_cores; + vm->hvm_state.first_hrt_gpa=vm->mem_size; + + if (!config || !(hvm_config=v3_cfg_subtree(config,"hvm"))) { + PrintDebug(vm,VCORE_NONE,"hvm: no HVM configuration found (all HW is ROS)\n"); + goto out_ok; + } + + if (!(enable=v3_cfg_val(hvm_config,"enable")) || strcasecmp(enable,"y")) { + PrintDebug(vm,VCORE_NONE,"hvm: HVM configuration disabled (all HW is ROS)\n"); + goto out_ok; + } + + if (!(ros_config=v3_cfg_subtree(hvm_config,"ros"))) { + PrintError(vm,VCORE_NONE,"hvm: HVM configuration without ROS block...\n"); + return -1; + } + + if (!(ros_cores=v3_cfg_val(ros_config,"cores"))) { + PrintError(vm,VCORE_NONE,"hvm: ROS block without cores...\n"); + return -1; + } + + vm->hvm_state.first_hrt_core = ((uint32_t)atoi(ros_cores)); + + if (!(ros_mem=v3_cfg_val(ros_config,"mem"))) { + PrintError(vm,VCORE_NONE,"hvm: ROS block without mem...\n"); + return -1; + } + + vm->hvm_state.first_hrt_gpa = ((uint64_t)atoi(ros_mem))*1024*1024; + + if (!(hrt_config=v3_cfg_subtree(hvm_config,"hrt"))) { + PrintError(vm,VCORE_NONE,"hvm: HVM configuration without HRT block...\n"); + return -1; + } + + if (!(hrt_file_id=v3_cfg_val(hrt_config,"file_id"))) { + PrintError(vm,VCORE_NONE,"hvm: HRT block without file_id...\n"); + return -1; + } + + vm->hvm_state.hrt_file = v3_cfg_get_file(vm,hrt_file_id); + + if (!vm->hvm_state.hrt_file) { + PrintError(vm,VCORE_NONE,"hvm: HRT block contains bad file_id (%s)\n",hrt_file_id); + return -1; + } + + // XXX sanity check config here + + vm->hvm_state.is_hvm=1; + + out_ok: + if (vm->hvm_state.is_hvm) { + V3_Print(vm,VCORE_NONE,"hvm: [ROS: cores 0..%u, mem 0..%p] [HRT: cores %u..%u, mem %p..%p, file_id=%s (tag %s)]\n", + vm->hvm_state.first_hrt_core-1, + (void*) vm->hvm_state.first_hrt_gpa-1, + vm->hvm_state.first_hrt_core, + vm->num_cores-1, + (void*) vm->hvm_state.first_hrt_gpa, + (void*)vm->mem_size-1, + hrt_file_id, + vm->hvm_state.hrt_file->tag); + } else { + V3_Print(vm,VCORE_NONE,"hvm: This is a pure ROS VM\n"); + } + return 0; + +} + +int v3_deinit_hvm_vm(struct v3_vm_info *vm) +{ + PrintDebug(vm, VCORE_NONE, "hvm: HVM deinit\n"); + + return 0; +} + +int v3_init_hvm_core(struct guest_info *core) +{ + memset(&core->hvm_state,0,sizeof(core->hvm_state)); + if (core->vm_info->hvm_state.is_hvm) { + if (core->vcpu_id >= core->vm_info->hvm_state.first_hrt_core) { + core->hvm_state.is_hrt=1; + } + } + return 0; +} + +int v3_deinit_hvm_core(struct guest_info *core) +{ + return 0; +} + + +uint64_t v3_get_hvm_ros_memsize(struct v3_vm_info *vm) +{ + if (vm->hvm_state.is_hvm) { + return vm->hvm_state.first_hrt_gpa; + } else { + return vm->mem_size; + } +} +uint64_t v3_get_hvm_hrt_memsize(struct v3_vm_info *vm) +{ + if (vm->hvm_state.is_hvm) { + return vm->mem_size - vm->hvm_state.first_hrt_gpa; + } else { + return 0; + } +} + +uint32_t v3_get_hvm_ros_cores(struct v3_vm_info *vm) +{ + if (vm->hvm_state.is_hvm) { + return vm->hvm_state.first_hrt_core; + } else { + return vm->num_cores; + } +} + +uint32_t v3_get_hvm_hrt_cores(struct v3_vm_info *vm) +{ + if (vm->hvm_state.is_hvm) { + return vm->num_cores - vm->hvm_state.first_hrt_core; + } else { + return 0; + } +} + + +int v3_is_hvm_ros_mem_gpa(struct v3_vm_info *vm, addr_t gpa) +{ + if (vm->hvm_state.is_hvm) { + return gpa>=0 && gpahvm_state.first_hrt_gpa; + } else { + return 1; + } +} + +int v3_is_hvm_hrt_mem_gpa(struct v3_vm_info *vm, addr_t gpa) +{ + if (vm->hvm_state.is_hvm) { + return gpa>=vm->hvm_state.first_hrt_gpa && gpamem_size; + } else { + return 0; + } +} + +int v3_is_hvm_hrt_core(struct guest_info *core) +{ + return core->hvm_state.is_hrt; +} + +int v3_is_hvm_ros_core(struct guest_info *core) +{ + return !core->hvm_state.is_hrt; +} +