#include <palacios/vmm_config.h>
#include <palacios/vmm_hashtable.h>
-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)
+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);
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));
+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
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;
-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;
}
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;
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));
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 <palacios/vm_guest_mem.h>
+
+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;
}
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);
}
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;
+}