From: Jack Lange Date: Fri, 19 Nov 2010 03:31:12 +0000 (-0600) Subject: added some more device unregister functions X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=1df601c90b519a54b64ca101fd6aa4c0a39bf0f0;p=palacios.git added some more device unregister functions --- diff --git a/palacios/src/devices/8254.c b/palacios/src/devices/8254.c index 31375d3..3ac10e1 100644 --- a/palacios/src/devices/8254.c +++ b/palacios/src/devices/8254.c @@ -680,7 +680,8 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct pit * pit_state = NULL; struct vm_device * dev = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); - + int ret = 0; + // PIT is only usable in non-multicore environments // just hardcode the core context struct guest_info * info = &(vm->cores[0]); @@ -696,14 +697,21 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_attach_device(vm, dev) == -1) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(pit_state); return -1; } - v3_hook_io_port(vm, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel, dev); - v3_hook_io_port(vm, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel, dev); - v3_hook_io_port(vm, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel, dev); - v3_hook_io_port(vm, COMMAND_PORT, NULL, &pit_write_command, dev); - v3_hook_io_port(vm, SPEAKER_PORT, &pit_read_channel, &pit_write_channel, dev); + ret |= v3_hook_io_port(vm, CHANNEL0_PORT, &pit_read_channel, &pit_write_channel, dev); + ret |= v3_hook_io_port(vm, CHANNEL1_PORT, &pit_read_channel, &pit_write_channel, dev); + ret |= v3_hook_io_port(vm, CHANNEL2_PORT, &pit_read_channel, &pit_write_channel, dev); + ret |= v3_hook_io_port(vm, COMMAND_PORT, NULL, &pit_write_command, dev); + ret |= v3_hook_io_port(vm, SPEAKER_PORT, &pit_read_channel, &pit_write_channel, dev); + + if (ret != 0) { + PrintError("8254 PIT: Failed to hook IO ports\n"); + v3_detach_device(dev); + return -1; + } #ifdef CONFIG_DEBUG_PIT PrintDebug("8254 PIT: OSC_HZ=%d, reload_val=", OSC_HZ); @@ -727,7 +735,6 @@ static int pit_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { pit_state->pit_reload = reload_val; - init_channel(&(pit_state->ch_0)); init_channel(&(pit_state->ch_1)); init_channel(&(pit_state->ch_2)); diff --git a/palacios/src/devices/apic.c b/palacios/src/devices/apic.c index 6eaa35f..1827366 100644 --- a/palacios/src/devices/apic.c +++ b/palacios/src/devices/apic.c @@ -207,6 +207,8 @@ struct apic_state { struct guest_info * core; + struct v3_timer * timer; + uint32_t eoi; v3_lock_t lock; @@ -1463,13 +1465,27 @@ static struct v3_timer_ops timer_ops = { static int apic_free(struct vm_device * dev) { + struct apic_dev_state * apic_dev = (struct apic_dev_state *)dev->private_data; + int i = 0; + + for (i = 0; i < dev->vm->num_cores; i++) { + struct apic_state * apic = &(apic_dev->apics[i]); + struct guest_info * core = &(dev->vm->cores[i]); + + + // unregister intr controller - /* TODO: This should crosscall to force an unhook on each CPU */ + if (apic->timer) { + v3_remove_timer(core, apic->timer); + } + + // unhook memory - // struct apic_state * apic = (struct apic_state *)dev->private_data; + } v3_unhook_msr(dev->vm, BASE_ADDR_MSR); + V3_Free(apic_dev); return 0; } @@ -1501,6 +1517,7 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_attach_device(vm, dev) == -1) { PrintError("apic: Could not attach device %s\n", dev_id); + V3_Free(apic_dev); return -1; } @@ -1515,7 +1532,13 @@ static int apic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { v3_register_intr_controller(core, &intr_ops, apic_dev); - v3_add_timer(core, &timer_ops, apic_dev); + apic->timer = v3_add_timer(core, &timer_ops, apic_dev); + + if (apic->timer == NULL) { + PrintError("APIC: Failed to attach timer to core %d\n", i); + v3_detach_device(dev); + return -1; + } v3_hook_full_mem(vm, core->cpu_id, apic->base_addr, apic->base_addr + PAGE_SIZE_4KB, apic_read, apic_write, apic_dev); diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index c4999f7..adba835 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -21,6 +21,7 @@ #include #include +#include #define BUF_SIZE 1024 @@ -43,7 +44,8 @@ struct debug_state { uint_t cons_offset; }; -static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) { +static int handle_info_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = priv_data; struct debug_state * state = (struct debug_state *)dev->private_data; state->info_buf[state->info_offset++] = *(char*)src; @@ -58,7 +60,8 @@ static int handle_info_write(struct guest_info * core, ushort_t port, void * src } -static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) { +static int handle_debug_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = priv_data; struct debug_state * state = (struct debug_state *)dev->private_data; state->debug_buf[state->debug_offset++] = *(char*)src; @@ -73,7 +76,8 @@ static int handle_debug_write(struct guest_info * core, ushort_t port, void * sr } -static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) { +static int handle_console_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = priv_data; struct debug_state * state = (struct debug_state *)dev->private_data; state->cons_buf[state->cons_offset++] = *(char *)src; @@ -88,8 +92,9 @@ static int handle_console_write(struct guest_info * core, ushort_t port, void * } -static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) { - +static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) { + //struct vm_device * dev = priv_data; + switch (length) { case 1: PrintDebug(">0x%.2x\n", *(uchar_t*)src); @@ -113,10 +118,14 @@ static int handle_gen_write(struct guest_info * core, ushort_t port, void * src, static int debug_free(struct vm_device * dev) { - v3_dev_unhook_io(dev, BOCHS_PORT1); - v3_dev_unhook_io(dev, BOCHS_PORT2); - v3_dev_unhook_io(dev, BOCHS_INFO_PORT); - v3_dev_unhook_io(dev, BOCHS_DEBUG_PORT); + struct debug_state * state = dev->private_data; + + v3_unhook_io_port(dev->vm, BOCHS_PORT1); + v3_unhook_io_port(dev->vm, BOCHS_PORT2); + v3_unhook_io_port(dev->vm, BOCHS_INFO_PORT); + v3_unhook_io_port(dev->vm, BOCHS_DEBUG_PORT); + + V3_Free(state); return 0; }; @@ -137,6 +146,7 @@ static struct v3_device_ops dev_ops = { static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct debug_state * state = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); + int ret = 0; state = (struct debug_state *)V3_Malloc(sizeof(struct debug_state)); @@ -147,6 +157,7 @@ static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (v3_attach_device(vm, dev) == -1) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); return -1; } @@ -158,12 +169,17 @@ static int debug_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { memset(state->cons_buf, 0, BUF_SIZE); - v3_dev_hook_io(dev, BOCHS_PORT1, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_PORT2, NULL, &handle_gen_write); - v3_dev_hook_io(dev, BOCHS_INFO_PORT, NULL, &handle_info_write); - v3_dev_hook_io(dev, BOCHS_DEBUG_PORT, NULL, &handle_debug_write); - v3_dev_hook_io(dev, BOCHS_CONSOLE_PORT, NULL, &handle_console_write); + ret |= v3_hook_io_port(vm, BOCHS_PORT1, NULL, &handle_gen_write, dev); + ret |= v3_hook_io_port(vm, BOCHS_PORT2, NULL, &handle_gen_write, dev); + ret |= v3_hook_io_port(vm, BOCHS_INFO_PORT, NULL, &handle_info_write, dev); + ret |= v3_hook_io_port(vm, BOCHS_DEBUG_PORT, NULL, &handle_debug_write, dev); + ret |= v3_hook_io_port(vm, BOCHS_CONSOLE_PORT, NULL, &handle_console_write, dev); + if (ret != 0) { + PrintError("Could not hook Bochs Debug IO Ports\n"); + v3_detach_device(dev); + return -1; + } return 0; } diff --git a/palacios/src/devices/cga.c b/palacios/src/devices/cga.c index ec75d53..5adf005 100644 --- a/palacios/src/devices/cga.c +++ b/palacios/src/devices/cga.c @@ -302,7 +302,12 @@ int v3_cons_get_fb(struct vm_device * frontend_dev, uint8_t * dst, uint_t offset static int free_device(struct vm_device * dev) { + struct video_internal * video_state = (struct video_internal *)dev->private_data; + v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR); + + V3_Free(video_state); + return 0; } @@ -310,13 +315,10 @@ static int free_device(struct vm_device * dev) { static struct v3_device_ops dev_ops = { .free = free_device, - .reset = NULL, - .start = NULL, - .stop = NULL, }; static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { - struct video_internal * video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal)); + struct video_internal * video_state = NULL; addr_t frame_buf_pa = 0; int enable_passthrough = 0; char * dev_id = v3_cfg_val(cfg, "ID"); @@ -325,10 +327,13 @@ static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { PrintDebug("video: init_device\n"); + video_state = (struct video_internal *)V3_Malloc(sizeof(struct video_internal)); + struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, video_state); if (v3_attach_device(vm, dev) == -1) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(video_state); return -1; }