X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=palacios%2Fsrc%2Fpalacios%2Fvmm_dev_mgr.c;h=f0554ea78183e009d293db4cc330804994db5f14;hb=c0e8207d10b6b077c3fac4fb013ba7485f3a6391;hp=5fafbddb089fae6dcdeb323e3cbd80880b551ca4;hpb=e2964f7234daa3429275c039769a313f0870c212;p=palacios.git diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index 5fafbdd..f0554ea 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -44,7 +44,7 @@ static int dev_eq_fn(addr_t key1, addr_t key2) { } -int v3_init_devices() { +int V3_init_devices() { extern struct v3_device_info __start__v3_devices[]; extern struct v3_device_info __stop__v3_devices[]; struct v3_device_info * tmp_dev = __start__v3_devices; @@ -86,6 +86,12 @@ int v3_init_devices() { } +int V3_deinit_devices() { + v3_free_htable(master_dev_table, 0, 0); + return 0; +} + + int v3_init_dev_mgr(struct v3_vm_info * vm) { struct vmm_dev_mgr * mgr = &(vm->dev_mgr); @@ -108,19 +114,28 @@ int v3_init_dev_mgr(struct v3_vm_info * vm) { } -int v3_dev_mgr_deinit(struct v3_vm_info * vm) { - struct vm_device * dev; +int v3_free_vm_devices(struct v3_vm_info * vm) { struct vmm_dev_mgr * mgr = &(vm->dev_mgr); + struct vm_device * dev; struct vm_device * tmp; list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) { - v3_detach_device(dev); + v3_remove_device(dev); } - v3_free_htable(mgr->blk_table, 0, 0); - v3_free_htable(mgr->net_table, 0, 0); - v3_free_htable(mgr->char_table, 0, 0); - v3_free_htable(mgr->cons_table, 0, 0); + return 0; +} + +static int free_frontends(struct v3_vm_info * vm, struct vmm_dev_mgr * mgr); + +int v3_deinit_dev_mgr(struct v3_vm_info * vm) { + struct vmm_dev_mgr * mgr = &(vm->dev_mgr); + + // clear frontend lists + + free_frontends(vm, mgr); + + v3_free_htable(mgr->dev_table, 0, 0); @@ -149,10 +164,6 @@ int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_ } -void v3_free_device(struct vm_device * dev) { - V3_Free(dev); -} - struct vm_device * v3_find_dev(struct v3_vm_info * vm, const char * dev_name) { @@ -226,11 +237,19 @@ int v3_dev_unhook_io(struct vm_device * dev, uint16_t port) { -int v3_detach_device(struct vm_device * dev) { +int v3_remove_device(struct vm_device * dev) { struct vmm_dev_mgr * mgr = &(dev->vm->dev_mgr); + struct dev_io_hook * io_hook = NULL; + struct dev_io_hook * tmp; + + list_for_each_entry_safe(io_hook, tmp, &(dev->io_hooks), node) { + v3_unhook_io_port(dev->vm, io_hook->port); + list_del(&(io_hook->node)); + V3_Free(io_hook); + } if (dev->ops->free) { - dev->ops->free(dev); + dev->ops->free(dev->private_data); } else { PrintError("Error: %s free() not implemented\n", dev->name); } @@ -240,17 +259,23 @@ int v3_detach_device(struct vm_device * dev) { dev->vm = NULL; - v3_free_device(dev); + V3_Free(dev); return -1; } -struct vm_device * v3_allocate_device(char * name, - struct v3_device_ops * ops, - void * private_data) { +struct vm_device * v3_add_device(struct v3_vm_info * vm, + char * name, + struct v3_device_ops * ops, + void * private_data) { + struct vmm_dev_mgr * mgr = &(vm->dev_mgr); struct vm_device * dev = NULL; - dev = (struct vm_device*)V3_Malloc(sizeof(struct vm_device)); + dev = (struct vm_device *)V3_Malloc(sizeof(struct vm_device)); + + if (dev == NULL) { + return NULL; + } INIT_LIST_HEAD(&(dev->io_hooks)); @@ -258,28 +283,17 @@ struct vm_device * v3_allocate_device(char * name, dev->ops = ops; dev->private_data = private_data; - dev->vm = NULL; - - return dev; -} - - -int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev ) { - struct vmm_dev_mgr * mgr = &(vm->dev_mgr); - dev->vm = vm; list_add(&(dev->dev_link), &(mgr->dev_list)); mgr->num_devs++; - v3_htable_insert(mgr->dev_table, (addr_t)(dev->name), (addr_t)dev); - return 0; + return dev; } - void v3_print_dev_mgr(struct v3_vm_info * vm) { struct vmm_dev_mgr * mgr = &(vm->dev_mgr); struct vm_device * dev; @@ -548,3 +562,45 @@ int v3_dev_connect_char(struct v3_vm_info * vm, return 0; } + + +static int free_frontends(struct v3_vm_info * vm, struct vmm_dev_mgr * mgr) { + struct char_frontend * chr = NULL; + struct char_frontend * tmp_chr = NULL; + struct cons_frontend * cons = NULL; + struct cons_frontend * tmp_cons = NULL; + struct net_frontend * net = NULL; + struct net_frontend * tmp_net = NULL; + struct blk_frontend * blk = NULL; + struct blk_frontend * tmp_blk = NULL; + + + + list_for_each_entry_safe(chr, tmp_chr, &(mgr->char_list), char_node) { + list_del(&(chr->char_node)); + V3_Free(chr); + } + + list_for_each_entry_safe(cons, tmp_cons, &(mgr->cons_list), cons_node) { + list_del(&(cons->cons_node)); + V3_Free(cons); + } + + list_for_each_entry_safe(net, tmp_net, &(mgr->net_list), net_node) { + list_del(&(net->net_node)); + V3_Free(net); + } + + list_for_each_entry_safe(blk, tmp_blk, &(mgr->blk_list), blk_node) { + list_del(&(blk->blk_node)); + V3_Free(blk); + } + + v3_free_htable(mgr->blk_table, 0, 0); + v3_free_htable(mgr->net_table, 0, 0); + v3_free_htable(mgr->char_table, 0, 0); + v3_free_htable(mgr->cons_table, 0, 0); + + + return 0; +}