From: Jack Lange Date: Tue, 23 Nov 2010 16:31:26 +0000 (-0600) Subject: changed device registration interface X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=72420d58d18ec71d4777d029daaf0c6a1c820b32;p=palacios.git changed device registration interface --- diff --git a/palacios/include/palacios/vmm_dev_mgr.h b/palacios/include/palacios/vmm_dev_mgr.h index a952e9f..f18664b 100644 --- a/palacios/include/palacios/vmm_dev_mgr.h +++ b/palacios/include/palacios/vmm_dev_mgr.h @@ -75,10 +75,6 @@ struct vmm_dev_mgr { int v3_create_device(struct v3_vm_info * vm, const char * dev_name, v3_cfg_tree_t * cfg); - -void v3_free_device(struct vm_device * dev); - - struct vm_device * v3_find_dev(struct v3_vm_info * info, const char * dev_name); @@ -123,9 +119,14 @@ int v3_dev_unhook_io(struct vm_device * dev, ushort_t port); + +struct vm_device * v3_add_device(struct v3_vm_info * vm, char * name, + struct v3_device_ops * ops, void * private_data); +int v3_remove_device(struct vm_device * dev); + + int v3_attach_device(struct v3_vm_info * vm, struct vm_device * dev); int v3_detach_device(struct vm_device * dev); - struct vm_device * v3_allocate_device(char * name, struct v3_device_ops * ops, void * private_data); diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index 028357f..5a78e93 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -681,9 +681,9 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { V3_ASSERT(pit_state != NULL); pit_state->speaker = 0; - dev = v3_allocate_device(dev_id, &dev_ops, pit_state); + dev = v3_add_device(vm, dev_id, &dev_ops, pit_state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(pit_state); return -1; @@ -697,7 +697,7 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (ret != 0) { PrintError("8254 PIT: Failed to hook IO ports\n"); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } @@ -712,7 +712,7 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { pit_state->timer = v3_add_timer(info, &timer_ops, pit_state); if (pit_state->timer == NULL) { - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/8259a.c b/palacios/src/devices/8259a.c index 248fbb0..9bbef1e 100644 --- a/palacios/src/devices/8259a.c +++ b/palacios/src/devices/8259a.c @@ -743,19 +743,23 @@ static struct v3_device_ops dev_ops = { static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct pic_internal * state = NULL; - state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; // PIC is only usable in non-multicore environments // just hardcode the core context struct guest_info * core = &(vm->cores[0]); V3_ASSERT(state != NULL); + + state = (struct pic_internal *)V3_Malloc(sizeof(struct pic_internal)); + - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", dev_id); + if (dev == NULL) { + PrintError("Could not add device %s\n", dev_id); + V3_Free(state); return -1; } @@ -791,14 +795,20 @@ static int pic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state->slave_state = ICW1; - v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1); - v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2); - v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1); - v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2); + ret |= v3_dev_hook_io(dev, MASTER_PORT1, &read_master_port1, &write_master_port1); + ret |= v3_dev_hook_io(dev, MASTER_PORT2, &read_master_port2, &write_master_port2); + ret |= v3_dev_hook_io(dev, SLAVE_PORT1, &read_slave_port1, &write_slave_port1); + ret |= v3_dev_hook_io(dev, SLAVE_PORT2, &read_slave_port2, &write_slave_port2); - v3_dev_hook_io(dev, ELCR1_PORT, &read_elcr_port, &write_elcr_port); - v3_dev_hook_io(dev, ELCR2_PORT, &read_elcr_port, &write_elcr_port); + ret |= v3_dev_hook_io(dev, ELCR1_PORT, &read_elcr_port, &write_elcr_port); + ret |= v3_dev_hook_io(dev, ELCR2_PORT, &read_elcr_port, &write_elcr_port); + + if (ret != 0) { + PrintError("Error hooking io ports\n"); + v3_remove_device(dev); + return -1; + } return 0; } diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 91c6824..8e07132 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -1508,9 +1508,9 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { apic_dev->num_apics = vm->num_cores; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, apic_dev); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, apic_dev); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("apic: Could not attach device %s\n", dev_id); V3_Free(apic_dev); return -1; @@ -1531,7 +1531,7 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (apic->timer == NULL) { PrintError("APIC: Failed to attach timer to core %d\n", i); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index 6631023..c12c1f8 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -139,12 +139,15 @@ static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); - V3_ASSERT(state != NULL); + if (state == NULL) { + PrintError("Could not allocate bochs debug state\n"); + return -1; + } PrintDebug("Creating Bochs Debug Device\n"); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(state); return -1; @@ -166,7 +169,7 @@ static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (ret != 0) { PrintError("Could not hook Bochs Debug IO Ports\n"); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/cga.c b/palacios/src/devices/cga.c index 665c455..10722dd 100644 --- a/palacios/src/devices/cga.c +++ b/palacios/src/devices/cga.c @@ -331,15 +331,16 @@ static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct video_internal * video_state = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); char * passthrough_str = v3_cfg_val(cfg, "passthrough"); + int ret = 0; PrintDebug("video: init_device\n"); video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal)); memset(video_state, 0, sizeof(struct video_internal)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, video_state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(video_state); return -1; @@ -371,51 +372,56 @@ static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { } - v3_dev_hook_io(dev, 0x3b0, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b1, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b2, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b3, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b4, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b5, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b6, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b7, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b8, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3b9, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3ba, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3bb, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c0, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c1, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c2, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c3, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c4, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c5, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c6, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c7, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c8, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3c9, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3ca, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3cb, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3cc, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3cd, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3ce, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3cf, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d0, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d1, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d2, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d3, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d4, &video_read_port, &crtc_index_write); - v3_dev_hook_io(dev, 0x3d5, &video_read_port, &crtc_data_write); - v3_dev_hook_io(dev, 0x3d6, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d7, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d8, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3d9, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3da, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3db, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3dc, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3dd, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3de, &video_read_port, &video_write_port); - v3_dev_hook_io(dev, 0x3df, &video_read_port, &video_write_port); - + ret |= v3_dev_hook_io(dev, 0x3b0, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b1, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b2, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b3, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b4, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b5, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b6, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b7, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b8, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3b9, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3ba, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3bb, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c0, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c1, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c2, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c3, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c4, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c5, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c6, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c7, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c8, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3c9, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3ca, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3cb, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3cc, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3cd, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3ce, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3cf, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d0, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d1, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d2, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d3, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d4, &video_read_port, &crtc_index_write); + ret |= v3_dev_hook_io(dev, 0x3d5, &video_read_port, &crtc_data_write); + ret |= v3_dev_hook_io(dev, 0x3d6, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d7, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d8, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3d9, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3da, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3db, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3dc, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3dd, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3de, &video_read_port, &video_write_port); + ret |= v3_dev_hook_io(dev, 0x3df, &video_read_port, &video_write_port); + + if (ret != 0) { + PrintError("Error allocating cga io port\n"); + v3_remove_device(dev); + return -1; + } return 0; } diff --git a/palacios/src/devices/char_stream.c b/palacios/src/devices/char_stream.c index 52e217e..be72399 100644 --- a/palacios/src/devices/char_stream.c +++ b/palacios/src/devices/char_stream.c @@ -86,7 +86,7 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(state, 0, sizeof(struct stream_state)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); if (dev == NULL) { PrintError("Could not allocate device %s\n", dev_id); @@ -94,17 +94,13 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", dev_id); - V3_Free(state); - return -1; - } + state->stream = v3_stream_open(vm, stream_name); if (state->stream == NULL) { PrintError("Could not open stream %s\n", stream_name); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } @@ -115,7 +111,7 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state, &(state->push_fn_arg)) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/curses_cons.c b/palacios/src/devices/curses_cons.c index 9359ecc..c4aba1d 100644 --- a/palacios/src/devices/curses_cons.c +++ b/palacios/src/devices/curses_cons.c @@ -221,11 +221,9 @@ static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) } /* allocate device */ - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); - V3_ASSERT(dev); - - /* attach device to virtual machine */ - if (v3_attach_device(vm, dev) == -1) { + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); + + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(state); return -1; diff --git a/palacios/src/devices/disk_model.c b/palacios/src/devices/disk_model.c index 49ee033..c1d8836 100644 --- a/palacios/src/devices/disk_model.c +++ b/palacios/src/devices/disk_model.c @@ -106,15 +106,16 @@ static int model_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { char * dev_id = v3_cfg_val(cfg, "ID"); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, NULL); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, NULL); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); return -1; } if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, NULL) == -1) { PrintError("Could not register %s as block frontend\n", dev_id); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/filedisk.c b/palacios/src/devices/filedisk.c index c0122cd..001f1da 100644 --- a/palacios/src/devices/filedisk.c +++ b/palacios/src/devices/filedisk.c @@ -153,11 +153,20 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(disk, 0, sizeof(struct disk_state)); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk); + + if (dev == NULL) { + PrintError("Could not attach device %s\n", dev_id); + V3_Free(disk); + return -1; + } + + disk->fd = v3_file_open(vm, path, flags); if (disk->fd == NULL) { PrintError("Could not open file disk:%s\n", path); - V3_Free(disk); + v3_remove_device(dev); return -1; } @@ -166,21 +175,12 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("Registering FILEDISK %s (path=%s, fd=%lu, size=%lu)\n", dev_id, path, file->fd, file->capacity); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk); - - if (v3_attach_device(vm, dev) == -1) { - PrintError("Could not attach device %s\n", dev_id); - v3_file_close(disk->fd); - V3_Free(disk); - return -1; - } if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), &blk_ops, frontend_cfg, disk) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); - v3_file_close(disk->fd); - V3_Free(disk); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/generic.c b/palacios/src/devices/generic.c index d01ce95..f10048d 100644 --- a/palacios/src/devices/generic.c +++ b/palacios/src/devices/generic.c @@ -215,9 +215,9 @@ static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(state, 0, sizeof(struct generic_internal)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(state); return -1; @@ -238,13 +238,13 @@ static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { mode = GENERIC_PRINT_AND_PASSTHROUGH; } else { PrintError("Invalid Mode %s\n", mode_str); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } if (add_port_range(dev, start, end, mode) == -1) { PrintError("Could not add port range %d-%d\n", start, end); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/i440fx.c b/palacios/src/devices/i440fx.c index 22f5c62..24e0d29 100644 --- a/palacios/src/devices/i440fx.c +++ b/palacios/src/devices/i440fx.c @@ -70,6 +70,7 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct i440_state * state = NULL; struct vm_device * pci = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; if (!pci) { PrintError("could not find PCI Device\n"); @@ -80,17 +81,23 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state->pci = pci; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); V3_Free(state); return -1; } for (i = 0; i < 4; i++) { - v3_dev_hook_io(dev, 0x0cf8 + i, &io_read, &io_write); - v3_dev_hook_io(dev, 0x0cfc + i, &io_read, &io_write); + ret |= v3_dev_hook_io(dev, 0x0cf8 + i, &io_read, &io_write); + ret |= v3_dev_hook_io(dev, 0x0cfc + i, &io_read, &io_write); + } + + if (ret != 0) { + PrintError("Error hooking i440FX io ports\n"); + v3_remove_device(dev); + return -1; } for (i = 0; i < 6; i++) { @@ -102,7 +109,7 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { NULL, NULL, NULL, state); if (!pci_dev) { - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index b13617d..0af2198 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -1524,6 +1524,7 @@ static int connect_fn(struct v3_vm_info * vm, static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct ide_internal * ide = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; PrintDebug("IDE: Initializing IDE\n"); @@ -1537,7 +1538,6 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(ide, 0, sizeof(struct ide_internal)); ide->vm = vm; - ide->pci_bus = v3_find_dev(vm, v3_cfg_val(cfg, "bus")); if (ide->pci_bus != NULL) { @@ -1554,72 +1554,76 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("IDE: Creating IDE bus x 2\n"); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ide); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ide); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); - v3_free_device(dev); V3_Free(ide); return -1; } if (init_ide_state(ide) == -1) { PrintError("Failed to initialize IDE state\n"); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } PrintDebug("Connecting to IDE IO ports\n"); - v3_dev_hook_io(dev, PRI_DATA_PORT, - &ide_read_data_port, &write_data_port); - v3_dev_hook_io(dev, PRI_FEATURES_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_CMD_PORT, - &read_port_std, &write_cmd_port); - - v3_dev_hook_io(dev, SEC_DATA_PORT, - &ide_read_data_port, &write_data_port); - v3_dev_hook_io(dev, SEC_FEATURES_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, - &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CMD_PORT, - &read_port_std, &write_cmd_port); + ret |= v3_dev_hook_io(dev, PRI_DATA_PORT, + &ide_read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, PRI_FEATURES_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_SECT_NUM_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CYL_LOW_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CYL_HIGH_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CMD_PORT, + &read_port_std, &write_cmd_port); + + ret |= v3_dev_hook_io(dev, SEC_DATA_PORT, + &ide_read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, SEC_FEATURES_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_SECT_NUM_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CYL_LOW_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CYL_HIGH_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, + &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CMD_PORT, + &read_port_std, &write_cmd_port); - v3_dev_hook_io(dev, PRI_CTRL_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_CTRL_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_CTRL_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_CTRL_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, + &read_port_std, &write_port_std); - v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, - &read_port_std, &write_port_std); + ret |= v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, + &read_port_std, &write_port_std); + if (ret != 0) { + PrintError("Error hooking IDE IO port\n"); + v3_remove_device(dev); + return -1; + } if (ide->pci_bus) { @@ -1650,6 +1654,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (pci_dev == NULL) { PrintError("Failed to register IDE BUS %d with PCI\n", i); + v3_remove_device(dev); return -1; } @@ -1677,7 +1682,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)ide) == -1) { PrintError("Could not register %s as frontend\n", dev_id); - v3_detach_device(dev); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/io_apic.c b/palacios/src/devices/io_apic.c index 757e96e..31169f4 100644 --- a/palacios/src/devices/io_apic.c +++ b/palacios/src/devices/io_apic.c @@ -332,15 +332,14 @@ static int ioapic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { ioapic->apic_dev_data = apic_dev; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, ioapic); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, ioapic); - - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("ioapic: Could not attach device %s\n", dev_id); + V3_Free(ioapic); return -1; } - v3_register_intr_router(vm, &router_ops, ioapic); init_ioapic_state(ioapic, vm->num_cores); diff --git a/palacios/src/devices/keyboard.c b/palacios/src/devices/keyboard.c index 0483350..71bed11 100644 --- a/palacios/src/devices/keyboard.c +++ b/palacios/src/devices/keyboard.c @@ -1020,6 +1020,7 @@ static struct v3_device_ops dev_ops = { static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct keyboard_internal * kbd = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; PrintDebug("keyboard: init_device\n"); @@ -1029,10 +1030,11 @@ static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { kbd->vm = vm; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, kbd); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, kbd); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(kbd); return -1; } @@ -1043,8 +1045,14 @@ static int keyboard_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { // hook ports - v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); - v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); + ret |= v3_dev_hook_io(dev, KEYBOARD_64H, &keyboard_read_status, &keyboard_write_command); + ret |= v3_dev_hook_io(dev, KEYBOARD_60H, &keyboard_read_input, &keyboard_write_output); + + if (ret != 0) { + PrintError("Error hooking keyboard IO ports\n"); + v3_remove_device(dev); + return -1; + } v3_hook_host_event(vm, HOST_KEYBOARD_EVT, V3_HOST_EVENT_HANDLER(key_event_handler), kbd); v3_hook_host_event(vm, HOST_MOUSE_EVT, V3_HOST_EVENT_HANDLER(mouse_event_handler), kbd); diff --git a/palacios/src/devices/lnx_virtio_balloon.c b/palacios/src/devices/lnx_virtio_balloon.c index a620308..0bd5727 100644 --- a/palacios/src/devices/lnx_virtio_balloon.c +++ b/palacios/src/devices/lnx_virtio_balloon.c @@ -419,19 +419,18 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { } - virtio_state = (struct virtio_balloon_state *)V3_Malloc(sizeof(struct virtio_balloon_state)); + virtio_state = (struct virtio_balloon_state *)V3_Malloc(sizeof(struct virtio_balloon_state)); memset(virtio_state, 0, sizeof(struct virtio_balloon_state)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state); - if (v3_attach_device(vm, dev) == -1) { + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state); + + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(virtio_state); return -1; } - - - // PCI initialization { struct v3_pci_bar bars[6]; @@ -476,6 +475,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (!pci_dev) { PrintError("Could not register PCI Device\n"); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/lnx_virtio_blk.c b/palacios/src/devices/lnx_virtio_blk.c index 6cb8fa3..bb29d9a 100644 --- a/palacios/src/devices/lnx_virtio_blk.c +++ b/palacios/src/devices/lnx_virtio_blk.c @@ -612,14 +612,17 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { virtio_state->pci_bus = pci_bus; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state); - if (v3_attach_device(vm, dev) == -1) { + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state); + + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(virtio_state); return -1; } if (v3_dev_add_blk_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) { PrintError("Could not register %s as block frontend\n", dev_id); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/lnx_virtio_nic.c b/palacios/src/devices/lnx_virtio_nic.c index 6da1893..7609b0a 100644 --- a/palacios/src/devices/lnx_virtio_nic.c +++ b/palacios/src/devices/lnx_virtio_nic.c @@ -805,14 +805,17 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { virtio_state->pci_bus = pci_bus; virtio_state->vm = vm; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state); - if (v3_attach_device(vm, dev) == -1) { + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state); + + if (dev == NULL) { PrintError("Virtio NIC: Could not attach device %s\n", dev_id); + V3_Free(virtio_state); return -1; } if (v3_dev_add_net_frontend(vm, dev_id, connect_fn, (void *)virtio_state) == -1) { PrintError("Virtio NIC: Could not register %s as net frontend\n", dev_id); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/lnx_virtio_symmod.c b/palacios/src/devices/lnx_virtio_symmod.c index 09ec44c..d3d5d7e 100644 --- a/palacios/src/devices/lnx_virtio_symmod.c +++ b/palacios/src/devices/lnx_virtio_symmod.c @@ -629,10 +629,11 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, virtio_state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, virtio_state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(virtio_state); return -1; } @@ -679,6 +680,7 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (!pci_dev) { PrintError("Could not register PCI Device\n"); + v3_remove_device(dev); return -1; } @@ -703,7 +705,6 @@ static int virtio_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { } - V3_Print("SYMMOD: %d available sym modules\n", virtio_state->sym_cfg.avail_mods); virtio_reset(virtio_state); diff --git a/palacios/src/devices/lnx_virtio_vnet.c b/palacios/src/devices/lnx_virtio_vnet.c index 984f9b0..7746bcc 100644 --- a/palacios/src/devices/lnx_virtio_vnet.c +++ b/palacios/src/devices/lnx_virtio_vnet.c @@ -588,10 +588,11 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { vnet_state->vm = vm; - struct vm_device * dev = v3_allocate_device(name, &dev_ops, vnet_state); + struct vm_device * dev = v3_add_device(vm, name, &dev_ops, vnet_state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", name); + V3_Free(vnet_state); return -1; } @@ -635,6 +636,7 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (!pci_dev) { PrintError("Could not register PCI Device\n"); + v3_remove_device(dev); return -1; } @@ -659,6 +661,7 @@ static int dev_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { brg_ops.poll = vnet_virtio_poll; V3_Print("Registering Virtio device as vnet bridge\n"); + v3_vnet_add_bridge(vm, &brg_ops, CTL_VM_BRIDGE, (void *)vnet_state); return 0; diff --git a/palacios/src/devices/netdisk.c b/palacios/src/devices/netdisk.c index b2e76b1..60f71ff 100644 --- a/palacios/src/devices/netdisk.c +++ b/palacios/src/devices/netdisk.c @@ -286,15 +286,17 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { disk->port = atoi(port_str); disk->vm = vm; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(disk); return -1; } if (socket_init(disk) == -1) { PrintError("could not initialize network connection\n"); + v3_remove_device(dev); return -1; } @@ -303,6 +305,7 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), &blk_ops, frontend_cfg, disk) == -1) { PrintError("Could not connect %s to frontend\n", dev_id); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/nic_bridge.c b/palacios/src/devices/nic_bridge.c index 00ce9b6..dffe6d2 100644 --- a/palacios/src/devices/nic_bridge.c +++ b/palacios/src/devices/nic_bridge.c @@ -87,10 +87,11 @@ static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { bridge = (struct nic_bridge_state *)V3_Malloc(sizeof(struct nic_bridge_state)); memset(bridge, 0, sizeof(struct nic_bridge_state)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, bridge); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, bridge); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(bridge); return -1; } @@ -101,6 +102,7 @@ static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { &(bridge->net_ops), frontend_cfg, bridge) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/nvram.c b/palacios/src/devices/nvram.c index e08d5d3..38e9794 100644 --- a/palacios/src/devices/nvram.c +++ b/palacios/src/devices/nvram.c @@ -763,6 +763,7 @@ static int nvram_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct nvram_internal * nvram_state = NULL; struct vm_device * ide = v3_find_dev(vm, v3_cfg_val(cfg, "storage")); char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; if (!ide) { PrintError("Could not find IDE device\n"); @@ -777,20 +778,26 @@ static int nvram_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { nvram_state->ide = ide; nvram_state->vm = vm; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, nvram_state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, nvram_state); - - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(nvram_state); return -1; } init_nvram_state(vm, nvram_state); // hook ports - v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); - v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); + ret |= v3_dev_hook_io(dev, NVRAM_REG_PORT, NULL, &nvram_write_reg_port); + ret |= v3_dev_hook_io(dev, NVRAM_DATA_PORT, &nvram_read_data_port, &nvram_write_data_port); + if (ret != 0) { + PrintError("Error hooking NVRAM IO ports\n"); + v3_remove_device(dev); + return -1; + } + v3_hook_host_event(vm, HOST_TIMER_EVT, V3_HOST_EVENT_HANDLER(handle_timer_event), nvram_state); return 0; diff --git a/palacios/src/devices/os_debug.c b/palacios/src/devices/os_debug.c index e3fb734..b97da12 100644 --- a/palacios/src/devices/os_debug.c +++ b/palacios/src/devices/os_debug.c @@ -104,15 +104,20 @@ static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("Creating OS Debug Device\n"); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); + return -1; + } + + if (v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write) == -1) { + PrintError("Error hooking OS debug IO port\n"); + v3_remove_device(dev); return -1; } - v3_dev_hook_io(dev, DEBUG_PORT1, NULL, &handle_gen_write); v3_register_hypercall(vm, OS_DEBUG_HCALL, handle_hcall, state); state->debug_offset = 0; diff --git a/palacios/src/devices/pci.c b/palacios/src/devices/pci.c index b1f6b54..5a12909 100644 --- a/palacios/src/devices/pci.c +++ b/palacios/src/devices/pci.c @@ -629,13 +629,15 @@ static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct pci_internal * pci_state = V3_Malloc(sizeof(struct pci_internal)); int i = 0; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; PrintDebug("PCI internal at %p\n",(void *)pci_state); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, pci_state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, pci_state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(pci_state); return -1; } @@ -648,8 +650,14 @@ static int pci_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("Sizeof config header=%d\n", (int)sizeof(struct pci_config_header)); for (i = 0; i < 4; i++) { - v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write); - v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write); + ret |= v3_dev_hook_io(dev, CONFIG_ADDR_PORT + i, &addr_port_read, &addr_port_write); + ret |= v3_dev_hook_io(dev, CONFIG_DATA_PORT + i, &data_port_read, &data_port_write); + } + + if (ret != 0) { + PrintError("Error hooking PCI IO ports\n"); + v3_remove_device(dev); + return -1; } return 0; @@ -764,14 +772,14 @@ int v3_pci_raise_irq(struct vm_device * pci_bus, int bus_num, struct pci_device struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data; struct pci_bus * bus = &(pci_state->bus_list[bus_num]); - return bus->raise_pci_irq(bus->irq_dev_data, dev); + return bus->raise_pci_irq(dev, bus->irq_dev_data); } int v3_pci_lower_irq(struct vm_device * pci_bus, int bus_num, struct pci_device * dev) { struct pci_internal * pci_state = (struct pci_internal *)pci_bus->private_data; struct pci_bus * bus = &(pci_state->bus_list[bus_num]); - return bus->lower_pci_irq(bus->irq_dev_data, dev); + return bus->lower_pci_irq(dev, bus->irq_dev_data); } // if dev_num == -1, auto assign diff --git a/palacios/src/devices/pci_passthrough.c b/palacios/src/devices/pci_passthrough.c index 2ace074..b8f921b 100644 --- a/palacios/src/devices/pci_passthrough.c +++ b/palacios/src/devices/pci_passthrough.c @@ -790,10 +790,11 @@ static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { strncpy(state->name, dev_id, 32); - dev = v3_allocate_device(dev_id, &dev_ops, state); + dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); return -1; } @@ -804,6 +805,7 @@ static int passthrough_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintError("Could not find PCI Device %s:%s\n", v3_cfg_val(cfg, "vendor_id"), v3_cfg_val(cfg, "device_id")); + v3_remove_device(dev); return 0; } diff --git a/palacios/src/devices/piix3.c b/palacios/src/devices/piix3.c index 487a821..59c70fc 100644 --- a/palacios/src/devices/piix3.c +++ b/palacios/src/devices/piix3.c @@ -454,16 +454,22 @@ static int piix3_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { piix3->pci_bus = pci; piix3->type = V3_SB_PIIX3; - dev = v3_allocate_device(dev_id, &dev_ops, piix3); + dev = v3_add_device(vm, dev_id, &dev_ops, piix3); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(piix3); return -1; } PrintDebug("Created PIIX3\n"); - return setup_pci(piix3); + if (setup_pci(piix3) == -1) { + v3_remove_device(dev); + return -1; + } + + return 0; } diff --git a/palacios/src/devices/ramdisk.c b/palacios/src/devices/ramdisk.c index e33c873..5695bc4 100644 --- a/palacios/src/devices/ramdisk.c +++ b/palacios/src/devices/ramdisk.c @@ -91,10 +91,6 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); - disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state)); - memset(disk, 0, sizeof(struct disk_state)); - - if (!filename) { PrintError("Missing filename (%s) for %s\n", filename, dev_id); return -1; @@ -107,22 +103,30 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } + + disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state)); + memset(disk, 0, sizeof(struct disk_state)); + disk->disk_image = file->data; disk->capacity = file->size; PrintDebug("Registering RAMDISK at %p (size=%d)\n", (void *)file->data, (uint32_t)file->size); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, disk); - if (v3_attach_device(vm, dev) == -1) { + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, disk); + + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(disk); return -1; } + if (v3_dev_connect_blk(vm, v3_cfg_val(frontend_cfg, "tag"), &blk_ops, frontend_cfg, disk) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/serial.c b/palacios/src/devices/serial.c index 1ca3f13..e6adf3c 100644 --- a/palacios/src/devices/serial.c +++ b/palacios/src/devices/serial.c @@ -926,6 +926,7 @@ static int connect_fn(struct v3_vm_info * vm, static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct serial_state * state = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; state = (struct serial_state *)V3_Malloc(sizeof(struct serial_state)); @@ -936,8 +937,6 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(state, 0, sizeof(struct serial_state)); - - init_serial_port(&(state->coms[0])); init_serial_port(&(state->coms[1])); init_serial_port(&(state->coms[2])); @@ -949,50 +948,57 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { state->coms[3].irq_number = COM4_IRQ; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); return -1; } PrintDebug("Serial device attached\n"); - v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); - - v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); - v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); - v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); - v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM1_DATA_PORT, &read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, COM1_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM1_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM1_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM1_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM1_LINE_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM1_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM1_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + ret |= v3_dev_hook_io(dev, COM2_DATA_PORT, &read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, COM2_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM2_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM2_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM2_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM2_LINE_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM2_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM2_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + ret |= v3_dev_hook_io(dev, COM3_DATA_PORT, &read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, COM3_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM3_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM3_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM3_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM3_LINE_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM3_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM3_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + ret |= v3_dev_hook_io(dev, COM4_DATA_PORT, &read_data_port, &write_data_port); + ret |= v3_dev_hook_io(dev, COM4_IRQ_ENABLE_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM4_FIFO_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM4_LINE_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM4_MODEM_CTRL_PORT, &read_ctrl_port, &write_ctrl_port); + ret |= v3_dev_hook_io(dev, COM4_LINE_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM4_MODEM_STATUS_PORT, &read_status_port, &write_status_port); + ret |= v3_dev_hook_io(dev, COM4_SCRATCH_PORT, &read_ctrl_port, &write_ctrl_port); + + if (ret != 0) { + PrintError("Error hooking Serial IO ports\n"); + v3_remove_device(dev); + return -1; + } PrintDebug("Serial ports hooked\n"); @@ -1000,6 +1006,7 @@ static int serial_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_dev_add_char_frontend(vm, dev_id, connect_fn, (void *)state) == -1) { PrintError("Could not register %s as frontend\n", dev_id); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/telnet_cons.c b/palacios/src/devices/telnet_cons.c index 8c052b9..fc03c88 100644 --- a/palacios/src/devices/telnet_cons.c +++ b/palacios/src/devices/telnet_cons.c @@ -531,10 +531,11 @@ static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { v3_lock_init(&(state->cons_lock)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, state); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); return -1; } diff --git a/palacios/src/devices/tmpdisk.c b/palacios/src/devices/tmpdisk.c index 450de53..96bffef 100644 --- a/palacios/src/devices/tmpdisk.c +++ b/palacios/src/devices/tmpdisk.c @@ -117,10 +117,11 @@ static int blk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(blk->blk_space, 0, capacity); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, blk); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, blk); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(blk); return -1; } @@ -128,6 +129,7 @@ static int blk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { &blk_ops, frontend_cfg, blk) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); + v3_remove_device(dev); return -1; } diff --git a/palacios/src/devices/vnet_nic.c b/palacios/src/devices/vnet_nic.c index fb91984..74ca080 100644 --- a/palacios/src/devices/vnet_nic.c +++ b/palacios/src/devices/vnet_nic.c @@ -176,10 +176,11 @@ static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { vnetnic = (struct vnet_nic_state *)V3_Malloc(sizeof(struct vnet_nic_state)); memset(vnetnic, 0, sizeof(struct vnet_nic_state)); - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, vnetnic); + struct vm_device * dev = v3_add_device(vm, dev_id, &dev_ops, vnetnic); - if (v3_attach_device(vm, dev) == -1) { + if (dev == NULL) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(vnetnic); return -1; } @@ -193,6 +194,7 @@ static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { &(vnetnic->net_ops), frontend_cfg, vnetnic) == -1) { PrintError("Could not connect %s to frontend %s\n", dev_id, v3_cfg_val(frontend_cfg, "tag")); + v3_remove_device(vnetnic); return -1; } @@ -201,7 +203,10 @@ static int vnet_nic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if ((vnet_dev_id = register_to_vnet(vm, vnetnic, dev_id, vnetnic->mac)) == -1) { PrintError("Vnet-nic device %s (mac: %s) fails to registered to VNET\n", dev_id, macstr); + v3_remove_device(vnetnic); + return 0; } + vnetnic->vnet_dev_id = vnet_dev_id; PrintDebug("Vnet-nic device %s (mac: %s, %ld) registered to VNET\n", diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index 5fafbdd..70d0d5e 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -114,7 +114,7 @@ int v3_dev_mgr_deinit(struct v3_vm_info * vm) { 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); @@ -149,10 +149,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,8 +222,16 @@ 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); @@ -240,17 +244,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 +268,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;