From: Jack Lange Date: Fri, 14 May 2010 21:37:44 +0000 (-0500) Subject: symbiotic module changes X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=13d9a33d365278c508b8709288f9c7c2949a50f9 symbiotic module changes --- diff --git a/palacios/include/palacios/vmm_symmod.h b/palacios/include/palacios/vmm_symmod.h index 9433890..526a0c5 100644 --- a/palacios/include/palacios/vmm_symmod.h +++ b/palacios/include/palacios/vmm_symmod.h @@ -30,31 +30,39 @@ - -#define V3_SYMMOD_INV (0x00000000) -#define V3_SYMMOD_LNX (0x00000001) -#define V3_SYMMOD_MOD (0x00000002) -#define V3_SYMMOD_SEC (0x00000003) -union v3_symmod_flags { - uint32_t flags; - struct { - uint8_t type; - } __attribute__((packed)); -} __attribute__((packed)); - - -struct v3_sym_module { +struct v3_sym_capsule { char * name; void * start_addr; - void * end_addr; - uint32_t flags; // see 'struct v3_symmod_flags' -} __attribute__((packed)); + uint32_t size; + uint32_t guest_size; + + union { + uint32_t flags; + struct { +#define V3_SYMMOD_INV (0x00) +#define V3_SYMMOD_LNX (0x01) +#define V3_SYMMOD_MOD (0x02) +#define V3_SYMMOD_SEC (0x03) + uint8_t type; + +#define V3_SYMMOD_ARCH_INV (0x00) +#define V3_SYMMOD_ARCH_i386 (0x01) +#define V3_SYMMOD_ARCH_x86_64 (0x02) + uint8_t arch; + uint16_t rsvd; + } __attribute__((packed)); + } __attribute__((packed)); + + void * capsule_data; + + struct list_head node; +}; struct v3_symmod_loader_ops { - int (*load_module)(struct v3_vm_info * vm, struct v3_sym_module * mod, void * priv_data); + int (*load_capsule)(struct v3_vm_info * vm, struct v3_sym_capsule * mod, void * priv_data); }; @@ -63,7 +71,10 @@ struct v3_symmod_state { struct v3_symmod_loader_ops * loader_ops; void * loader_data; - struct hashtable * module_table; + uint32_t num_avail_capsules; + uint32_t num_loaded_capsules; + + struct hashtable * capsule_table; /* List containing V3 symbols */ /* (defined in vmm_symmod.c) */ @@ -74,24 +85,12 @@ struct v3_symmod_state { int v3_set_symmod_loader(struct v3_vm_info * vm, struct v3_symmod_loader_ops * ops, void * priv_data); -int v3_load_sym_module(struct v3_vm_info * vm, char * mod_name); +int v3_load_sym_capsule(struct v3_vm_info * vm, char * mod_name); int v3_init_symmod_vm(struct v3_vm_info * vm, v3_cfg_tree_t * cfg); -struct v3_sym_module * v3_get_sym_module(struct v3_vm_info * vm, char * name); - - - - - +struct v3_sym_capsule * v3_get_sym_capsule(struct v3_vm_info * vm, char * name); -#define register_module(name, start, end, flags) \ - static char v3_module_name[] = name; \ - static struct v3_sym_module _v3_module \ - __attribute__((__used__)) \ - __attribute__((unused, __section__ ("_v3_modules"), \ - aligned(sizeof(addr_t)))) \ - = {v3_module_name, start, end, flags}; int V3_init_symmod(); diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index 82d4543..2935c43 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -377,7 +377,7 @@ static int key_event_handler(struct v3_vm_info * vm, #endif #ifdef CONFIG_SYMMOD else if (evt->scan_code == 0x40) { // F6 Test symmod load - v3_load_sym_module(vm, "test_32"); + v3_load_sym_capsule(vm, "lnx_test"); } #endif diff --git a/palacios/src/devices/lnx_virtio_symmod.c b/palacios/src/devices/lnx_virtio_symmod.c index 62ed8d3..fb2984b 100644 --- a/palacios/src/devices/lnx_virtio_symmod.c +++ b/palacios/src/devices/lnx_virtio_symmod.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -30,6 +31,8 @@ #define NUM_QUEUES 2 struct sym_config { + uint32_t avail_mods; + uint32_t loaded_mods; } __attribute__((packed)); @@ -41,7 +44,9 @@ struct virtio_sym_state { struct vm_device * pci_bus; struct pci_device * pci_dev; - + struct v3_vm_info * vm; + struct v3_symmod_state * symmod_state; + #define NOTIFY_QUEUE 0 #define LOADER_QUEUE 1 @@ -56,10 +61,41 @@ struct virtio_sym_state { +struct symmod_cmd { +#define CMD_INV 0 +#define CMD_LOAD 1 +#define CMD_LIST 2 + uint32_t cmd; + uint32_t num_cmds; +} __attribute__((packed)); + + // structure of the symmod notifier ring structures struct symmod_hdr { uint32_t num_bytes; char name[32]; + union { + uint32_t flags; + struct { +#define V3_SYMMOD_INV (0x00) +#define V3_SYMMOD_LNX (0x01) +#define V3_SYMMOD_MOD (0x02) +#define V3_SYMMOD_SEC (0x03) + uint8_t type; + +#define V3_SYMMOD_ARCH_INV (0x00) +#define V3_SYMMOD_ARCH_i386 (0x01) +#define V3_SYMMOD_ARCH_x86_64 (0x02) + uint8_t arch; + +#define V3_SYMMOD_ACT_INV (0x00) +#define V3_SYMMOD_ACT_ADVERTISE (0x01) +#define V3_SYMMOD_ACT_LOAD (0x02) + uint8_t action; + + uint8_t rsvd; + } __attribute__((packed)); + } __attribute__((packed)); } __attribute__((packed)); @@ -76,7 +112,8 @@ static int virtio_reset(struct virtio_sym_state * virtio) { virtio->queue[1].queue_size = QUEUE_SIZE; - memset(&(virtio->sym_cfg), 0, sizeof(struct sym_config)); + virtio->sym_cfg.avail_mods = virtio->symmod_state->num_avail_capsules; + virtio->sym_cfg.loaded_mods = virtio->symmod_state->num_loaded_capsules; return 0; } @@ -104,62 +141,79 @@ 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) { - struct vring_desc * hdr_desc = NULL; - struct vring_desc * buf_desc = NULL; - struct vring_desc * status_desc = NULL; + struct vring_desc * cmd_desc = NULL; + struct symmod_cmd * cmd = NULL; uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % QUEUE_SIZE]; uint16_t desc_cnt = get_desc_count(q, desc_idx); - struct symmod_hdr * hdr = NULL; - int i; - uint32_t xfer_len = 0; + struct vring_desc * status_desc = NULL; uint8_t status = 0; uint8_t * status_ptr = NULL; - struct v3_sym_module * module = NULL; - uint32_t offset = 0; - - - PrintDebug("Descriptor Count=%d, index=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE); + int i; + uint32_t xfer_len = 0; - if (desc_cnt < 3) { - PrintError("Symmod loads must include at least 3 descriptors (cnt=%d)\n", desc_cnt); - return -1; - } + cmd_desc = &(q->desc[desc_idx]); - hdr_desc = &(q->desc[desc_idx]); - - if (guest_pa_to_host_va(core, hdr_desc->addr_gpa, (addr_t *)&hdr) == -1) { + if (guest_pa_to_host_va(core, cmd_desc->addr_gpa, (addr_t *)&cmd) == -1) { PrintError("Could not translate SYMMOD header address\n"); return -1; } - desc_idx = hdr_desc->next; - - module = v3_get_sym_module(core->vm_info, hdr->name); + desc_idx = cmd_desc->next; - for (i = 0; i < desc_cnt - 2; i++) { - uint8_t tmp_status = 0; - uint8_t * buf = NULL; + if (cmd->cmd == CMD_LOAD) { + struct vring_desc * name_desc = NULL; + struct vring_desc * buf_desc = NULL; + char * name = NULL; + struct v3_sym_capsule * capsule = NULL; + uint32_t offset = 0; + - buf_desc = &(q->desc[desc_idx]); + PrintDebug("Descriptor Count=%d, index=%d\n", desc_cnt, q->cur_avail_idx % QUEUE_SIZE); + + if (desc_cnt < 3) { + PrintError("Symmod loads must include at least 3 descriptors (cnt=%d)\n", desc_cnt); + return -1; + } + + name_desc = &(q->desc[desc_idx]); - if (guest_pa_to_host_va(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) { - PrintError("Could not translate buffer address\n"); + if (guest_pa_to_host_va(core, name_desc->addr_gpa, (addr_t *)&name) == -1) { + PrintError("Could not translate SYMMOD header address\n"); return -1; } - memcpy(buf, module->start_addr + offset, buf_desc->length); - PrintDebug("Copying module to virtio buffers: SRC=%p, DST=%p, len=%d\n", - (void *)(module->start_addr + offset), (void *)buf, buf_desc->length); + desc_idx = name_desc->next; - if (tmp_status != 0) { - PrintError("Error loading module segment\n"); - status = tmp_status; - } + capsule = v3_get_sym_capsule(core->vm_info, name); + for (i = 0; i < desc_cnt - 3; i++) { + uint8_t tmp_status = 0; + uint8_t * buf = NULL; - offset += buf_desc->length; - xfer_len += buf_desc->length; - desc_idx = buf_desc->next; + buf_desc = &(q->desc[desc_idx]); + + if (guest_pa_to_host_va(core, buf_desc->addr_gpa, (addr_t *)&(buf)) == -1) { + PrintError("Could not translate buffer address\n"); + return -1; + } + + memcpy(buf, capsule->start_addr + offset, buf_desc->length); + PrintDebug("Copying module to virtio buffers: SRC=%p, DST=%p, len=%d\n", + (void *)(capsule->start_addr + offset), (void *)buf, buf_desc->length); + + if (tmp_status != 0) { + PrintError("Error loading module segment\n"); + status = tmp_status; + } + + + offset += buf_desc->length; + xfer_len += buf_desc->length; + desc_idx = buf_desc->next; + } + } else { + PrintError("Invalid SYMMOD Loader command\n"); + return -1; } status_desc = &(q->desc[desc_idx]); @@ -178,6 +232,7 @@ static int handle_xfer_kick(struct guest_info * core, struct virtio_sym_state * q->used->index++; q->cur_avail_idx++; + } @@ -192,6 +247,75 @@ static int handle_xfer_kick(struct guest_info * core, struct virtio_sym_state * } + + +static int handle_notification_kick(struct guest_info * core, struct virtio_sym_state * sym_state) { + // struct virtio_queue * q = sym_state->cur_queue; + struct virtio_queue * q = &(sym_state->queue[NOTIFY_QUEUE]); + struct hashtable_iter * capsule_iter = NULL; + + PrintDebug("SYMMOD: VIRTIO SYMMOD Kick on notification queue\n"); + + capsule_iter = v3_create_htable_iter(sym_state->symmod_state->capsule_table); + + do { + uint16_t desc_idx = q->avail->ring[q->cur_avail_idx % q->queue_size]; + struct vring_desc * hdr_desc = NULL; + struct symmod_hdr * hdr = NULL; + struct v3_sym_capsule * capsule = NULL; + + + capsule = (struct v3_sym_capsule *)v3_htable_get_iter_value(capsule_iter); + + + PrintDebug("SYMMOD: Advertising Capsule %s\n", capsule->name); + + if (capsule->type != V3_SYMMOD_LNX) { + continue; + } + + + + if (q->cur_avail_idx == q->avail->index) { + PrintError("Notification Queue Too SMALL\n"); + return -1; + } + + hdr_desc = &(q->desc[desc_idx]); + + if (guest_pa_to_host_va(core, hdr_desc->addr_gpa, (addr_t *)&hdr) == -1) { + PrintError("Could not translate SYMMOD header address\n"); + return -1; + } + + memset(hdr, 0, sizeof(struct symmod_hdr)); + + + memcpy(hdr->name, capsule->name, strlen(capsule->name)); + hdr->num_bytes = capsule->size; + hdr->flags = capsule->flags; + hdr->action = V3_SYMMOD_ACT_ADVERTISE; + + q->used->ring[q->used->index % QUEUE_SIZE].id = q->avail->ring[q->cur_avail_idx % QUEUE_SIZE]; + q->used->ring[q->used->index % QUEUE_SIZE].length = sizeof(struct symmod_hdr) ; // set to total inbound xfer length + + q->used->index++; + q->cur_avail_idx++; + + } while (v3_htable_iter_advance(capsule_iter)); + + + if (!(q->avail->flags & VIRTIO_NO_IRQ_FLAG)) { + PrintDebug("Raising IRQ %d\n", sym_state->pci_dev->config_header.intr_line); + v3_pci_raise_irq(sym_state->pci_bus, 0, sym_state->pci_dev); + sym_state->virtio_cfg.pci_isr = 1; + } + + + return 0; +} + + static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * private_data) { struct virtio_sym_state * sym_state = (struct virtio_sym_state *)private_data; int port_idx = port % sym_state->io_range_size; @@ -272,12 +396,17 @@ static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, break; case VRING_Q_NOTIFY_PORT: { uint16_t queue_idx = *(uint16_t *)src; - + PrintDebug("SYMMOD: Handling Kick\n"); - + if (queue_idx == 0) { + if (handle_notification_kick(core, sym_state) == -1) { + PrintError("Could not handle Notification Kick\n"); + return -1; + } + sym_state->notifier_active = 1; - + } else if (queue_idx == 1) { if (handle_xfer_kick(core, sym_state) == -1) { PrintError("Could not handle Symbiotic Notification\n"); @@ -287,7 +416,7 @@ static int virtio_io_write(struct guest_info * core, uint16_t port, void * src, PrintError("Kick on invalid queue (%d)\n", queue_idx); return -1; } - + break; } case VIRTIO_STATUS_PORT: @@ -372,6 +501,8 @@ static int virtio_io_read(struct guest_info * core, uint16_t port, void * dst, u uint8_t * cfg_ptr = (uint8_t *)&(sym_state->sym_cfg); memcpy(dst, cfg_ptr + cfg_offset, length); + + V3_Print("Reading SymConfig at idx %d (val=%x)\n", cfg_offset, *(uint32_t *)cfg_ptr); } else { PrintError("Read of Unhandled Virtio Read\n"); @@ -387,18 +518,18 @@ 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, struct v3_sym_module * mod, void * priv_data) { +static int virtio_load_capsule(struct v3_vm_info * vm, struct v3_sym_capsule * 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(mod->name) >= 32) { - PrintError("Module name is too long... (%d bytes) limit is 32\n", (uint32_t)strlen(mod->name)); + PrintError("Capsule name is too long... (%d bytes) limit is 32\n", (uint32_t)strlen(mod->name)); return -1; } - PrintDebug("SYMMOD: VIRTIO SYMMOD Loader: Loading Module (size=%d)\n", mod_size); + PrintDebug("SYMMOD: VIRTIO SYMMOD Loader: Loading Capsule (size=%d)\n", mod->size); //queue is not set yet if (q->ring_avail_addr == 0) { @@ -427,11 +558,13 @@ static int virtio_load_module(struct v3_vm_info * vm, struct v3_sym_module * mod // clear the notifier memset(notifier, 0, sizeof(struct symmod_hdr)); - // set the module name + // set the capsule name memcpy(notifier->name, mod->name, strlen(mod->name)); - // set module length - notifier->num_bytes = mod_size; + // set capsule length + notifier->num_bytes = mod->size; + notifier->flags = mod->flags; + notifier->action = V3_SYMMOD_ACT_LOAD; q->used->ring[q->used->index % q->queue_size].id = q->avail->ring[q->cur_avail_idx % q->queue_size]; @@ -465,13 +598,14 @@ static struct v3_device_ops dev_ops = { static struct v3_symmod_loader_ops loader_ops = { - .load_module = virtio_load_module, + .load_capsule = virtio_load_capsule, }; static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct vm_device * pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); struct virtio_sym_state * virtio_state = NULL; + struct v3_symmod_state * symmod_state = &(vm->sym_vm_state.symmod_state); struct pci_device * pci_dev = NULL; char * name = v3_cfg_val(cfg, "name"); @@ -485,6 +619,12 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { virtio_state = (struct virtio_sym_state *)V3_Malloc(sizeof(struct virtio_sym_state)); memset(virtio_state, 0, sizeof(struct virtio_sym_state)); + virtio_state->vm = vm; + virtio_state->symmod_state = symmod_state; + + + + struct vm_device * dev = v3_allocate_device(name, &dev_ops, virtio_state); if (v3_attach_device(vm, dev) == -1) { @@ -557,6 +697,10 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { virtio_state->pci_dev = pci_dev; virtio_state->pci_bus = pci_bus; } + + + + V3_Print("SYMMOD: %d available sym modules\n", virtio_state->sym_cfg.avail_mods); virtio_reset(virtio_state); diff --git a/palacios/src/palacios/vmm_symmod.c b/palacios/src/palacios/vmm_symmod.c index 20559a9..3b45c23 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,36 +46,69 @@ 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("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_mod != __stop__v3_modules) { + while (tmp_def != __stop__v3_capsules) { + struct v3_sym_capsule * capsule = NULL; - if (v3_htable_search(master_mod_table, (addr_t)(tmp_mod->name))) { - PrintError("Multiple instances of Module (%s)\n", tmp_mod->name); + if (v3_htable_search(capsule_table, (addr_t)(tmp_def->name))) { + PrintError("Multiple instances of Module (%s)\n", tmp_def->name); return -1; } - PrintDebug("Registering Symbiotic Module (%s)\n", tmp_mod->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); + capsule = V3_Malloc(sizeof(struct v3_sym_capsule)); + 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; + + + + 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 { + return -1; + } + + PrintDebug("Registering Symbiotic Module (%s)\n", tmp_def->name); + + if (v3_htable_insert(capsule_table, + (addr_t)(tmp_def->name), + (addr_t)(capsule)) == 0) { + PrintError("Could not insert module %s to master list\n", tmp_def->name); return -1; } - tmp_mod = &(__start__v3_modules[++i]); + list_add(&(capsule->node), &capsule_list); + + tmp_def = &(__start__v3_capsules[++i]); } return 0; @@ -89,6 +125,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; @@ -143,7 +186,24 @@ 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("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("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); @@ -170,25 +230,29 @@ 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("Could not find capsule %s\n", name); return -1; } - PrintDebug("Loading Module (%s)\n", mod_name); + PrintDebug("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); diff --git a/symmods/capsule/Makefile b/symmods/capsule/Makefile index 1dea03f..a573104 100644 --- a/symmods/capsule/Makefile +++ b/symmods/capsule/Makefile @@ -1,9 +1,19 @@ ifeq ($(MOD_TYPE),V3_LINUX_MOD) - MOD_IDX := 1 + TYPE_IDX := 1 else ifeq ($(MOD_TYPE),V3_SYM_MOD) - MOD_IDX := 2 -else ifeq($(MOD_TYPE),V3_SEC_MOD) - MOD_IDX := 3 + TYPE_IDX := 2 +else ifeq ($(MOD_TYPE),V3_SEC_MOD) + TYPE_IDX := 3 +else + TYPE_IDX := 0 +endif + +ifeq ($(MOD_ARCH),i386) + ARCH_IDX := 1 +else ifeq ($(MOD_ARCH),x86_64) + ARCH_IDX := 2 +else + ARCH_IDX := 0 endif @@ -11,7 +21,8 @@ endif DEFS := -DMOD_NAME=$(MOD_NAME) \ -DMOD_DIR=$(MOD_DIR) \ -DMOD_OBJ=$(MOD_OBJ) \ - -DMOD_TYPE=$(MOD_IDX) + -DMOD_TYPE=$(TYPE_IDX) \ + -DMOD_ARCH=$(ARCH_IDX) # cpp -undef $(DEFS) binary.S -o $(MOD_DIR)/.tmp.binary.S diff --git a/symmods/capsule/binary.S b/symmods/capsule/binary.S index e37a312..d7190b5 100644 --- a/symmods/capsule/binary.S +++ b/symmods/capsule/binary.S @@ -28,9 +28,6 @@ #define MOD_NM(name) TOSTR(name) - - -.globl mod_start mod_start: .incbin MOD_PATH(MOD_DIR,MOD_OBJ) mod_stop: @@ -39,12 +36,14 @@ mod_name: .ascii MOD_NM(MOD_NAME) -.section _v3_modules, "a" +.section _v3_capsules, "a" IDENT(#ifdef __x86_64__) .quad mod_name .quad mod_start .quad mod_stop -.long MOD_TYPE +.byte MOD_TYPE +.byte MOD_ARCH +.space 2 IDENT(#else) .long mod_name .space 4 @@ -52,5 +51,7 @@ IDENT(#else) .space 4 .long mod_stop .space 4 -.long MOD_TYPE +.byte MOD_TYPE +.byte MOD_ARCH +.space 2 IDENT(#endif) diff --git a/symmods/linux/test/Makefile b/symmods/linux/test/Makefile index 0b4e233..f209420 100644 --- a/symmods/linux/test/Makefile +++ b/symmods/linux/test/Makefile @@ -2,31 +2,37 @@ # First the linux module is compiled via the target kernels build system # Second, the module is encapsulated for the Palacios VMM -V3_MOD_NAME := test +V3_MOD_NAME := lnx_test V3_MOD_OBJ := test.ko LINUX_MOD_OBJ := test.o # This is the target used by the Linux build process ifneq ($(KERNELRELEASE),) obj-m := $(LINUX_MOD_OBJ) -else +else + # These are configuration values to be set KERNELDIR := /home/jarusl/linux-2.6.30.y PWD := $(shell pwd) - PALACIOSDIR := $(PWD)/../../capsule + PALACIOSDIR := $(PWD)/../../.. + CAPSULEDIR := $(PALACIOSDIR)/symmods/capsule V3_MOD_TYPE := V3_LINUX_MOD - + V3_MOD_ARCH := i386 linux: FORCE $(MAKE) -C $(KERNELDIR) M=$(PWD) modules capsule: FORCE - $(MAKE) -C $(PALACIOSDIR) MOD_NAME=$(V3_MOD_NAME) MOD_DIR=$(PWD) \ - MOD_OBJ=$(V3_MOD_OBJ) MOD_TYPE=$(V3_MOD_TYPE) + $(MAKE) -C $(CAPSULEDIR) MOD_NAME=$(V3_MOD_NAME) MOD_DIR=$(PWD) \ + MOD_OBJ=$(V3_MOD_OBJ) MOD_TYPE=$(V3_MOD_TYPE) \ + MOD_ARCH=$(V3_MOD_ARCH) default: linux capsule +install: + cp $(V3_MOD_NAME).vo $(PALACIOSDIR)/modules/ + FORCE: endif diff --git a/symmods/v3_mod.h b/symmods/v3_mod.h new file mode 100644 index 0000000..7507cb8 --- /dev/null +++ b/symmods/v3_mod.h @@ -0,0 +1,43 @@ +/* + * This file is part of the Palacios Virtual Machine Monitor developed + * by the V3VEE Project with funding from the United States National + * Science Foundation and the Department of Energy. + * + * The V3VEE Project is a joint project between Northwestern University + * and the University of New Mexico. You can find out more at + * http://www.v3vee.org + * + * Copyright (c) 2008, Jack Lange + * Copyright (c) 2008, The V3VEE Project + * All rights reserved. + * + * Author: Jack Lange + * + * This is free software. You are permitted to use, + * redistribute, and modify it as specified in the file "V3VEE_LICENSE". + */ + + +struct v3_mod_info { + int (*init)(char * args); + int (*exit)(); +} __attribute__((packed)); + + +#define register_module(init_fn, exit_fn) \ + static struct v3_mod_info _v3_mod \ + __attribute__((used)) \ + __attribute__((unused, __section__(".v3_linkage"), \ + aligned(8))) \ + = {init_fn, exit_fn}; + + +/* + * Module interface API + */ + + +int v3_mod_test(void); +int v3_var_test; + +int v3_printk(const char * fmt, ...);