Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


add cleanup for Palacios extensions, add per-core data to extensions
Kyle Hale [Fri, 20 Jul 2012 00:20:42 +0000 (19:20 -0500)]
extensions can now have their own per-core extension state without
adding cruft to the guest_info structure

palacios/include/palacios/vmm_extensions.h
palacios/src/extensions/ext_inspector.c
palacios/src/gears/ext_execve_hook.c
palacios/src/gears/ext_sw_intr.c
palacios/src/gears/ext_syscall_hijack.c
palacios/src/palacios/vm_guest.c
palacios/src/palacios/vmm_extensions.c

index fdddb69..a7c1718 100644 (file)
@@ -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)                                        \
index 4c58775..cceafab 100644 (file)
@@ -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];
 
index c7307ab..8c26867 100644 (file)
@@ -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;
index 9d9bebf..8219447 100644 (file)
@@ -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) {
index 7aab405..e6cc5e4 100644 (file)
@@ -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);
index e17feb9..957c3dd 100644 (file)
@@ -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);
 
index b46af1b..ee16ca0 100644 (file)
@@ -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;
+}
+