Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


added initial extension framework
Jack Lange [Wed, 8 Jun 2011 17:53:44 +0000 (12:53 -0500)]
linux_module/Makefile
linux_module/ld.cmd
linux_module/linux-exts.c [new file with mode: 0644]
linux_module/linux-exts.h [new file with mode: 0644]
linux_module/palacios-vm.c
linux_module/palacios-vm.h
linux_module/palacios.h

index b3bd558..e3cb52a 100644 (file)
@@ -14,8 +14,9 @@ v3vee-objs :=         palacios.o \
                palacios-vm.o \
                palacios-mm.o \
                palacios-queue.o \
-               palacios-hashtable.o
-
+               palacios-hashtable.o \
+               linux-exts.o
+       
 ifdef V3_CONFIG_CONSOLE
        v3vee-objs +=   palacios-console.o
 endif
index 7dd7747..fd97c26 100644 (file)
@@ -22,5 +22,11 @@ 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
new file mode 100644 (file)
index 0000000..f4afafd
--- /dev/null
@@ -0,0 +1,62 @@
+
+#include "linux-exts.h"
+
+/* 
+ * 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 *))));
+
+
+
+
+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;
+    int i = 0;
+
+    while (tmp_ext != __stop__lnx_exts) {
+       printk("Registering Linux Extension (%s)\n", tmp_ext->name);
+       tmp_ext->init();
+
+       tmp_ext = &(__start__lnx_exts[++i]);
+    }
+    
+    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;
+    int i = 0;
+
+    while (tmp_ext != __stop__lnx_exts) {
+       printk("Registering Linux Extension (%s)\n", tmp_ext->name);
+       tmp_ext->init();
+
+       tmp_ext = &(__start__lnx_exts[++i]);
+    }
+    
+    return 0;
+}
+
+
+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;
+    int i = 0;
+
+    while (tmp_ext != __stop__lnx_exts) {
+       printk("Cleaning up Linux Extension (%s)\n", tmp_ext->name);
+       tmp_ext->deinit();
+
+       tmp_ext = &(__start__lnx_exts[++i]);
+    }
+    
+    return 0;
+}
diff --git a/linux_module/linux-exts.h b/linux_module/linux-exts.h
new file mode 100644 (file)
index 0000000..72e4800
--- /dev/null
@@ -0,0 +1,29 @@
+#include "palacios.h"
+
+
+int add_mod_cmd(struct v3_guest * guest, unsigned int cmd, 
+               int (*handler)(struct v3_guest * guest, 
+                              unsigned int cmd, unsigned long arg));
+
+
+struct linux_ext {
+    char * name;
+    int (*init)( void );
+    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));
+
+
+
+int init_lnx_extensions( void );
+int deinit_lnx_extensions( void );
+
+
+
+#define register_extension(ext)                                        \
+    static struct linux_ext * _lnx_ext                         \
+    __attribute__((used))                                      \
+       __attribute__((unused, __section("_lnx_exts"),  \
+                      aligned(sizeof(void *))))                \
+       = ext;
index dd422c3..a434f17 100644 (file)
 #include <linux/smp_lock.h>
 #include <linux/file.h>
 #include <linux/spinlock.h>
-
+#include <linux/rbtree.h>
 
 #include <palacios/vmm.h>
 
 #include "palacios.h"
 #include "palacios-vm.h"
 
+
+struct vm_ctrl {
+    unsigned int cmd;
+
+    int (*handler)(struct v3_guest * guest, 
+                  unsigned int cmd, unsigned long arg, 
+                  void * priv_data);
+
+    void * priv_data;
+
+    struct rb_node tree_node;
+};
+
+
+static inline struct vm_ctrl * __insert_ctrl(struct v3_guest * vm, 
+                                            struct vm_ctrl * ctrl) {
+    struct rb_node ** p = &(vm->vm_ctrls.rb_node);
+    struct rb_node * parent = NULL;
+    struct vm_ctrl * tmp_ctrl = NULL;
+
+    while (*p) {
+       parent = *p;
+       tmp_ctrl = rb_entry(parent, struct vm_ctrl, tree_node);
+
+       if (ctrl->cmd < tmp_ctrl->cmd) {
+           p = &(*p)->rb_left;
+       } else if (ctrl->cmd > tmp_ctrl->cmd) {
+           p = &(*p)->rb_right;
+       } else {
+           return tmp_ctrl;
+       }
+    }
+
+    rb_link_node(&(ctrl->tree_node), parent, p);
+
+    return NULL;
+}
+
+
+
+int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, 
+                  int (*handler)(struct v3_guest * guest, 
+                                 unsigned int cmd, unsigned long arg, 
+                                 void * priv_data),
+                  void * priv_data) {
+    struct vm_ctrl * ctrl = kmalloc(sizeof(struct vm_ctrl), GFP_KERNEL);
+
+    if (ctrl == NULL) {
+       printk("Error: Could not allocate vm ctrl %d\n", cmd);
+       return -1;
+    }
+
+    ctrl->cmd = cmd;
+    ctrl->handler = handler;
+    ctrl->priv_data = priv_data;
+
+    if (__insert_ctrl(guest, ctrl) != NULL) {
+       printk("Could not insert guest ctrl %d\n", cmd);
+       kfree(ctrl);
+       return -1;
+    }
+    
+    rb_insert_color(&(ctrl->tree_node), &(guest->vm_ctrls));
+
+    return 0;
+}
+
+
+static struct vm_ctrl * get_ctrl(struct v3_guest * guest, unsigned int cmd) {
+    struct rb_node * n = guest->vm_ctrls.rb_node;
+    struct vm_ctrl * ctrl = NULL;
+
+    while (n) {
+       ctrl = rb_entry(n, struct vm_ctrl, tree_node);
+
+       if (cmd < ctrl->cmd) {
+           n = n->rb_left;
+       } else if (cmd > ctrl->cmd) {
+           n = n->rb_right;
+       } else {
+           return ctrl;
+       }
+    }
+
+    return NULL;
+}
+
+
 #ifdef V3_CONFIG_STREAM
 #include "palacios-stream.h"
 #endif
@@ -123,9 +211,17 @@ static long v3_vm_ioctl(struct file * filp,
            break;
 
 
-       default: 
-           printk("\tUnhandled\n");
+       default: {
+           struct vm_ctrl * ctrl = get_ctrl(guest, ioctl);
+
+           if (ctrl) {
+               return ctrl->handler(guest, ioctl, arg, ctrl->priv_data);
+           }
+           
+           
+           printk("\tUnhandled ctrl cmd: %d\n", ioctl);
            return -EINVAL;
+       }
     }
 
     return 0;
@@ -184,6 +280,11 @@ int start_palacios_vm(void * arg)  {
        return -1;
     }
 
+    // init linux extensions
+#ifdef V3_CONFIG_EXT_INSPECTOR
+    inspect_vm(guest);
+#endif
+
     printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
 
     cdev_init(&(guest->cdev), &v3_vm_fops);
@@ -215,9 +316,7 @@ int start_palacios_vm(void * arg)  {
     printk("palacios: launching vm\n");
 
 
-#ifdef V3_CONFIG_EXT_INSPECTOR
-    inspect_vm(guest);
-#endif
+
 
 
     if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
index e0c5f74..3423d34 100644 (file)
 int start_palacios_vm(void * arg);
 int stop_palacios_vm(struct v3_guest * guest);
 
+
+int add_guest_ctrl(struct v3_guest * guest,  unsigned int cmd, 
+                 int (*handler)(struct v3_guest * guest, 
+                                unsigned int cmd, unsigned long arg,
+                                void * priv_data),
+                 void * priv_data);
+
+
+
 #endif
index 9fe9c29..8923361 100644 (file)
@@ -64,6 +64,10 @@ struct v3_guest {
 
     char name[128];
 
+
+    struct rb_root vm_ctrls;
+
+
     struct list_head files;
     struct list_head streams;
     struct list_head sockets;