From: Jack Lange Date: Sat, 13 Mar 2010 00:24:03 +0000 (-0600) Subject: symbiotic updates for module loading X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=1423d1b79cde22d1967efb0465a9ca88a2b8a199;p=palacios.git symbiotic updates for module loading --- diff --git a/palacios/include/palacios/vmm_symmod.h b/palacios/include/palacios/vmm_symmod.h index b6d3745..57ef01c 100644 --- a/palacios/include/palacios/vmm_symmod.h +++ b/palacios/include/palacios/vmm_symmod.h @@ -25,19 +25,11 @@ #include #include -struct v3_symmod_loader_ops { - int (*load_module)(struct v3_vm_info * vm, char * name, int len, void * priv_data); -}; -struct v3_symmod_state { - struct v3_symmod_loader_ops * loader_ops; - void * loader_data; - struct hashtable * module_table; -}; #define V3_SYMMOD_INV (0x00000000) #define V3_SYMMOD_LNX (0x00000001) @@ -60,6 +52,25 @@ struct v3_sym_module { +struct v3_symmod_loader_ops { + + int (*load_module)(struct v3_vm_info * vm, struct v3_sym_module * mod, void * priv_data); +}; + + +struct v3_symmod_state { + + struct v3_symmod_loader_ops * loader_ops; + void * loader_data; + + struct hashtable * module_table; + + /* List containing V3 symbols */ + /* (defined in vmm_symmod.c) */ + struct list_head v3_sym_list; +}; + + int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data); diff --git a/palacios/include/palacios/vmm_symspy.h b/palacios/include/palacios/vmm_symspy.h index 5b17b39..b2def67 100644 --- a/palacios/include/palacios/vmm_symspy.h +++ b/palacios/include/palacios/vmm_symspy.h @@ -32,7 +32,8 @@ struct v3_symspy_global_page { union { uint32_t feature_flags; struct { - uint_t pci_map_valid : 1; + uint8_t pci_map_valid : 1; + uint8_t symmod_enabled : 1; } __attribute__((packed)); } __attribute__((packed)); @@ -87,6 +88,8 @@ int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, +struct v3_symspy_global_page * v3_sym_get_symspy_vm(struct v3_vm_info * vm); +struct v3_symspy_local_page * v3_sym_get_symspy_core(struct guest_info * core); #endif diff --git a/palacios/src/devices/lnx_virtio_symmod.c b/palacios/src/devices/lnx_virtio_symmod.c index d6df7a7..46b9ecb 100644 --- a/palacios/src/devices/lnx_virtio_symmod.c +++ b/palacios/src/devices/lnx_virtio_symmod.c @@ -103,7 +103,7 @@ static int handle_xfer_kick(struct guest_info * core, struct virtio_sym_state * PrintDebug("SYMMOD: VIRTIO SYMMOD Kick on loader queue\n"); - while (q->cur_avail_idx < q->avail->index) { + while (q->cur_avail_idx ! q->avail->index) { struct vring_desc * hdr_desc = NULL; struct vring_desc * buf_desc = NULL; struct vring_desc * status_desc = NULL; @@ -387,13 +387,14 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u -static int virtio_load_module(struct v3_vm_info * vm, char * name, int mod_size, void * priv_data) { +static int virtio_load_module(struct v3_vm_info * vm, struct v3_sym_module * mod, void * priv_data) { struct virtio_sym_state * virtio = (struct virtio_sym_state *)priv_data; // struct virtio_queue * q = virtio->cur_queue; struct virtio_queue * q = &(virtio->queue[NOTIFY_QUEUE]); + uint32_t mod_size = mod->end_addr - mod->start_addr; - if (strlen(name) >= 32) { - PrintError("Module name is too long... (%d bytes) limit is 32\n", (uint32_t)strlen(name)); + if (strlen(mod->name) >= 32) { + PrintError("Module name is too long... (%d bytes) limit is 32\n", (uint32_t)strlen(mod->name)); return -1; } @@ -427,7 +428,7 @@ static int virtio_load_module(struct v3_vm_info * vm, char * name, int mod_size, memset(notifier, 0, sizeof(struct symmod_hdr)); // set the module name - memcpy(notifier->name, name, strlen(name)); + memcpy(notifier->name, mod->name, strlen(mod->name)); // set module length notifier->num_bytes = mod_size; diff --git a/palacios/src/palacios/vmm_symmod.c b/palacios/src/palacios/vmm_symmod.c index 193f511..e2becb9 100644 --- a/palacios/src/palacios/vmm_symmod.c +++ b/palacios/src/palacios/vmm_symmod.c @@ -24,6 +24,7 @@ static struct hashtable * master_mod_table = NULL; + static uint_t mod_hash_fn(addr_t key) { char * name = (char *)key; return v3_hash_buffer((uchar_t *)name, strlen(name)); @@ -65,9 +66,80 @@ int V3_init_symmod() { return 0; } +/* ***************** */ +/* Linkage functions */ +/* ***************** */ + + +/* Data structure containing symbols exported via the symbiotic interface */ +struct v3_symbol_def32 { + uint32_t name_gva; + uint32_t value; +} __attribute__((packed)); + +struct v3_symbol { + char name[256]; + uint64_t linkage; + + struct list_head sym_node; +}; + + + +#include + +static int symbol_hcall_handler(struct guest_info * core, hcall_id_t hcall_id, void * priv_data) { + struct v3_symmod_state * symmod_state = &(core->vm_info->sym_vm_state.symmod_state); + addr_t sym_start_gva = core->vm_regs.rbx; + uint32_t sym_size = core->vm_regs.rcx; + + int i = 0; + + PrintError("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; + struct v3_symbol_def32 * tmp_symbol = NULL; + struct v3_symbol * new_symbol = NULL; + 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"); + 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"); + continue; + } + + PrintError("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)); + + strncpy(new_symbol->name, sym_name, 256); + new_symbol->linkage = tmp_symbol->value; + + list_add(&(new_symbol->sym_node), &(symmod_state->v3_sym_list)); + } + + return 0; +} + + +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); + + 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"); -int v3_init_symmod_vm(struct v3_vm_info * info, v3_cfg_tree_t * cfg) { return 0; } @@ -97,7 +169,7 @@ int v3_load_sym_module(struct v3_vm_info * vm, char * mod_name) { PrintDebug("Loading Module (%s)\n", mod_name); - return symmod_state->loader_ops->load_module(vm, mod->name, mod->end_addr - mod->start_addr, symmod_state->loader_data); + return symmod_state->loader_ops->load_module(vm, mod, symmod_state->loader_data); } diff --git a/palacios/src/palacios/vmm_symspy.c b/palacios/src/palacios/vmm_symspy.c index 53f3e89..1110dd7 100644 --- a/palacios/src/palacios/vmm_symspy.c +++ b/palacios/src/palacios/vmm_symspy.c @@ -180,3 +180,12 @@ int v3_sym_unmap_pci_passthrough(struct v3_vm_info * vm, uint_t bus, uint_t dev, return 0; } + + +struct v3_symspy_global_page * v3_sym_get_symspy_vm(struct v3_vm_info * vm) { + return vm->sym_vm_state.symspy_state.sym_page; +} + +struct v3_symspy_local_page * v3_sym_get_symspy_core(struct guest_info * core) { + return core->sym_core_state.symspy_state.local_page; +}