From: Jack Lange Date: Thu, 3 Mar 2011 21:22:25 +0000 (-0600) Subject: added extension framework X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=f18097c35ddc13572ab41e03ad7a14430cff11ac;p=palacios.git added extension framework --- diff --git a/palacios/include/palacios/vm_guest.h b/palacios/include/palacios/vm_guest.h index 078bbb9..d67fd9f 100644 --- a/palacios/include/palacios/vm_guest.h +++ b/palacios/include/palacios/vm_guest.h @@ -36,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_TELEMETRY #include @@ -164,13 +165,16 @@ struct v3_vm_info { v3_vm_operating_mode_t run_state; + + + + struct v3_extensions extensions; + #ifdef CONFIG_SYMBIOTIC /* Symbiotic state */ struct v3_sym_vm_state sym_vm_state; #endif - - #ifdef CONFIG_TELEMETRY uint_t enable_telemetry; struct v3_telemetry_state telemetry; diff --git a/palacios/include/palacios/vmm_extensions.h b/palacios/include/palacios/vmm_extensions.h index c6a2ae2..0135f88 100644 --- a/palacios/include/palacios/vmm_extensions.h +++ b/palacios/include/palacios/vmm_extensions.h @@ -24,23 +24,36 @@ #include #include -#include +#include + + +struct v3_vm_info; +struct guest_info; + +struct v3_extensions { + struct list_head extensions; + struct list_head on_exits; + struct list_head on_entries; +}; + struct v3_extension_impl { char * name; - int (*init)(struct v3_vm_info * vm, v3_cfg_tree_t * cfg); + int (*init)(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data); int (*deinit)(struct v3_vm_info * vm, void * priv_data); int (*core_init)(struct guest_info * core); int (*core_deinit)(struct guest_info * core); + int (*on_entry)(struct guest_info * core); + int (*on_exit)(struct guest_info * core); }; - - struct v3_extension { struct v3_extension_impl * impl; void * priv_data; struct list_head node; + struct list_head exit_node; + struct list_head entry_node; }; @@ -49,6 +62,9 @@ int V3_init_extensions(); int V3_deinit_extensions(); +int v3_init_ext_manager(struct v3_vm_info * vm); +int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg); + #define register_extension(ext) \ static struct v3_extension_impl * _v3_ext \ diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index c85c235..73926cc 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -497,6 +497,7 @@ int v3_init_vm(struct v3_vm_info * vm) { v3_init_cpuid_map(vm); v3_init_host_events(vm); v3_init_intr_routers(vm); + v3_init_ext_manager(vm); // Initialize the memory map if (v3_init_mem_map(vm) == -1) { diff --git a/palacios/src/palacios/vmm_config.c b/palacios/src/palacios/vmm_config.c index d97beac..f24dc38 100644 --- a/palacios/src/palacios/vmm_config.c +++ b/palacios/src/palacios/vmm_config.c @@ -58,6 +58,7 @@ struct file_idx_table { static int setup_memory_map(struct v3_vm_info * vm, v3_cfg_tree_t * cfg); +static int setup_extensions(struct v3_vm_info * vm, v3_cfg_tree_t * cfg); static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg); @@ -369,9 +370,18 @@ static int post_config_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintError("Setting up guest memory map failed...\n"); return -1; } - - //v3_hook_io_port(info, 1234, &IO_Read, NULL, info); - + + /* + * Initialize configured extensions + */ + if (setup_extensions(vm, cfg) == -1) { + PrintError("Failed to setup extensions\n"); + return -1; + } + + /* + * Initialize configured devices + */ if (setup_devices(vm, cfg) == -1) { PrintError("Failed to setup devices\n"); return -1; @@ -565,6 +575,24 @@ static int setup_memory_map(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { } +static int setup_extensions(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { + v3_cfg_tree_t * extension = v3_cfg_subtree(v3_cfg_subtree(cfg, "extensions"), "extension"); + + while (extension) { + char * ext_name = v3_cfg_val(extension, "name"); + + V3_Print("Configuring extension %s\n", ext_name); + + if (v3_add_extension(vm, ext_name, extension) == -1) { + PrintError("Error adding extension %s\n", ext_name); + return -1; + } + + extension = v3_cfg_next_branch(extension); + } + + return 0; +} static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { @@ -591,4 +619,3 @@ static int setup_devices(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { - diff --git a/palacios/src/palacios/vmm_extensions.c b/palacios/src/palacios/vmm_extensions.c index 40a0dd0..de1cfa0 100644 --- a/palacios/src/palacios/vmm_extensions.c +++ b/palacios/src/palacios/vmm_extensions.c @@ -20,7 +20,7 @@ #include #include - +#include #include @@ -75,3 +75,53 @@ int V3_deinit_extensions() { } +int v3_init_ext_manager(struct v3_vm_info * vm) { + struct v3_extensions * ext_state = &(vm->extensions); + + INIT_LIST_HEAD(&(ext_state->extensions)); + INIT_LIST_HEAD(&(ext_state->on_exits)); + INIT_LIST_HEAD(&(ext_state->on_entries)); + + return 0; +} + +int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg) { + struct v3_extension_impl * impl = NULL; + struct v3_extension * ext = NULL; + + impl = (void *)v3_htable_search(ext_table, (addr_t)name); + + if (impl == NULL) { + PrintError("Could not find requested extension (%s)\n", name); + return -1; + } + + V3_ASSERT(impl->init); + + ext = V3_Malloc(sizeof(struct v3_extension)); + + if (!ext) { + PrintError("Could not allocate extension\n"); + return -1; + } + + ext->impl = impl; + + if (impl->init(vm, cfg, &(ext->priv_data)) == -1) { + PrintError("Error initializing Extension (%s)\n", name); + V3_Free(ext); + return -1; + } + + list_add(&(ext->node), &(vm->extensions.extensions)); + + if (impl->on_exit) { + list_add(&(ext->exit_node), &(vm->extensions.on_exits)); + } + + if (impl->on_entry) { + list_add(&(ext->entry_node), &(vm->extensions.on_entries)); + } + + return 0; +} diff --git a/palacios/src/palacios/vmm_mtrr.c b/palacios/src/palacios/vmm_mtrr.c index 4c563ce..5e27afc 100644 --- a/palacios/src/palacios/vmm_mtrr.c +++ b/palacios/src/palacios/vmm_mtrr.c @@ -77,9 +77,10 @@ static int mtrr_cap_write(struct guest_info * core, uint32_t msr, struct v3_msr -static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { +static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** priv_data) { + V3_Print("Intializing MTRR extension\n"); v3_hook_msr(vm, MTRR_CAP_MSR, mtrr_cap_read, mtrr_cap_write, NULL); @@ -88,7 +89,7 @@ static int init_mtrrs(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { } -struct v3_extension_impl mtrr_ext = { +static struct v3_extension_impl mtrr_ext = { .name = "MTRRS", .init = init_mtrrs, .deinit = NULL, diff --git a/palacios/src/palacios/vmm_time.c b/palacios/src/palacios/vmm_time.c index 2880f5d..357bae4 100644 --- a/palacios/src/palacios/vmm_time.c +++ b/palacios/src/palacios/vmm_time.c @@ -96,6 +96,14 @@ int v3_start_time(struct guest_info * info) { return 0; } +int v3_offset_time( struct guest_info * info, sint64_t offset ) +{ + struct vm_time * time_state = &(info->time_state); +// PrintDebug("Adding additional offset of %lld to guest time.\n", offset); + time_state->guest_host_offset += offset; + return 0; +} + // Control guest time in relation to host time so that the two stay // appropriately synchronized to the extent possible. int v3_adjust_time(struct guest_info * info) { @@ -190,13 +198,7 @@ v3_time_enter_vm( struct guest_info * info ) return 0; } -int v3_offset_time( struct guest_info * info, sint64_t offset ) -{ - struct vm_time * time_state = &(info->time_state); -// PrintDebug("Adding additional offset of %lld to guest time.\n", offset); - time_state->guest_host_offset += offset; - return 0; -} + struct v3_timer * v3_add_timer(struct guest_info * info, struct v3_timer_ops * ops,