From: Jack Lange Date: Fri, 19 Nov 2010 17:36:48 +0000 (-0600) Subject: more device free updates X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=ec660ce1c5410ef08a7820f7ee064a30b416a523;p=palacios-OLD.git more device free updates --- diff --git a/palacios/include/palacios/vmm_console.h b/palacios/include/palacios/vmm_console.h index 1315ccd..cab3c4f 100644 --- a/palacios/include/palacios/vmm_console.h +++ b/palacios/include/palacios/vmm_console.h @@ -31,6 +31,7 @@ typedef void * v3_console_t; v3_console_t v3_console_open(struct v3_vm_info * vm, uint32_t width, uint32_t height); +void v3_console_close(v3_console_t cons); int v3_console_set_cursor(v3_console_t cons, int x, int y); int v3_console_set_char(v3_console_t cons, int x, int y, char c, uint8_t style); @@ -44,6 +45,8 @@ int v3_console_update(v3_console_t cons); struct v3_console_hooks { /* open console device, mode is a combination of TTY_OPEN_MODE_* flags */ void *(*open)(void * priv_data, unsigned int width, unsigned int height); + + void (*close)(void * tty); /* set cursor position */ int (*set_cursor)(void * tty, int x, int y); diff --git a/palacios/src/devices/bochs_debug.c b/palacios/src/devices/bochs_debug.c index adba835..42128b6 100644 --- a/palacios/src/devices/bochs_debug.c +++ b/palacios/src/devices/bochs_debug.c @@ -135,9 +135,7 @@ static int debug_free(struct vm_device * dev) { static struct v3_device_ops dev_ops = { .free = debug_free, - .reset = NULL, - .start = NULL, - .stop = NULL, + }; diff --git a/palacios/src/devices/cga.c b/palacios/src/devices/cga.c index 5adf005..119709f 100644 --- a/palacios/src/devices/cga.c +++ b/palacios/src/devices/cga.c @@ -23,6 +23,7 @@ #include #include #include +#include #include @@ -51,6 +52,7 @@ struct video_internal { uint8_t * framebuf; + addr_t framebuf_pa; // These store the values for unhandled ports, in case of a read op uint8_t port_store[44]; @@ -148,7 +150,8 @@ static int video_write_mem(struct guest_info * core, addr_t guest_addr, void * d return length; } -static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, struct vm_device * dev) { +static int video_read_port(struct guest_info * core, uint16_t port, void * dest, uint_t length, void * priv_data) { + struct vm_device * dev = (struct vm_device *)priv_data; struct video_internal * video_state = (struct video_internal *)dev->private_data; @@ -163,7 +166,8 @@ static int video_read_port(struct guest_info * core, uint16_t port, void * dest, -static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) { +static int video_write_port(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = (struct vm_device *)priv_data; struct video_internal * video_state = (struct video_internal *)dev->private_data; @@ -178,7 +182,8 @@ static int video_write_port(struct guest_info * core, uint16_t port, void * src, -static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) { +static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = (struct vm_device *)priv_data; struct video_internal * video_state = (struct video_internal *)dev->private_data; uint8_t val = *(uint8_t *)src; uint_t index = video_state->crtc_index_reg; @@ -257,7 +262,8 @@ static int crtc_data_write(struct guest_info * core, uint16_t port, void * src, } -static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, struct vm_device * dev) { +static int crtc_index_write(struct guest_info * core, uint16_t port, void * src, uint_t length, void * priv_data) { + struct vm_device * dev = (struct vm_device *)priv_data; struct video_internal * video_state = (struct video_internal *)dev->private_data; if (length > 2) { @@ -303,31 +309,78 @@ 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; + struct v3_vm_info * vm = dev->vm; + + if (video_state->framebuf_pa) { + V3_FreePages((void *)(video_state->framebuf_pa), (FRAMEBUF_SIZE / 4096)); + } v3_unhook_mem(dev->vm, V3_MEM_CORE_ANY, START_ADDR); + v3_unhook_io_port(vm, 0x3b0); + v3_unhook_io_port(vm, 0x3b1); + v3_unhook_io_port(vm, 0x3b2); + v3_unhook_io_port(vm, 0x3b3); + v3_unhook_io_port(vm, 0x3b4); + v3_unhook_io_port(vm, 0x3b5); + v3_unhook_io_port(vm, 0x3b6); + v3_unhook_io_port(vm, 0x3b7); + v3_unhook_io_port(vm, 0x3b8); + v3_unhook_io_port(vm, 0x3b9); + v3_unhook_io_port(vm, 0x3ba); + v3_unhook_io_port(vm, 0x3bb); + v3_unhook_io_port(vm, 0x3c0); + v3_unhook_io_port(vm, 0x3c1); + v3_unhook_io_port(vm, 0x3c2); + v3_unhook_io_port(vm, 0x3c3); + v3_unhook_io_port(vm, 0x3c4); + v3_unhook_io_port(vm, 0x3c5); + v3_unhook_io_port(vm, 0x3c6); + v3_unhook_io_port(vm, 0x3c7); + v3_unhook_io_port(vm, 0x3c8); + v3_unhook_io_port(vm, 0x3c9); + v3_unhook_io_port(vm, 0x3ca); + v3_unhook_io_port(vm, 0x3cb); + v3_unhook_io_port(vm, 0x3cc); + v3_unhook_io_port(vm, 0x3cd); + v3_unhook_io_port(vm, 0x3ce); + v3_unhook_io_port(vm, 0x3cf); + v3_unhook_io_port(vm, 0x3d0); + v3_unhook_io_port(vm, 0x3d1); + v3_unhook_io_port(vm, 0x3d2); + v3_unhook_io_port(vm, 0x3d3); + v3_unhook_io_port(vm, 0x3d4); + v3_unhook_io_port(vm, 0x3d5); + v3_unhook_io_port(vm, 0x3d6); + v3_unhook_io_port(vm, 0x3d7); + v3_unhook_io_port(vm, 0x3d8); + v3_unhook_io_port(vm, 0x3d9); + v3_unhook_io_port(vm, 0x3da); + v3_unhook_io_port(vm, 0x3db); + v3_unhook_io_port(vm, 0x3dc); + v3_unhook_io_port(vm, 0x3dd); + v3_unhook_io_port(vm, 0x3de); + v3_unhook_io_port(vm, 0x3df); + V3_Free(video_state); return 0; } - static struct v3_device_ops dev_ops = { .free = free_device, }; static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct video_internal * video_state = NULL; - addr_t frame_buf_pa = 0; - int enable_passthrough = 0; char * dev_id = v3_cfg_val(cfg, "ID"); - - enable_passthrough = (strcasecmp(v3_cfg_val(cfg, "passthrough"), "enable") == 0) ? 1 : 0; - + char * passthrough_str = v3_cfg_val(cfg, "passthrough"); + 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); @@ -337,75 +390,76 @@ static int cga_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return -1; } - frame_buf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096); - - video_state->framebuf = V3_VAddr((void *)frame_buf_pa); + video_state->framebuf_pa = (addr_t)V3_AllocPages(FRAMEBUF_SIZE / 4096); + video_state->framebuf = V3_VAddr((void *)(video_state->framebuf_pa)); memset(video_state->framebuf, 0, FRAMEBUF_SIZE); - PrintDebug("PA of array: %p\n", (void *)frame_buf_pa); + PrintDebug("PA of array: %p\n", (void *)(video_state->framebuf_pa)); - video_state->passthrough = enable_passthrough; + if ((passthrough_str != NULL) && + (strcasecmp(passthrough_str, "enable") == 0)) {; + video_state->passthrough = 1; + } - video_state->ops = NULL; - video_state->private_data = NULL; - if (enable_passthrough) { + if (video_state->passthrough) { PrintDebug("Enabling CGA Passthrough\n"); - - if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, START_ADDR, &video_write_mem, dev) == -1) { + if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, + START_ADDR, &video_write_mem, dev) == -1) { PrintDebug("\n\nVideo Hook failed.\n\n"); } } else { - if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, frame_buf_pa, &video_write_mem, dev) == -1) { + if (v3_hook_write_mem(vm, V3_MEM_CORE_ANY, START_ADDR, END_ADDR, + video_state->framebuf_pa, &video_write_mem, dev) == -1) { PrintDebug("\n\nVideo Hook failed.\n\n"); } } - 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); + v3_hook_io_port(vm, 0x3b0, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b1, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b2, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b3, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b4, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b5, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b6, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b7, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b8, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3b9, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3ba, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3bb, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c0, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c1, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c2, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c3, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c4, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c5, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c6, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c7, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c8, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3c9, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3ca, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3cb, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3cc, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3cd, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3ce, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3cf, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d0, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d1, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d2, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d3, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d4, &video_read_port, &crtc_index_write, dev); + v3_hook_io_port(vm, 0x3d5, &video_read_port, &crtc_data_write, dev); + v3_hook_io_port(vm, 0x3d6, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d7, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d8, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3d9, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3da, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3db, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3dc, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3dd, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3de, &video_read_port, &video_write_port, dev); + v3_hook_io_port(vm, 0x3df, &video_read_port, &video_write_port, dev); return 0; diff --git a/palacios/src/devices/char_stream.c b/palacios/src/devices/char_stream.c index 445194c..52e217e 100644 --- a/palacios/src/devices/char_stream.c +++ b/palacios/src/devices/char_stream.c @@ -37,41 +37,46 @@ struct stream_state { static int serial_event_handler(struct v3_vm_info * vm, struct v3_serial_event * evt, - void * private_data) { - struct stream_state *state = (struct stream_state *)private_data; + void * private_data) { + struct stream_state * state = (struct stream_state *)private_data; - if(state->char_ops.push != NULL){ + if (state->char_ops.push != NULL){ state->char_ops.push(vm, evt->data, evt->len, state->push_fn_arg); } return 0; } -static int stream_write(uint8_t * buf, uint64_t length, void * private_data) -{ - struct stream_state *state = (struct stream_state *)private_data; +static int stream_write(uint8_t * buf, uint64_t length, void * private_data) { + struct stream_state * state = (struct stream_state *)private_data; return v3_stream_write(state->stream, buf, length); } +static int stream_free(struct vm_device * dev) { + struct stream_state * state = (struct stream_state *)(dev->private_data); + + v3_stream_close(state->stream); + + // detach host event + + V3_Free(state); + + return 0; +} static struct v3_device_ops dev_ops = { - .free = NULL, - .reset = NULL, - .start = NULL, - .stop = NULL, + .free = stream_free, }; -static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) -{ +static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { char * dev_id = v3_cfg_val(cfg, "ID"); char * stream_name = v3_cfg_val(cfg, "name"); struct stream_state * state = NULL; v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); - state = (struct stream_state *)V3_Malloc(sizeof(struct stream_state)); if (state == NULL) { @@ -81,20 +86,11 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) memset(state, 0, sizeof(struct stream_state)); - state->stream = v3_stream_open(vm, stream_name); - - if (state->stream == NULL) { - PrintError("Could not open stream %s\n", stream_name); - V3_Free(state); - return -1; - } - - state->char_ops.write = stream_write; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); if (dev == NULL) { PrintError("Could not allocate device %s\n", dev_id); + V3_Free(state); return -1; } @@ -104,20 +100,28 @@ static int stream_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) 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); + return -1; + } + + state->char_ops.write = stream_write; + if (v3_dev_connect_char(vm, v3_cfg_val(frontend_cfg, "tag"), &(state->char_ops), frontend_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); return -1; } - v3_hook_host_event(vm, HOST_SERIAL_EVT, V3_HOST_EVENT_HANDLER(serial_event_handler), state); - return 0; } -device_register("CHAR_STREAM", stream_init) - +device_register("CHAR_STREAM", stream_init); diff --git a/palacios/src/devices/curses_cons.c b/palacios/src/devices/curses_cons.c index 1461036..90f695d 100644 --- a/palacios/src/devices/curses_cons.c +++ b/palacios/src/devices/curses_cons.c @@ -82,8 +82,8 @@ static int cursor_update(uint_t x, uint_t y, void *private_data) } static int screen_update(uint_t x, uint_t y, uint_t length, void * private_data) { - struct vm_device *dev = (struct vm_device *)private_data; - struct cons_state *state = (struct cons_state *)dev->private_data; + struct vm_device * dev = (struct vm_device *)private_data; + struct cons_state * state = (struct cons_state *)dev->private_data; uint_t offset = (x * BYTES_PER_COL) + (y * BYTES_PER_ROW); uint8_t fb_buf[length]; int i; @@ -156,6 +156,18 @@ static int scroll(int rows, void * private_data) { } +static int cons_free(struct vm_device * dev) { + struct cons_state * state = (struct cons_state *)dev->private_data; + + v3_console_close(state->cons); + + // remove host event + + V3_Free(state); + + return 0; +} + static int console_event_handler(struct v3_vm_info * vm, struct v3_console_event * evt, void * priv_data) { @@ -171,10 +183,7 @@ static struct v3_console_ops cons_ops = { }; static struct v3_device_ops dev_ops = { - .free = NULL, - .reset = NULL, - .start = NULL, - .stop = NULL, + .free = cons_free, }; static int cons_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) diff --git a/palacios/src/devices/filedisk.c b/palacios/src/devices/filedisk.c index f4e6318..928355a 100644 --- a/palacios/src/devices/filedisk.c +++ b/palacios/src/devices/filedisk.c @@ -112,6 +112,11 @@ static struct v3_dev_blk_ops blk_ops = { static int disk_free(struct vm_device * dev) { + struct disk_state * disk = dev->private_data; + + v3_file_close(disk->fd); + + V3_Free(disk); return 0; } @@ -129,37 +134,36 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { struct disk_state * disk = NULL; char * path = v3_cfg_val(cfg, "path"); char * dev_id = v3_cfg_val(cfg, "ID"); - char * writable = v3_cfg_val(cfg, "writable"); - char * readable = v3_cfg_val(cfg, "readable"); - - int allowWrite = ( writable && writable[0] == '1' ); - int allowRead = ( !readable || readable[0] == '1' ); - v3_cfg_tree_t * frontend_cfg = v3_cfg_subtree(cfg, "frontend"); + int flags = FILE_OPEN_MODE_READ; - disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state)); - memset(disk, 0, sizeof(struct disk_state)); - + if ( (writable) && (writable[0] == '1') ) { + flags |= FILE_OPEN_MODE_WRITE; + } if (path == NULL) { PrintError("Missing path (%s) for %s\n", path, dev_id); return -1; + } + + disk = (struct disk_state *)V3_Malloc(sizeof(struct disk_state)); + if (disk == NULL) { + PrintError("Could not allocate disk\n"); + return -1; } - - if ( (allowRead == 1) && (allowWrite == 1) ) { - disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_READ | FILE_OPEN_MODE_WRITE ); - } else if ( (allowRead == 1) && (allowWrite == 0) ) { - disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_READ); - } else if ( (allowRead == 0) && (allowWrite == 1) ) { - disk->fd = v3_file_open(vm, path, FILE_OPEN_MODE_WRITE); - } else { - PrintError("Error on %s: No file mode specified\n", dev_id ); - return -1; + memset(disk, 0, sizeof(struct disk_state)); + + disk->fd = v3_file_open(vm, path, flags); + + if (disk->fd == NULL) { + PrintError("Could not open file disk:%s\n", path); + V3_Free(disk); + return -1; } - + disk->capacity = v3_file_size(disk->fd); PrintDebug("Registering FILEDISK %s (path=%s, fd=%lu, size=%lu)\n", @@ -168,19 +172,19 @@ static int disk_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { 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); return -1; - } diff --git a/palacios/src/devices/generic.c b/palacios/src/devices/generic.c index 924de7c..ec78bb9 100644 --- a/palacios/src/devices/generic.c +++ b/palacios/src/devices/generic.c @@ -53,54 +53,32 @@ struct port_range { -static int generic_reset_device(struct vm_device * dev) { - PrintDebug("generic: reset device\n"); - return 0; -} - - - - - -static int generic_start_device(struct vm_device * dev) { - PrintDebug("generic: start device\n"); - return 0; -} - - -static int generic_stop_device(struct vm_device * dev) { - PrintDebug("generic: stop device\n"); - return 0; -} - - - static int generic_write_port_passthrough(struct guest_info * core, uint16_t port, void * src, - uint_t length, struct vm_device * dev) { + uint_t length, void * priv_data) { uint_t i; PrintDebug("generic: writing 0x"); for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); + PrintDebug("%x", ((uint8_t *)src)[i]); } PrintDebug(" to port 0x%x ... ", port); switch (length) { case 1: - v3_outb(port,((uchar_t*)src)[0]); + v3_outb(port, ((uint8_t *)src)[0]); break; case 2: - v3_outw(port,((uint16_t*)src)[0]); + v3_outw(port, ((uint16_t *)src)[0]); break; case 4: - v3_outdw(port,((uint32_t *)src)[0]); + v3_outdw(port, ((uint32_t *)src)[0]); break; default: for (i = 0; i < length; i++) { - v3_outb(port, ((uchar_t *)src)[i]); + v3_outb(port, ((uint8_t *)src)[i]); } } @@ -110,7 +88,7 @@ static int generic_write_port_passthrough(struct guest_info * core, uint16_t por } static int generic_read_port_passthrough(struct guest_info * core, uint16_t port, void * src, - uint_t length, struct vm_device * dev) { + uint_t length, void * priv_data) { uint_t i; PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); @@ -118,24 +96,24 @@ static int generic_read_port_passthrough(struct guest_info * core, uint16_t port switch (length) { case 1: - ((uchar_t*)src)[0] = v3_inb(port); + ((uint8_t *)src)[0] = v3_inb(port); break; case 2: - ((uint16_t*)src)[0] = v3_inw(port); + ((uint16_t *)src)[0] = v3_inw(port); break; case 4: - ((uint_t*)src)[0] = v3_indw(port); + ((uint32_t *)src)[0] = v3_indw(port); break; default: for (i = 0; i < length; i++) { - ((uchar_t*)src)[i] = v3_inb(port); + ((uint8_t *)src)[i] = v3_inb(port); } } PrintDebug(" done ... read 0x"); for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); + PrintDebug("%x", ((uint8_t *)src)[i]); } PrintDebug("\n"); @@ -144,13 +122,13 @@ static int generic_read_port_passthrough(struct guest_info * core, uint16_t port } static int generic_write_port_ignore(struct guest_info * core, uint16_t port, void * src, - uint_t length, struct vm_device * dev) { - uint_t i; + uint_t length, void * priv_data) { + int i; PrintDebug("generic: writing 0x"); for (i = 0; i < length; i++) { - PrintDebug("%x", ((uchar_t*)src)[i]); + PrintDebug("%x", ((uint8_t *)src)[i]); } PrintDebug(" to port 0x%x ... ignored\n", port); @@ -159,11 +137,11 @@ static int generic_write_port_ignore(struct guest_info * core, uint16_t port, vo } static int generic_read_port_ignore(struct guest_info * core, uint16_t port, void * src, - uint_t length, struct vm_device * dev) { + uint_t length, void * priv_data) { PrintDebug("generic: reading 0x%x bytes from port 0x%x ...", length, port); - memset((char*)src, 0, length); + memset((uint8_t *)src, 0, length); PrintDebug(" ignored (return zeroed buffer)\n"); return length; @@ -187,7 +165,7 @@ static int generic_free(struct vm_device * dev) { cur->start, cur->end); for (i = cur->start; i <= cur->end; i++) { - if (v3_dev_unhook_io(dev, i)) { + if (v3_unhook_io_port(dev->vm, i)) { PrintDebug("generic: can't unhook port 0x%x (already unhooked?)\n", i); } } @@ -197,7 +175,7 @@ static int generic_free(struct vm_device * dev) { V3_Free(cur); } - generic_reset_device(dev); + V3_Free(state); return 0; } @@ -207,9 +185,6 @@ static int generic_free(struct vm_device * dev) { static struct v3_device_ops dev_ops = { .free = generic_free, - .reset = generic_reset_device, - .start = generic_start_device, - .stop = generic_stop_device, }; @@ -230,12 +205,16 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene for (i = start; i <= end; i++) { if (mode == GENERIC_PRINT_AND_PASSTHROUGH) { - if (v3_dev_hook_io(dev, i, &generic_read_port_passthrough, &generic_write_port_passthrough) == -1) { + if (v3_hook_io_port(dev->vm, i, + &generic_read_port_passthrough, + &generic_write_port_passthrough, dev) == -1) { PrintError("generic: can't hook port 0x%x (already hooked?)\n", i); return -1; } } else if (mode == GENERIC_PRINT_AND_IGNORE) { - if (v3_dev_hook_io(dev, i, &generic_read_port_ignore, &generic_write_port_ignore) == -1) { + if (v3_hook_io_port(dev->vm, i, + &generic_read_port_ignore, + &generic_write_port_ignore, dev) == -1) { PrintError("generic: can't hook port 0x%x (already hooked?)\n", i); return -1; } @@ -253,25 +232,32 @@ static int add_port_range(struct vm_device * dev, uint_t start, uint_t end, gene static int generic_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { - struct generic_internal * state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); + struct generic_internal * state = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); - v3_cfg_tree_t * port_cfg = v3_cfg_subtree(cfg, "ports"); + state = (struct generic_internal *)V3_Malloc(sizeof(struct generic_internal)); + + if (state == NULL) { + PrintError("Could not allocate generic state\n"); + return -1; + } + + memset(state, 0, sizeof(struct generic_internal)); + INIT_LIST_HEAD(&(state->port_list)); state->num_port_ranges = 0; - struct vm_device * dev = v3_allocate_device(dev_id, &dev_ops, state); if (v3_attach_device(vm, dev) == -1) { PrintError("Could not attach device %s\n", dev_id); + V3_Free(state); return -1; } PrintDebug("generic: init_device\n"); - generic_reset_device(dev); // scan port list.... while (port_cfg) { @@ -286,11 +272,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); 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); return -1; } diff --git a/palacios/src/devices/i440fx.c b/palacios/src/devices/i440fx.c index ddd169c..9b52eed 100644 --- a/palacios/src/devices/i440fx.c +++ b/palacios/src/devices/i440fx.c @@ -21,6 +21,8 @@ #include #include +#include + // We Have to setup some sort of PIC interrupt mapping here.... @@ -29,12 +31,14 @@ struct i440_state { }; -static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, struct vm_device * dev) { +static int io_read(struct guest_info * core, ushort_t port, void * dst, uint_t length, void * priv_data) { + // struct vm_device * dev = priv_data; PrintError("Unhandled read on port %x\n", port); return -1; } -static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, struct vm_device * dev) { +static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t length, void * priv_data) { + // struct vm_device * dev = priv_data; PrintError("Unhandled write on port %x\n", port); return -1; } @@ -44,6 +48,18 @@ static int io_write(struct guest_info * core, ushort_t port, void * src, uint_t static int i440_free(struct vm_device * dev) { + struct i440_state * state = dev->private_data; + int i; + + for (i = 0; i < 4; i++) { + v3_unhook_io_port(dev->vm, 0x0cf8 + i); + v3_unhook_io_port(dev->vm, 0x0cfc + i); + } + + // unregister from PCI + + V3_Free(state); + return 0; } @@ -78,15 +94,13 @@ static int i440_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; } - 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); + v3_hook_io_port(vm, 0x0cf8 + i, &io_read, &io_write, dev); + v3_hook_io_port(vm, 0x0cfc + i, &io_read, &io_write, dev); } for (i = 0; i < 6; i++) { @@ -98,6 +112,7 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { NULL, NULL, NULL, dev); if (!pci_dev) { + v3_detach_device(dev); return -1; } @@ -112,4 +127,4 @@ static int i440_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { return 0; } -device_register("i440FX", i440_init) +device_register("i440FX", i440_init); diff --git a/palacios/src/devices/ide.c b/palacios/src/devices/ide.c index 4ad0fa9..8577e09 100644 --- a/palacios/src/devices/ide.c +++ b/palacios/src/devices/ide.c @@ -1433,16 +1433,19 @@ static int init_ide_state(struct vm_device * dev) { static int ide_free(struct vm_device * dev) { // unhook io ports.... + + // deregister from PCI? + + + return 0; } static struct v3_device_ops dev_ops = { .free = ide_free, - .reset = NULL, - .start = NULL, - .stop = NULL, + }; @@ -1520,10 +1523,18 @@ 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 = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal)); + struct ide_internal * ide = NULL; char * dev_id = v3_cfg_val(cfg, "ID"); PrintDebug("IDE: Initializing IDE\n"); + + ide = (struct ide_internal *)V3_Malloc(sizeof(struct ide_internal)); + + if (ide == NULL) { + PrintError("Error allocating IDE state\n"); + return -1; + } + memset(ide, 0, sizeof(struct ide_internal)); @@ -1534,6 +1545,7 @@ static int ide_init(struct v3_vm_info * vm, v3_cfg_tree_t * cfg) { if (!southbridge) { PrintError("Could not find southbridge\n"); + V3_Free(ide); return -1; } @@ -1546,11 +1558,14 @@ static int ide_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_device(dev); + V3_Free(ide); return -1; } if (init_ide_state(dev) == -1) { PrintError("Failed to initialize IDE state\n"); + v3_detach_device(dev); return -1; } @@ -1662,6 +1677,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); return -1; } diff --git a/palacios/src/palacios/vmm_console.c b/palacios/src/palacios/vmm_console.c index 9ecf780..f461606 100644 --- a/palacios/src/palacios/vmm_console.c +++ b/palacios/src/palacios/vmm_console.c @@ -35,6 +35,12 @@ v3_console_t v3_console_open(struct v3_vm_info * vm, uint32_t width, uint32_t he return console_hooks->open(vm->host_priv_data, width, height); } +void v3_console_close(v3_console_t cons) { + V3_ASSERT(console_hooks); + V3_ASSERT(console_hooks->close); + + console_hooks->close(cons); +} int v3_console_set_cursor(v3_console_t cons, int x, int y) { V3_ASSERT(console_hooks != NULL); diff --git a/palacios/src/palacios/vmm_dev_mgr.c b/palacios/src/palacios/vmm_dev_mgr.c index 5561cec..cd6857d 100644 --- a/palacios/src/palacios/vmm_dev_mgr.c +++ b/palacios/src/palacios/vmm_dev_mgr.c @@ -115,7 +115,6 @@ int v3_dev_mgr_deinit(struct v3_vm_info * vm) { list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) { v3_detach_device(dev); - v3_free_device(dev); } v3_free_htable(mgr->blk_table, 0, 0); @@ -145,7 +144,6 @@ int v3_core_dev_mgr_deinit(struct v3_vm_info * vm) { list_for_each_entry_safe(dev, tmp, &(mgr->dev_list), dev_link) { v3_detach_device(dev); - v3_free_device(dev); } // TODO: Clear hash tables @@ -226,6 +224,7 @@ int v3_detach_device(struct vm_device * dev) { dev->vm = NULL; + v3_free_device(dev); return -1; }