static int pci_free(struct pci_internal * pci_state) {
+ int i;
+
+
+ // cleanup devices
+ for (i = 0; i < PCI_BUS_COUNT; i++) {
+ struct pci_bus * bus = &(pci_state->bus_list[i]);
+ struct rb_node * node = v3_rb_first(&(bus->devices));
+ struct pci_device * dev = NULL;
- // cleanup devices (?)
+ while (node) {
+ dev = rb_entry(node, struct pci_device, dev_tree_node);
+ node = v3_rb_next(node);
+
+ v3_rb_erase(&(dev->dev_tree_node), &(bus->devices));
+ V3_Free(dev);
+ }
+
+ }
V3_Free(pci_state);
return 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->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);
v3_free_htable(mgr->dev_table, 0, 0);
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;
+}
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) {