X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_symmod.c;h=1cb20335bada3db0124f79a6c277c3c6bb9c7688;hb=d22c11cec4e8c3390bfe6bf16ed07f5d073f0d4a;hp=20559a9814d3d22c800896bf955576a15dcdd5d0;hpb=4dbdf474c9eddfc402df451e021e4948a984289b;p=palacios.git diff --git a/palacios/src/palacios/vmm_symmod.c b/palacios/src/palacios/vmm_symmod.c index 20559a9..1cb2033 100644 --- a/palacios/src/palacios/vmm_symmod.c +++ b/palacios/src/palacios/vmm_symmod.c @@ -20,14 +20,17 @@ #include #include #include +#include + +static struct hashtable * capsule_table = NULL; +static LIST_HEAD(capsule_list); -static struct hashtable * master_mod_table = NULL; /* - * This is a place holder to ensure that the _v3_modules section gets created + * This is a place holder to ensure that the _v3_modules section gets created by gcc */ static struct {} null_mod __attribute__((__used__)) \ - __attribute__((unused, __section__ ("_v3_modules"), \ + __attribute__((unused, __section__ ("_v3_capsules"), \ aligned(sizeof(addr_t)))); static uint_t mod_hash_fn(addr_t key) { @@ -43,41 +46,90 @@ static int mod_eq_fn(addr_t key1, addr_t key2) { } +struct capsule_def { + char * name; + addr_t start_addr; + addr_t end_addr; + uint32_t flags; // see 'struct v3_symmod_flags' +} __attribute__((packed)); + + int V3_init_symmod() { - extern struct v3_sym_module __start__v3_modules[]; - extern struct v3_sym_module __stop__v3_modules[]; - struct v3_sym_module * tmp_mod = __start__v3_modules; + extern struct capsule_def __start__v3_capsules[]; + extern struct capsule_def __stop__v3_capsules[]; + struct capsule_def * tmp_def = __start__v3_capsules; int i = 0; - if (tmp_mod == __stop__v3_modules) { - PrintDebug("No Symbiotic modules found\n"); + if (tmp_def == __stop__v3_capsules) { + PrintDebug(VM_NONE, VCORE_NONE, "No Symbiotic capsules found\n"); return 0; } - master_mod_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn); + capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn); + + while (tmp_def != __stop__v3_capsules) { + struct v3_sym_capsule * capsule = NULL; + + if (v3_htable_search(capsule_table, (addr_t)(tmp_def->name))) { + PrintError(VM_NONE, VCORE_NONE, "Multiple instances of Module (%s)\n", tmp_def->name); + return -1; + } + - while (tmp_mod != __stop__v3_modules) { + capsule = V3_Malloc(sizeof(struct v3_sym_capsule)); - if (v3_htable_search(master_mod_table, (addr_t)(tmp_mod->name))) { - PrintError("Multiple instances of Module (%s)\n", tmp_mod->name); + if (!capsule) { + PrintError(VM_NONE, VCORE_NONE, "Cannot allocate in initializing symmod\n"); return -1; } + + + memset(capsule, 0, sizeof(struct v3_sym_capsule)); + + capsule->name = tmp_def->name; + capsule->start_addr = (void *)(tmp_def->start_addr); + capsule->size = tmp_def->end_addr - tmp_def->start_addr; + capsule->flags = tmp_def->flags; - PrintDebug("Registering Symbiotic Module (%s)\n", tmp_mod->name); + + + if (capsule->type == V3_SYMMOD_MOD) { + // parse module + // capsule->capsule_data = v3_sym_module... + // capsule->guest_size = size of linked module + } else if (capsule->type == V3_SYMMOD_LNX) { + capsule->guest_size = capsule->size; + capsule->capsule_data = NULL; + } else { + V3_Free(capsule); + return -1; + } + + PrintDebug(VM_NONE, VCORE_NONE, "Registering Symbiotic Module (%s)\n", tmp_def->name); - if (v3_htable_insert(master_mod_table, - (addr_t)(tmp_mod->name), - (addr_t)(tmp_mod)) == 0) { - PrintError("Could not insert module %s to master list\n", tmp_mod->name); + if (v3_htable_insert(capsule_table, + (addr_t)(tmp_def->name), + (addr_t)(capsule)) == 0) { + PrintError(VM_NONE, VCORE_NONE, "Could not insert module %s to master list\n", tmp_def->name); + V3_Free(capsule); return -1; } - tmp_mod = &(__start__v3_modules[++i]); + + list_add(&(capsule->node), &capsule_list); + + tmp_def = &(__start__v3_capsules[++i]); } return 0; } +int V3_deinit_symmod() { + v3_free_htable(capsule_table, 1, 0); + + return 0; +} + /* ***************** */ /* Linkage functions */ /* ***************** */ @@ -89,6 +141,13 @@ struct v3_symbol_def32 { uint32_t value; } __attribute__((packed)); +struct v3_symbol_def64 { + uint64_t name_gva; + uint64_t value; +} __attribute__((packed)); + + + struct v3_symbol { char name[256]; uint64_t linkage; @@ -107,7 +166,7 @@ static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, v int i = 0; - PrintError("Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size); + PrintError(core->vm_info, core, "Received SYMMOD symbol tables addr=%p, size=%d\n", (void *)sym_start_gva, sym_size); for (i = 0; i < sym_size; i++) { char * sym_name = NULL; @@ -116,21 +175,27 @@ static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, v addr_t sym_gva = sym_start_gva + (sizeof(struct v3_symbol_def32) * i); - if (guest_va_to_host_va(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) { - PrintError("Could not locate symbiotic symbol definition\n"); + if (v3_gva_to_hva(core, sym_gva, (addr_t *)&(tmp_symbol)) == -1) { + PrintError(core->vm_info, core, "Could not locate symbiotic symbol definition\n"); continue; } - if (guest_va_to_host_va(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) { - PrintError("Could not locate symbiotic symbol name\n"); + if (v3_gva_to_hva(core, tmp_symbol->name_gva, (addr_t *)&(sym_name)) == -1) { + PrintError(core->vm_info, core, "Could not locate symbiotic symbol name\n"); continue; } - PrintError("Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value); + PrintError(core->vm_info, core, "Symbiotic Symbol (%s) at %p\n", sym_name, (void *)(addr_t)tmp_symbol->value); new_symbol = (struct v3_symbol *)V3_Malloc(sizeof(struct v3_symbol)); + if (!new_symbol) { + PrintError(core->vm_info, core, "Cannot allocate in symbiotic hcall handler\n"); + return -1; + } + strncpy(new_symbol->name, sym_name, 256); + new_symbol->name[255] = 0; new_symbol->linkage = tmp_symbol->value; list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list)); @@ -143,18 +208,51 @@ static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, v int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state); struct v3_symspy_global_page * sym_page = v3_sym_get_symspy_vm(vm); + struct v3_sym_capsule * tmp_capsule = NULL; + + symmod_state->capsule_table = v3_create_htable(0, mod_hash_fn, mod_eq_fn); + + + // Add modules to local hash table, should be keyed to config + list_for_each_entry(tmp_capsule, &capsule_list, node) { + V3_Print(vm, VCORE_NONE, "Adding %s to local module table\n", tmp_capsule->name); + if (v3_htable_insert(symmod_state->capsule_table, + (addr_t)(tmp_capsule->name), + (addr_t)(tmp_capsule)) == 0) { + PrintError(vm, VCORE_NONE, "Could not insert module %s to vm local list\n", tmp_capsule->name); + return -1; + } + symmod_state->num_avail_capsules++; + } + symmod_state->num_loaded_capsules = 0; sym_page->symmod_enabled = 1; v3_register_hypercall(vm, SYMMOD_SYMS_HCALL, symbol_hcall_handler, NULL); INIT_LIST_HEAD(&(symmod_state->v3_sym_list)); - V3_Print("Symmod initialized\n"); + V3_Print(vm, VCORE_NONE, "Symmod initialized\n"); return 0; } +int v3_deinit_symmod_vm(struct v3_vm_info * vm) { + struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state); + struct v3_symbol * sym = NULL; + struct v3_symbol * tmp_sym = NULL; + + v3_remove_hypercall(vm, SYMMOD_SYMS_HCALL); + + v3_free_htable(symmod_state->capsule_table, 0, 0); + + list_for_each_entry_safe(sym, tmp_sym, &(symmod_state->v3_sym_list), sym_node) { + list_del(&(sym->sym_node)); + V3_Free(sym); + } + + return 0; +} int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data) { @@ -170,28 +268,32 @@ int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * o -int v3_load_sym_module(struct v3_vm_info * vm, char * mod_name) { +int v3_load_sym_capsule(struct v3_vm_info * vm, char * name) { struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state); - struct v3_sym_module * mod = (struct v3_sym_module *)v3_htable_search(master_mod_table, (addr_t)mod_name); + struct v3_sym_capsule * capsule = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name); - if (!mod) { - PrintError("Could not find module %s\n", mod_name); + if (!capsule) { + PrintError(vm, VCORE_NONE, "Could not find capsule %s\n", name); return -1; } - PrintDebug("Loading Module (%s)\n", mod_name); + PrintDebug(vm, VCORE_NONE, "Loading Capsule (%s)\n", name); - return symmod_state->loader_ops->load_module(vm, mod, symmod_state->loader_data); + return symmod_state->loader_ops->load_capsule(vm, capsule, symmod_state->loader_data); } +struct list_head * v3_get_sym_capsule_list() { + return &(capsule_list); +} + -struct v3_sym_module * v3_get_sym_module(struct v3_vm_info * vm, char * name) { - struct v3_sym_module * mod = (struct v3_sym_module *)v3_htable_search(master_mod_table, (addr_t)name); +struct v3_sym_capsule * v3_get_sym_capsule(struct v3_vm_info * vm, char * name) { + struct v3_sym_capsule * mod = (struct v3_sym_capsule *)v3_htable_search(capsule_table, (addr_t)name); if (!mod) { - PrintError("Could not find module %s\n", name); + PrintError(vm, VCORE_NONE, "Could not find module %s\n", name); return NULL; }