From: Jack Lange Date: Wed, 8 Jun 2011 19:36:38 +0000 (-0500) Subject: bug fixes for extension framework, and porting of console to new interface X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=c94c9b19999f937b32627794c80e19c9be555822 bug fixes for extension framework, and porting of console to new interface --- diff --git a/linux_module/ld.cmd b/linux_module/ld.cmd index fd97c26..bd86dc7 100644 --- a/linux_module/ld.cmd +++ b/linux_module/ld.cmd @@ -1,5 +1,12 @@ SECTIONS { + + _lnx_exts : + { + __start__lnx_exts = .; + *(_lnx_exts); + __stop__lnx_exts = .; + } _v3_devices : { __start__v3_devices = .; @@ -22,11 +29,6 @@ SECTIONS __stop__v3_extensions = .; } - _lnx_exts : - { - __start__lnx_exts = .; - *(_lnx_exts); - __stop__lnx_exts = .; - } + } diff --git a/linux_module/linux-exts.c b/linux_module/linux-exts.c index f4afafd..d6409b8 100644 --- a/linux_module/linux-exts.c +++ b/linux_module/linux-exts.c @@ -4,41 +4,90 @@ /* * This is a place holder to ensure that the _lnx_exts section gets created by gcc */ + + static struct {} null_ext __attribute__((__used__)) \ - __attribute__((unused, __section__ ("_lnx_exts"), \ - aligned(sizeof(void *)))); + __attribute__((unused, __section__ ("_lnx_exts"), \ + aligned(sizeof(void *)))); +struct vm_ext { + struct linux_ext * impl; + void * vm_data; + struct list_head node; +}; int init_vm_extensions(struct v3_guest * guest) { - extern struct linux_ext * __start__lnx_exts; - extern struct linux_ext * __stop__lnx_exts; - struct linux_ext * tmp_ext = __start__lnx_exts; + extern struct linux_ext * __start__lnx_exts[]; + extern struct linux_ext * __stop__lnx_exts[]; + struct linux_ext * ext_impl = __start__lnx_exts[0]; int i = 0; - while (tmp_ext != __stop__lnx_exts) { - printk("Registering Linux Extension (%s)\n", tmp_ext->name); - tmp_ext->init(); + while (ext_impl != __stop__lnx_exts[0]) { + struct vm_ext * ext = NULL; + + if (ext_impl->guest_init == NULL) { + // We can have global extensions without per guest state + continue; + } + + printk("Registering Linux Extension (%s)\n", ext_impl->name); + + ext = kmalloc(sizeof(struct vm_ext), GFP_KERNEL); + + if (!ext) { + printk("Error allocating VM extension (%s)\n", ext_impl->name); + return -1; + } - tmp_ext = &(__start__lnx_exts[++i]); + ext->impl = ext_impl; + + ext_impl->guest_init(guest, &(ext->vm_data)); + + list_add(&(ext->node), &(guest->exts)); + + ext_impl = __start__lnx_exts[++i]; } return 0; +} + +int deinit_vm_extensions(struct v3_guest * guest) { + struct vm_ext * ext = NULL; + struct vm_ext * tmp = NULL; + + list_for_each_entry_safe(ext, tmp, &(guest->exts), node) { + if (ext->impl->guest_deinit) { + ext->impl->guest_deinit(guest, ext->vm_data); + } else { + printk("WARNING: Extension %s, does not have a guest deinit function\n", ext->impl->name); + } + + list_del(&(ext->node)); + kfree(ext); + } + + return 0; } int init_lnx_extensions( void ) { - extern struct linux_ext * __start__lnx_exts; - extern struct linux_ext * __stop__lnx_exts; - struct linux_ext * tmp_ext = __start__lnx_exts; + extern struct linux_ext * __start__lnx_exts[]; + extern struct linux_ext * __stop__lnx_exts[]; + struct linux_ext * tmp_ext = __start__lnx_exts[0]; int i = 0; - while (tmp_ext != __stop__lnx_exts) { - printk("Registering Linux Extension (%s)\n", tmp_ext->name); - tmp_ext->init(); + while (tmp_ext != __stop__lnx_exts[0]) { + + printk("tmp_ext=%p\n", tmp_ext); + + if (tmp_ext->init != NULL) { + printk("Registering Linux Extension (%s)\n", tmp_ext->name); + tmp_ext->init(); + } - tmp_ext = &(__start__lnx_exts[++i]); + tmp_ext = __start__lnx_exts[++i]; } return 0; @@ -46,16 +95,20 @@ int init_lnx_extensions( void ) { int deinit_lnx_extensions( void ) { - extern struct linux_ext * __start__lnx_exts; - extern struct linux_ext * __stop__lnx_exts; - struct linux_ext * tmp_ext = __start__lnx_exts; + extern struct linux_ext * __start__lnx_exts[]; + extern struct linux_ext * __stop__lnx_exts[]; + struct linux_ext * tmp_ext = __start__lnx_exts[0]; int i = 0; - while (tmp_ext != __stop__lnx_exts) { + while (tmp_ext != __stop__lnx_exts[0]) { printk("Cleaning up Linux Extension (%s)\n", tmp_ext->name); - tmp_ext->deinit(); + if (tmp_ext->deinit != NULL) { + tmp_ext->deinit(); + } else { + printk("WARNING: Extension %s does not have a global deinit function\n", tmp_ext->name); + } - tmp_ext = &(__start__lnx_exts[++i]); + tmp_ext = __start__lnx_exts[++i]; } return 0; diff --git a/linux_module/linux-exts.h b/linux_module/linux-exts.h index 72e4800..041d8dc 100644 --- a/linux_module/linux-exts.h +++ b/linux_module/linux-exts.h @@ -12,7 +12,7 @@ struct linux_ext { int (*deinit)( void ); int (*guest_init)(struct v3_guest * guest, void ** priv_data); int (*guest_deinit)(struct v3_guest * guest, void * priv_data); -} __attribute__((packed)); +}; @@ -24,6 +24,6 @@ int deinit_lnx_extensions( void ); #define register_extension(ext) \ static struct linux_ext * _lnx_ext \ __attribute__((used)) \ - __attribute__((unused, __section("_lnx_exts"), \ + __attribute__((unused, __section__("_lnx_exts"), \ aligned(sizeof(void *)))) \ = ext; diff --git a/linux_module/palacios-console.c b/linux_module/palacios-console.c index 7ba96bd..d0c85ba 100644 --- a/linux_module/palacios-console.c +++ b/linux_module/palacios-console.c @@ -16,9 +16,10 @@ #include #include +#include "palacios-vm.h" #include "palacios.h" -#include "palacios-console.h" #include "palacios-queue.h" +#include "linux-exts.h" typedef enum { CONSOLE_CURS_SET = 1, CONSOLE_CHAR_SET = 2, @@ -28,6 +29,23 @@ typedef enum { CONSOLE_CURS_SET = 1, +struct palacios_console { + struct gen_queue * queue; + spinlock_t lock; + + int open; + int connected; + + wait_queue_head_t intr_queue; + + unsigned int width; + unsigned int height; + + struct v3_guest * guest; +}; + + + struct cursor_msg { int x; int y; @@ -186,8 +204,9 @@ static struct file_operations cons_fops = { -int connect_console(struct v3_guest * guest) { - struct palacios_console * cons = &(guest->console); +static int console_connect(struct v3_guest * guest, unsigned int cmd, + unsigned long arg, void * priv_data) { + struct palacios_console * cons = priv_data; int cons_fd = 0; unsigned long flags; @@ -219,7 +238,7 @@ int connect_console(struct v3_guest * guest) { static void * palacios_tty_open(void * private_data, unsigned int width, unsigned int height) { struct v3_guest * guest = (struct v3_guest *)private_data; - struct palacios_console * cons = &(guest->console); + struct palacios_console * cons = kmalloc(sizeof(struct palacios_console), GFP_KERNEL); printk("Guest initialized virtual console (Guest=%s)\n", guest->name); @@ -234,19 +253,20 @@ static void * palacios_tty_open(void * private_data, unsigned int width, unsigne } - cons->width = width; - cons->height = height; - cons->queue = create_queue(CONSOLE_QUEUE_LEN); spin_lock_init(&(cons->lock)); init_waitqueue_head(&(cons->intr_queue)); cons->guest = guest; - cons->open = 1; cons->connected = 0; + cons->width = width; + cons->height = height; + cons->open = 1; + add_guest_ctrl(guest, V3_VM_CONSOLE_CONNECT, console_connect, cons); + return cons; } @@ -369,8 +389,25 @@ static struct v3_console_hooks palacios_console_hooks = { -int palacios_init_console( void ) { + + + +static int console_init( void ) { V3_Init_Console(&palacios_console_hooks); return 0; } + + + + +static struct linux_ext console_ext = { + .name = "CONSOLE", + .init = console_init, + .deinit = NULL, + .guest_init = NULL, + .guest_deinit = NULL +}; + + +register_extension(&console_ext); diff --git a/linux_module/palacios-console.h b/linux_module/palacios-console.h deleted file mode 100644 index 9e443e5..0000000 --- a/linux_module/palacios-console.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Palacios VM Stream Console interface - * (c) Jack Lange, 2010 - */ - -#ifndef __PALACIOS_CONSOLE_H__ -#define __PALACIOS_CONSOLE_H__ - - -#include -#include - - -struct palacios_console { - struct gen_queue * queue; - spinlock_t lock; - - int open; - int connected; - - wait_queue_head_t intr_queue; - - unsigned int width; - unsigned int height; - - struct v3_guest * guest; -}; - - - -struct v3_guest; - - -int connect_console(struct v3_guest * guest); - -int palacios_init_console( void ); - - -#endif diff --git a/linux_module/palacios-dev.c b/linux_module/palacios-dev.c index cf8e0fe..7e796cf 100644 --- a/linux_module/palacios-dev.c +++ b/linux_module/palacios-dev.c @@ -28,6 +28,8 @@ #include "palacios-vnet.h" #include "palacios-packet.h" +#include "linux-exts.h" + #ifdef V3_CONFIG_EXT_INSPECTOR #include "palacios-inspector.h" #endif @@ -51,9 +53,6 @@ static u8 v3_minor_map[MAX_VMS / 8] = {[0 ... (MAX_VMS / 8) - 1] = 0}; struct class * v3_class = NULL; static struct cdev ctrl_dev; -void * v3_base_addr = NULL; -unsigned int v3_pages = 0; - static int register_vm( void ) { int i, j = 0; int avail = 0; @@ -137,6 +136,9 @@ static long v3_dev_ioctl(struct file * filp, printk("Launching VM\n"); + INIT_LIST_HEAD(&(guest->exts)); + + INIT_LIST_HEAD(&(guest->streams)); INIT_LIST_HEAD(&(guest->files)); INIT_LIST_HEAD(&(guest->sockets)); @@ -208,8 +210,6 @@ static struct file_operations v3_ctrl_fops = { }; -extern unsigned int v3_pages; -extern void * v3_base_addr; static int __init v3_init(void) { dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number @@ -218,6 +218,16 @@ static int __init v3_init(void) { palacios_init_mm(); + + // Initialize Palacios + + palacios_vmm_init(); + + + // initialize extensions + init_lnx_extensions(); + + v3_class = class_create(THIS_MODULE, "vms"); if (IS_ERR(v3_class)) { printk("Failed to register V3 VM device class\n"); @@ -251,13 +261,7 @@ static int __init v3_init(void) { goto failure1; } - if ((v3_pages > 0) && (v3_base_addr != NULL)) { - add_palacios_memory(__pa(v3_base_addr), v3_pages); - } - // Initialize Palacios - - palacios_vmm_init(); #ifdef V3_CONFIG_STREAM palacios_init_stream(); @@ -271,10 +275,6 @@ static int __init v3_init(void) { palacios_init_keyed_streams(); #endif -#ifdef V3_CONFIG_CONSOLE - palacios_init_console(); -#endif - #ifdef V3_CONFIG_GRAPHICS_CONSOLE palacios_init_graphics_console(); #endif diff --git a/linux_module/palacios-vm.c b/linux_module/palacios-vm.c index 9cdaa6d..d3ae315 100644 --- a/linux_module/palacios-vm.c +++ b/linux_module/palacios-vm.c @@ -115,9 +115,6 @@ static struct vm_ctrl * get_ctrl(struct v3_guest * guest, unsigned int cmd) { #include "palacios-stream.h" #endif -#ifdef V3_CONFIG_CONSOLE -#include "palacios-console.h" -#endif #ifdef V3_CONFIG_EXT_INSPECTOR #include "palacios-inspector.h" @@ -150,15 +147,6 @@ static long v3_vm_ioctl(struct file * filp, break; } - case V3_VM_CONSOLE_CONNECT: { -#ifdef V3_CONFIG_CONSOLE - return connect_console(guest); -#else - printk("Console support not available\n"); - return -EFAULT; -#endif - break; - } case V3_VM_STREAM_CONNECT: { #ifdef V3_CONFIG_STREAM @@ -284,6 +272,8 @@ int start_palacios_vm(void * arg) { } // init linux extensions + + #ifdef V3_CONFIG_EXT_INSPECTOR inspect_vm(guest); #endif diff --git a/linux_module/palacios.h b/linux_module/palacios.h index 62f43f1..936b71a 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -6,9 +6,6 @@ #include #include -#ifdef V3_CONFIG_CONSOLE -#include "palacios-console.h" -#endif #ifdef V3_CONFIG_GRAPHICS_CONSOLE #include "palacios-graphics-console.h" @@ -72,9 +69,6 @@ struct v3_guest { struct list_head streams; struct list_head sockets; -#ifdef V3_CONFIG_CONSOLE - struct palacios_console console; -#endif #ifdef V3_CONFIG_GRAPHICS_CONSOLE struct palacios_graphics_console graphics_console;