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 dedicated debugging framework with associated interface
[palacios.git] / linux_module / vm.c
index f53a598..40cfa06 100644 (file)
 #include <linux/file.h>
 #include <linux/spinlock.h>
 #include <linux/rbtree.h>
+#include <linux/module.h>
 
 #include <palacios/vmm.h>
+#include <palacios/vmm_host_events.h>
 
 #include "palacios.h"
 #include "vm.h"
@@ -71,7 +73,7 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd,
     struct vm_ctrl * ctrl = kmalloc(sizeof(struct vm_ctrl), GFP_KERNEL);
 
     if (ctrl == NULL) {
-       printk("Error: Could not allocate vm ctrl %d\n", cmd);
+       WARNING("Error: Could not allocate vm ctrl %d\n", cmd);
        return -1;
     }
 
@@ -80,7 +82,7 @@ int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd,
     ctrl->priv_data = priv_data;
 
     if (__insert_ctrl(guest, ctrl) != NULL) {
-       printk("Could not insert guest ctrl %d\n", cmd);
+       WARNING("Could not insert guest ctrl %d\n", cmd);
        kfree(ctrl);
        return -1;
     }
@@ -124,25 +126,113 @@ static long v3_vm_ioctl(struct file * filp,
 
     struct v3_guest * guest = filp->private_data;
 
-    printk("V3 IOCTL %d\n", ioctl);
+    INFO("V3 IOCTL %d\n", ioctl);
 
     switch (ioctl) {
+       case V3_VM_LAUNCH: {
+           NOTICE("palacios: launching vm\n");
 
+           if (v3_start_vm(guest->v3_ctx, (0x1 << num_online_cpus()) - 1) < 0) { 
+               WARNING("palacios: launch of vm failed\n");
+               return -1;
+           }
+           
+           break;
+       }
        case V3_VM_STOP: {
-           printk("Stopping VM (%s)\n", guest->name);
-           stop_palacios_vm(guest);
+           NOTICE("Stopping VM (%s) (%p)\n", guest->name, guest);
+
+           if (irqs_disabled()) {
+               ERROR("WHAT!!?? IRQs are disabled??\n");
+               break;
+           }
+
+           v3_stop_vm(guest->v3_ctx);
            break;
        }
        case V3_VM_PAUSE: {
-           printk("Pausing VM (%s)\n", guest->name);
+           NOTICE("Pausing VM (%s)\n", guest->name);
            v3_pause_vm(guest->v3_ctx);
            break;
        }
        case V3_VM_CONTINUE: {
-           printk("Continuing VM (%s)\n", guest->name);
+           NOTICE("Continuing VM (%s)\n", guest->name);
            v3_continue_vm(guest->v3_ctx);
            break;
        }
+       case V3_VM_SIMULATE: {
+           NOTICE("Simulating VM (%s) for %lu msecs\n", guest->name, arg);
+           v3_simulate_vm(guest->v3_ctx, arg);
+           break;
+       }
+
+
+#ifdef V3_CONFIG_CHECKPOINT
+       case V3_VM_SAVE: {
+           struct v3_chkpt_info chkpt;
+           void __user * argp = (void __user *)arg;
+
+           memset(&chkpt, 0, sizeof(struct v3_chkpt_info));
+
+           if (copy_from_user(&chkpt, argp, sizeof(struct v3_chkpt_info))) {
+               WARNING("Copy from user error getting checkpoint info\n");
+               return -EFAULT;
+           }
+           
+           NOTICE("Saving Guest to %s:%s\n", chkpt.store, chkpt.url);
+
+           if (v3_save_vm(guest->v3_ctx, chkpt.store, chkpt.url) == -1) {
+               WARNING("Error checkpointing VM state\n");
+               return -EFAULT;
+           }
+           
+           break;
+       }
+       case V3_VM_LOAD: {
+           struct v3_chkpt_info chkpt;
+           void __user * argp = (void __user *)arg;
+
+           memset(&chkpt, 0, sizeof(struct v3_chkpt_info));
+
+           if (copy_from_user(&chkpt, argp, sizeof(struct v3_chkpt_info))) {
+               WARNING("Copy from user error getting checkpoint info\n");
+               return -EFAULT;
+           }
+           
+           NOTICE("Loading Guest to %s:%s\n", chkpt.store, chkpt.url);
+
+           if (v3_load_vm(guest->v3_ctx, chkpt.store, chkpt.url) == -1) {
+               WARNING("Error Loading VM state\n");
+               return -EFAULT;
+           }
+           
+           break;
+       }
+#endif
+       case V3_VM_DEBUG: {
+           struct v3_debug_cmd cmd;
+           struct v3_debug_event evt;
+           void __user * argp = (void __user *)arg;        
+
+           memset(&cmd, 0, sizeof(struct v3_debug_cmd));
+           
+           if (copy_from_user(&cmd, argp, sizeof(struct v3_debug_cmd))) {
+               printk("Error: Could not copy debug command from user space\n");
+               return -EFAULT;
+           }
+
+           evt.core_id = cmd.core;
+           evt.cmd = cmd.cmd;
+
+           printk("Debugging VM\n");
+
+           if (v3_deliver_debug_event(guest->v3_ctx, &evt) == -1) {
+               printk("Error could not deliver debug cmd\n");
+               return -EFAULT;
+           }
+
+           break;
+       }
        case V3_VM_MOVE_CORE: {
            struct v3_core_move_cmd cmd;
            void __user * argp = (void __user *)arg;
@@ -150,16 +240,16 @@ static long v3_vm_ioctl(struct file * filp,
            memset(&cmd, 0, sizeof(struct v3_core_move_cmd));
            
            if (copy_from_user(&cmd, argp, sizeof(struct v3_core_move_cmd))) {
-               printk("copy from user error getting migrate command...\n");
+               WARNING("copy from user error getting migrate command...\n");
                return -EFAULT;
            }
        
-           printk("moving guest %s vcore %d to CPU %d\n", guest->name, cmd.vcore_id, cmd.pcore_id);
+           INFO("moving guest %s vcore %d to CPU %d\n", guest->name, cmd.vcore_id, cmd.pcore_id);
 
            v3_move_vm_core(guest->v3_ctx, cmd.vcore_id, cmd.pcore_id);
-       }
-       break;
 
+           break;
+       }
        default: {
            struct vm_ctrl * ctrl = get_ctrl(guest, ioctl);
 
@@ -168,7 +258,7 @@ static long v3_vm_ioctl(struct file * filp,
            }
            
            
-           printk("\tUnhandled ctrl cmd: %d\n", ioctl);
+           WARNING("\tUnhandled ctrl cmd: %d\n", ioctl);
            return -EINVAL;
        }
     }
@@ -210,27 +300,20 @@ extern u32 pg_frees;
 extern u32 mallocs;
 extern u32 frees;
 
-int start_palacios_vm(void * arg)  {
-    struct v3_guest * guest = (struct v3_guest *)arg;
+int create_palacios_vm(struct v3_guest * guest)  {
     int err;
 
-
-    daemonize(guest->name);
-    // allow_signal(SIGKILL);
-
-    
     init_vm_extensions(guest);
 
     guest->v3_ctx = v3_create_vm(guest->img, (void *)guest, guest->name);
 
     if (guest->v3_ctx == NULL) { 
-       printk("palacios: failed to create vm\n");
-       complete(&(guest->start_done));
+       WARNING("palacios: failed to create vm\n");
        return -1;
     }
 
 
-    printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
+    NOTICE("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
 
     cdev_init(&(guest->cdev), &v3_vm_fops);
 
@@ -238,39 +321,23 @@ int start_palacios_vm(void * arg)  {
     guest->cdev.ops = &v3_vm_fops;
 
 
-    printk("Adding VM device\n");
+    INFO("Adding VM device\n");
     err = cdev_add(&(guest->cdev), guest->vm_dev, 1);
 
     if (err) {
-       printk("Fails to add cdev\n");
+       WARNING("Fails to add cdev\n");
        v3_free_vm(guest->v3_ctx);
-       complete(&(guest->start_done));
        return -1;
     }
 
     if (device_create(v3_class, NULL, guest->vm_dev, guest, "v3-vm%d", MINOR(guest->vm_dev)) == NULL){
-       printk("Fails to create device\n");
+       WARNING("Fails to create device\n");
        cdev_del(&(guest->cdev));
        v3_free_vm(guest->v3_ctx);
-       complete(&(guest->start_done));
        return -1;
     }
 
-    complete(&(guest->start_done));
-
-    printk("palacios: launching vm\n");
-
-    if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
-       printk("palacios: launch of vm failed\n");
-       device_destroy(v3_class, guest->vm_dev);
-       cdev_del(&(guest->cdev));
-       v3_free_vm(guest->v3_ctx);
-       return -1;
-    }
-    
-    complete(&(guest->thread_done));
-
-    printk("palacios: vm completed.  returning.\n");
+    NOTICE("palacios: vm created at /dev/v3-vm%d\n", MINOR(guest->vm_dev));
 
     return 0;
 }
@@ -278,14 +345,11 @@ int start_palacios_vm(void * arg)  {
 
 
 
-int stop_palacios_vm(struct v3_guest * guest) {
 
-    v3_stop_vm(guest->v3_ctx);
-
-    wait_for_completion(&(guest->thread_done));
+int free_palacios_vm(struct v3_guest * guest) {
 
     v3_free_vm(guest->v3_ctx);
-    
+
     device_destroy(v3_class, guest->vm_dev);
 
     cdev_del(&(guest->cdev));