From: Kyle Hale Date: Fri, 20 Jul 2012 00:20:42 +0000 (-0500) Subject: add cleanup for Palacios extensions, add per-core data to extensions X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=c900a49cfd8ff982a35bb7385fbd927e961569a0 add cleanup for Palacios extensions, add per-core data to extensions extensions can now have their own per-core extension state without adding cruft to the guest_info structure --- diff --git a/palacios/include/palacios/vmm_extensions.h b/palacios/include/palacios/vmm_extensions.h index fdddb69..a7c1718 100644 --- a/palacios/include/palacios/vmm_extensions.h +++ b/palacios/include/palacios/vmm_extensions.h @@ -41,8 +41,8 @@ struct v3_extension_impl { char * name; 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, void * priv_data); - int (*core_deinit)(struct guest_info * core, void * priv_data); + int (*core_init)(struct guest_info * core, void * priv_data, void ** core_data); + int (*core_deinit)(struct guest_info * core, void * priv_data, void * core_data); int (*on_entry)(struct guest_info * core, void * priv_data); int (*on_exit)(struct guest_info * core, void * priv_data); }; @@ -54,6 +54,9 @@ struct v3_extension { struct list_head node; struct list_head exit_node; struct list_head entry_node; + + // KCH: has to be last entry in this struct + void * core_ext_priv_data[0]; }; @@ -63,10 +66,13 @@ int V3_deinit_extensions(); int v3_init_ext_manager(struct v3_vm_info * vm); +int v3_deinit_ext_manager(struct v3_vm_info * vm); int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * cfg); int v3_init_core_extensions(struct guest_info * core); +int v3_deinit_core_extensions(struct guest_info * core); void * v3_get_extension_state(struct v3_vm_info * vm, const char * name); +void * v3_get_ext_core_state (struct guest_info * core, const char * name); #define register_extension(ext) \ diff --git a/palacios/src/extensions/ext_inspector.c b/palacios/src/extensions/ext_inspector.c index 4c58775..cceafab 100644 --- a/palacios/src/extensions/ext_inspector.c +++ b/palacios/src/extensions/ext_inspector.c @@ -55,7 +55,7 @@ static int init_inspector(struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** p } -static int init_inspector_core(struct guest_info * core, void * priv_data) { +static int init_inspector_core(struct guest_info * core, void * priv_data, void ** core_data) { struct v3_inspector_state * vm_state = priv_data; char core_name[50]; diff --git a/palacios/src/gears/ext_execve_hook.c b/palacios/src/gears/ext_execve_hook.c index c7307ab..8c26867 100644 --- a/palacios/src/gears/ext_execve_hook.c +++ b/palacios/src/gears/ext_execve_hook.c @@ -56,7 +56,7 @@ static int init_exec_hooks (struct v3_vm_info * vm, v3_cfg_tree_t * cfg, void ** return 0; } -static int init_exec_hooks_core (struct guest_info * core, void * priv_data) { +static int init_exec_hooks_core (struct guest_info * core, void * priv_data, void ** core_data) { struct v3_exec_hooks * hooks = &exec_hooks; INIT_LIST_HEAD(&(hooks->hook_list)); hooks->bin_table = v3_create_htable(0, exec_hash_fn, exec_eq_fn); @@ -76,7 +76,7 @@ static int init_exec_hooks_core (struct guest_info * core, void * priv_data) { return 0; } -static int deinit_exec_hooks_core (struct guest_info * core, void * priv_data) { +static int deinit_exec_hooks_core (struct guest_info * core, void * priv_data, void * core_data) { struct v3_exec_hooks * hooks = &exec_hooks; struct exec_hook * hook = NULL; struct exec_hook * tmp = NULL; diff --git a/palacios/src/gears/ext_sw_intr.c b/palacios/src/gears/ext_sw_intr.c index 9d9bebf..8219447 100644 --- a/palacios/src/gears/ext_sw_intr.c +++ b/palacios/src/gears/ext_sw_intr.c @@ -78,7 +78,7 @@ static int init_swintr_core_vmx (struct guest_info * core, void * priv_data) { } -static int init_swintr_intercept_core (struct guest_info * core, void * priv_data) { +static int init_swintr_intercept_core (struct guest_info * core, void * priv_data, void ** core_data) { v3_cpu_arch_t cpu_type = v3_get_cpu_type(V3_Get_CPU()); switch (cpu_type) { diff --git a/palacios/src/gears/ext_syscall_hijack.c b/palacios/src/gears/ext_syscall_hijack.c index 7aab405..e6cc5e4 100644 --- a/palacios/src/gears/ext_syscall_hijack.c +++ b/palacios/src/gears/ext_syscall_hijack.c @@ -315,7 +315,7 @@ static int v3_handle_lstar_read (struct guest_info * core, uint_t msr, struct v3 #endif -static int init_syscall_hijack_core (struct guest_info * core, void * priv_data) { +static int init_syscall_hijack_core (struct guest_info * core, void * priv_data, void ** core_data) { #ifdef V3_CONFIG_EXT_SW_INTERRUPTS v3_hook_swintr(core, SYSCALL_INT_VECTOR, v3_syscall_handler, NULL); diff --git a/palacios/src/palacios/vm_guest.c b/palacios/src/palacios/vm_guest.c index e17feb9..957c3dd 100644 --- a/palacios/src/palacios/vm_guest.c +++ b/palacios/src/palacios/vm_guest.c @@ -329,6 +329,7 @@ int v3_free_vm_internal(struct v3_vm_info * vm) { v3_delete_mem_map(vm); v3_deinit_shdw_impl(vm); + v3_deinit_ext_manager(vm); v3_deinit_intr_routers(vm); v3_deinit_host_events(vm); diff --git a/palacios/src/palacios/vmm_extensions.c b/palacios/src/palacios/vmm_extensions.c index b46af1b..ee16ca0 100644 --- a/palacios/src/palacios/vmm_extensions.c +++ b/palacios/src/palacios/vmm_extensions.c @@ -81,6 +81,7 @@ int V3_init_extensions() { int V3_deinit_extensions() { v3_free_htable(ext_table, 0, 0); + return 0; } @@ -97,9 +98,37 @@ int v3_init_ext_manager(struct v3_vm_info * vm) { int v3_deinit_ext_manager(struct v3_vm_info * vm) { + struct v3_extensions * ext_state = &(vm->extensions); + struct v3_extension * ext = NULL; + struct v3_extension * tmp = NULL; + int i; + + /* deinit per-core state first */ + for (i = 0; i < vm->num_cores; i++) + v3_deinit_core_extensions(&(vm->cores[i])); + + list_for_each_entry_safe(ext, tmp, &(ext_state->extensions), node) { + + V3_Print("Cleaning up Extension (%s)\n", ext->impl->name); + if ((ext->impl) && (ext->impl->deinit)) { + if (ext->impl->deinit(vm, ext->priv_data) == -1) { + PrintError("Error cleaning up extension (%s)\n", ext->impl->name); + return -1; + } + } - PrintError("I should really do something here... \n"); - return -1; + if (ext->impl->on_exit) + list_del(&ext->exit_node); + + if (ext->impl->on_entry) + list_del(&ext->entry_node); + + list_del(&ext->node); + V3_Free(ext); + + } + + return 0; } @@ -107,6 +136,7 @@ int v3_deinit_ext_manager(struct v3_vm_info * vm) { 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; + int ext_size; impl = (void *)v3_htable_search(ext_table, (addr_t)name); @@ -117,7 +147,9 @@ int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * V3_ASSERT(impl->init); - ext = V3_Malloc(sizeof(struct v3_extension)); + /* this allows each extension to track its own per-core state */ + ext_size = sizeof(struct v3_extension) + (sizeof(void *) * vm->num_cores); + ext = V3_Malloc(ext_size); if (!ext) { PrintError("Could not allocate extension\n"); @@ -147,10 +179,11 @@ int v3_add_extension(struct v3_vm_info * vm, const char * name, v3_cfg_tree_t * int v3_init_core_extensions(struct guest_info * core) { struct v3_extension * ext = NULL; + uint32_t cpuid = core->vcpu_id; list_for_each_entry(ext, &(core->vm_info->extensions.extensions), node) { if ((ext->impl) && (ext->impl->core_init)) { - if (ext->impl->core_init(core, ext->priv_data) == -1) { + if (ext->impl->core_init(core, ext->priv_data, &(ext->core_ext_priv_data[cpuid])) == -1) { PrintError("Error configuring per core extension %s on core %d\n", ext->impl->name, core->vcpu_id); return -1; @@ -162,6 +195,25 @@ int v3_init_core_extensions(struct guest_info * core) { } +int v3_deinit_core_extensions (struct guest_info * core) { + struct v3_extension * ext = NULL; + struct v3_extension * tmp = NULL; + struct v3_vm_info * vm = core->vm_info; + uint32_t cpuid = core->vcpu_id; + + list_for_each_entry_safe(ext, tmp, &(vm->extensions.extensions), node) { + if ((ext->impl) && (ext->impl->core_deinit)) { + if (ext->impl->core_deinit(core, ext->priv_data, ext->core_ext_priv_data[cpuid]) == -1) { + PrintError("Error tearing down per core extension %s on core %d\n", + ext->impl->name, cpuid); + return -1; + } + } + } + + return 0; +} + void * v3_get_extension_state(struct v3_vm_info * vm, const char * name) { @@ -175,3 +227,19 @@ void * v3_get_extension_state(struct v3_vm_info * vm, const char * name) { return NULL; } + + +void * v3_get_ext_core_state (struct guest_info * core, const char * name) { + struct v3_extension * ext = NULL; + struct v3_vm_info * vm = core->vm_info; + uint32_t cpuid = core->vcpu_id; + + list_for_each_entry(ext, &(vm->extensions.extensions), node) { + if (strncmp(ext->impl->name, name, strlen(ext->impl->name)) == 0) { + return ext->core_ext_priv_data[cpuid]; + } + } + + return NULL; +} +