From: Jack Lange Date: Thu, 9 Jun 2011 17:41:24 +0000 (-0500) Subject: moved host device to extension framework X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=commitdiff_plain;h=3d2ae914c0dae420aa777ad0b298060b808434f1;p=palacios.git moved host device to extension framework --- diff --git a/linux_module/palacios-dev.c b/linux_module/palacios-dev.c index 71e861d..f06f166 100644 --- a/linux_module/palacios-dev.c +++ b/linux_module/palacios-dev.c @@ -21,7 +21,6 @@ #include "palacios.h" #include "palacios-mm.h" #include "palacios-vm.h" -#include "palacios-serial.h" #include "palacios-vnet.h" #include "linux-exts.h" @@ -127,10 +126,6 @@ static long v3_dev_ioctl(struct file * filp, INIT_LIST_HEAD(&(guest->exts)); - -#ifdef V3_CONFIG_HOST_DEVICE - INIT_LIST_HEAD(&(guest->hostdev.devs)); -#endif init_completion(&(guest->start_done)); init_completion(&(guest->thread_done)); @@ -256,10 +251,6 @@ static int __init v3_init(void) { palacios_vnet_init(); #endif -#ifdef V3_CONFIG_HOST_DEVICE - palacios_init_host_dev(); -#endif - return 0; failure1: diff --git a/linux_module/palacios-graphics-console.c b/linux_module/palacios-graphics-console.c index 2602df9..e5d4918 100644 --- a/linux_module/palacios-graphics-console.c +++ b/linux_module/palacios-graphics-console.c @@ -45,10 +45,11 @@ struct palacios_graphics_console { // descriptor for the data in the shared frame buffer struct v3_frame_buffer_spec spec; + // the actual shared frame buffer // Note that "shared" here means shared between palacios and us // This data could of course also be shared with userland - void *data; + void * data; int cons_refcount; int data_refcount; @@ -123,17 +124,17 @@ static void g_close(v3_graphics_console_t cons) gc->cons_refcount--; gc->data_refcount--; - if (gc->data_refcountcons_refcount) { + if (gc->data_refcount < gc->cons_refcount) { printk("palacios: error! data refcount is less than console refcount for graphics console\n"); } - if (gc->cons_refcount>0) { + if (gc->cons_refcount > 0) { return; } else { - if (gc->cons_refcount<0) { + if (gc->cons_refcount < 0) { printk("palacios: error! refcount for graphics console is negative on close!\n"); } - if (gc->data_refcount>0) { + if (gc->data_refcount > 0) { printk("palacios: error! refcount for graphics console data is positive on close - LEAKING MEMORY\n"); return; } @@ -255,13 +256,12 @@ static int gfx_console_init( void ) { static int fb_query(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) { - - struct v3_fb_query_response __user * u = (struct v3_fb_query_response __user *)arg; + struct palacios_graphics_console * cons = priv_data; struct v3_fb_query_response q; - if (copy_from_user(&q,(void __user *) u, sizeof(struct v3_fb_query_response))) { + if (copy_from_user(&q, (void __user *) arg, sizeof(struct v3_fb_query_response))) { printk("palacios: copy from user in getting query in fb\n"); return -EFAULT; } @@ -301,7 +301,7 @@ static int fb_query(struct v3_guest * guest, unsigned int cmd, unsigned long arg printk("palacios: unable to copy fb content to user\n"); return -EFAULT; } - q.updated=1; + q.updated = 1; } break; @@ -310,7 +310,7 @@ static int fb_query(struct v3_guest * guest, unsigned int cmd, unsigned long arg } // now we'll copy back any changes we made to the query/response structure - if (copy_to_user((void __user *) u, (void*)&q, sizeof(struct v3_fb_query_response))) { + if (copy_to_user((void __user *) arg, (void*)&q, sizeof(struct v3_fb_query_response))) { printk("palacios: unable to copy fb response to user\n"); return -EFAULT; } @@ -324,13 +324,12 @@ static int fb_input(struct v3_guest * guest, unsigned long arg, void * priv_data) { - struct v3_fb_input __user * u = (struct v3_fb_input __user *)arg; struct palacios_graphics_console * cons = priv_data; struct v3_fb_input inp; int rc = 0; - if (copy_from_user(&inp,(void __user *) u, sizeof(struct v3_fb_input))) { + if (copy_from_user(&inp, (void __user *) arg, sizeof(struct v3_fb_input))) { printk("palacios: copy from user in getting input in fb\n"); return -EFAULT; } diff --git a/linux_module/palacios-host-dev.c b/linux_module/palacios-host-dev.c index 29cb303..f92f115 100644 --- a/linux_module/palacios-host-dev.c +++ b/linux_module/palacios-host-dev.c @@ -17,10 +17,9 @@ #include #include "palacios.h" -#include "palacios-host-dev.h" #include "palacios-host-dev-user.h" - - +#include "linux-exts.h" +#include "palacios-vm.h" /* There are two things in this file: @@ -107,6 +106,12 @@ */ +struct palacios_host_dev { + spinlock_t lock; + struct list_head devs; +}; + + #define MAX_URL 256 #define RENDEZVOUS_WAIT_SECS 60 @@ -596,13 +601,22 @@ static struct file_operations host_dev_fops = { - -int connect_host_dev(struct v3_guest * guest, char *url) +static int host_dev_connect(struct v3_guest * guest, unsigned int cmd, unsigned long arg, void * priv_data) { + void __user * argp = (void __user *)arg; + char url[MAX_URL]; + struct palacios_host_dev * host_dev = priv_data; struct palacios_host_device_user *dev; unsigned long f1, f2; int i; + + + if (copy_from_user(url, argp, MAX_URL)) { + printk("copy from user error getting url for host device connect...\n"); + return -EFAULT; + } + // currently only support user: types: if (strncasecmp(url,"user:",5)) { ERROR("palacios: do not currently support host devices of type in \"%s\"\n",url); @@ -615,22 +629,22 @@ int connect_host_dev(struct v3_guest * guest, char *url) // URL. If we don't find it after a while, we give up for (i=0;ihostdev.lock),f1); - list_for_each_entry(dev,&(guest->hostdev.devs), node) { + spin_lock_irqsave(&(host_dev->lock),f1); + list_for_each_entry(dev,&(host_dev->devs), node) { if (!strncasecmp(url,dev->url,MAX_URL)) { // found it spin_lock_irqsave(&(dev->lock),f2); if (dev->connected) { ERROR("palacios: device for \"%s\" is already connected!\n",url); spin_unlock_irqrestore(&(dev->lock),f2); - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); return -1; } else { dev->fd = anon_inode_getfd("v3-hostdev", &host_dev_fops, dev, 0); if (dev->fd<0) { ERROR("palacios: cannot create fd for device \"%s\"\n",url); spin_unlock_irqrestore(&(dev->lock),f2); - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); return -1; } dev->connected=1; @@ -645,13 +659,13 @@ int connect_host_dev(struct v3_guest * guest, char *url) } INFO("palacios: connected fd for device \"%s\"\n",url); spin_unlock_irqrestore(&(dev->lock),f2); - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); return dev->fd; } spin_unlock_irqrestore(&(dev->lock),f2); } } - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); ssleep(RENDEZVOUS_RETRY_SECS); } @@ -684,12 +698,25 @@ static v3_host_dev_t palacios_host_dev_open(char *url, struct palacios_host_device_user *dev; unsigned long f1,f2; int i; + struct palacios_host_dev * host_dev = NULL; /* I will create the device in the list and then wait for the user side to attach */ + if (guest == NULL) { + return 0; + } + + + host_dev = get_vm_ext_data(guest, "HOST_DEV_INTERFACE"); + + if (host_dev == NULL) { + printk("Error locating vm host data for HOST_DEV_INTERFACE\n"); + return 0; + } + if (strncasecmp(url,"user:",5)) { ERROR("palacios: do not currently support devices of type in \"%s\"\n",url); @@ -697,16 +724,16 @@ static v3_host_dev_t palacios_host_dev_open(char *url, } // Check to see if a device of this url already exists, which would be ugly - spin_lock_irqsave(&(guest->hostdev.lock),f1); - list_for_each_entry(dev,&(guest->hostdev.devs), node) { + spin_lock_irqsave(&(host_dev->lock),f1); + list_for_each_entry(dev,&(host_dev->devs), node) { if (!strncasecmp(url,dev->url,MAX_URL)) { // found it - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); ERROR("palacios: a host device with url \"%s\" already exists in the guest!\n",url); return NULL; } } - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); INFO("palacios: creating host device \"%s\"\n",url); @@ -734,9 +761,9 @@ static v3_host_dev_t palacios_host_dev_open(char *url, INFO("palacios: attempting to rendezvous with user side of host device \"%s\"\n",url); // Insert ourselves into the list - spin_lock_irqsave(&(guest->hostdev.lock),f1); - list_add(&(dev->node),&(guest->hostdev.devs)); - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_lock_irqsave(&(host_dev->lock),f1); + list_add(&(dev->node),&(host_dev->devs)); + spin_unlock_irqrestore(&(host_dev->lock),f1); // Now wait until we are noticed! @@ -754,9 +781,9 @@ static v3_host_dev_t palacios_host_dev_open(char *url, ERROR("palacios: timeout waiting for user side to connect to host device \"%s\"",url); // get us out of the list - spin_lock_irqsave(&(guest->hostdev.lock),f1); + spin_lock_irqsave(&(host_dev->lock),f1); list_del(&(dev->node)); - spin_unlock_irqrestore(&(guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); palacios_host_dev_user_free(dev); @@ -768,10 +795,22 @@ static int palacios_host_dev_close(v3_host_dev_t hostdev) unsigned long f1, f2; struct palacios_host_device_user *dev = (struct palacios_host_device_user *) hostdev; - + struct palacios_host_dev * host_dev = NULL; + INFO("palacios: closing host device \"%s\"\n",dev->url); - spin_lock_irqsave(&(dev->guest->hostdev.lock),f1); + if ((dev == NULL) || (dev->guest == NULL)) { + return -1; + } + + host_dev = get_vm_ext_data(dev->guest, "HOST_DEV_INTERFACE"); + + + if (host_dev == NULL) { + return -1; + } + + spin_lock_irqsave(&(host_dev->lock),f1); spin_lock_irqsave(&(dev->lock),f2); @@ -783,7 +822,7 @@ static int palacios_host_dev_close(v3_host_dev_t hostdev) list_del(&(dev->node)); spin_unlock_irqrestore(&(dev->lock),f2); - spin_unlock_irqrestore(&(dev->guest->hostdev.lock),f1); + spin_unlock_irqrestore(&(host_dev->lock),f1); palacios_host_dev_user_free(dev); @@ -1253,9 +1292,39 @@ static struct v3_host_dev_hooks palacios_host_dev_hooks = { -int palacios_init_host_dev( void ) -{ +static int host_dev_init( void ) { V3_Init_Host_Device_Support(&palacios_host_dev_hooks); return 0; } + + +static int host_dev_guest_init(struct v3_guest * guest, void ** vm_data ) { + struct palacios_host_dev * host_dev = kmalloc(sizeof(struct palacios_host_dev), GFP_KERNEL); + + + INIT_LIST_HEAD(&(host_dev->devs)); + spin_lock_init(&(host_dev->lock)); + + *vm_data = host_dev; + + + add_guest_ctrl(guest, V3_VM_HOST_DEV_CONNECT, host_dev_connect, host_dev); + + return 0; +} + + + + + +static struct linux_ext host_dev_ext = { + .name = "HOST_DEV_INTERFACE", + .init = host_dev_init, + .deinit = NULL, + .guest_init = host_dev_guest_init, + .guest_deinit = NULL +}; + + +register_extension(&host_dev_ext); diff --git a/linux_module/palacios-host-dev.h b/linux_module/palacios-host-dev.h deleted file mode 100644 index d444b7d..0000000 --- a/linux_module/palacios-host-dev.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Palacios Host Device Interface + User-space interface - * (c) Peter Dinda, 2011 - */ - -#ifndef __PALACIOS_HOST_DEV_H__ -#define __PALACIOS_HOST_DEV_H__ - -#include -#include -#include "palacios-host-dev-user.h" - -struct v3_guest; - -/* - This is the collection of host devices that - a single guest has -*/ -struct palacios_host_dev { - spinlock_t lock; - struct list_head devs; -}; - - - -int connect_host_dev(struct v3_guest * guest, char *url); - -int palacios_init_host_dev( void ); - - -#endif diff --git a/linux_module/palacios-vm.c b/linux_module/palacios-vm.c index d325c8b..04b338a 100644 --- a/linux_module/palacios-vm.c +++ b/linux_module/palacios-vm.c @@ -115,10 +115,7 @@ static struct vm_ctrl * get_ctrl(struct v3_guest * guest, unsigned int cmd) { -#ifdef V3_CONFIG_HOST_DEVICE -#include "palacios-host-dev.h" -#define HOST_DEV_URL_LEN 256 -#endif + extern struct class * v3_class; @@ -138,28 +135,6 @@ static long v3_vm_ioctl(struct file * filp, break; } - - - case V3_VM_HOST_DEV_CONNECT: { -#ifdef V3_CONFIG_HOST_DEVICE - void __user * argp = (void __user *)arg; - char host_dev_url[HOST_DEV_URL_LEN]; - - if (copy_from_user(host_dev_url, argp, HOST_DEV_URL_LEN)) { - printk("copy from user error getting url for host device connect...\n"); - return -EFAULT; - } - - return connect_host_dev(guest,host_dev_url); -#else - printk("palacios: Host device support not available\n"); - return -EFAULT; -#endif - break; - } - - - default: { struct vm_ctrl * ctrl = get_ctrl(guest, ioctl); diff --git a/linux_module/palacios.h b/linux_module/palacios.h index 95f8d90..df9aabe 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -7,13 +7,6 @@ #include - - -#ifdef V3_CONFIG_HOST_DEVICE -#include "palacios-host-dev.h" -#endif - - /* Global Control IOCTLs */ #define V3_START_GUEST 10 #define V3_ADD_MEMORY 50 @@ -60,12 +53,6 @@ struct v3_guest { struct rb_root vm_ctrls; struct list_head exts; - -#ifdef V3_CONFIG_HOST_DEVICE - struct palacios_host_dev hostdev; -#endif - - struct completion start_done; struct completion thread_done; @@ -79,11 +66,6 @@ struct v3_guest { - - -extern void send_key_to_palacios(unsigned char status, unsigned char scan_code); - - int palacios_vmm_init( void ); int palacios_vmm_exit( void );