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.


Expose VM reset capability to Linux and Linux user
Peter Dinda [Thu, 18 Jun 2015 22:33:54 +0000 (17:33 -0500)]
linux_module/main.c
linux_module/palacios.h
linux_module/vm.c
linux_usr/Makefile
linux_usr/v3_ctrl.h
linux_usr/v3_free.c
linux_usr/v3_reset.c [new file with mode: 0644]

index 38a2fd4..2199d88 100644 (file)
@@ -326,7 +326,8 @@ static int read_guests_details(struct seq_file *s, void *v)
                           base->state==V3_VM_STOPPED ? "stopped" :
                           base->state==V3_VM_PAUSED ? "paused" :
                           base->state==V3_VM_ERROR ? "ERROR" :
-                          base->state==V3_VM_SIMULATING ? "simulating" : "UNKNOWN",
+                          base->state==V3_VM_SIMULATING ? "simulating" : 
+                          base->state==V3_VM_RESETTING ? "resetting"  : "UNKNOWN",
                           core->num_vcores,
                           mem->num_regions);
                seq_printf(s, "Core States\n");
@@ -337,7 +338,8 @@ static int read_guests_details(struct seq_file *s, void *v)
                               j, 
                               core->vcore[j].state==V3_VCORE_INVALID ? "INVALID" :
                               core->vcore[j].state==V3_VCORE_RUNNING ? "running" :
-                              core->vcore[j].state==V3_VCORE_STOPPED ? "stopped" : "UNKNOWN",
+                              core->vcore[j].state==V3_VCORE_STOPPED ? "stopped" :
+                              core->vcore[j].state==V3_VCORE_RESETTING ? "resetting" : "UNKNOWN",
                               core->vcore[j].pcore,
                               core->vcore[j].num_exits,
                               core->vcore[j].last_rip,
index 4c8cf62..63d948f 100644 (file)
@@ -44,6 +44,8 @@
 
 #define V3_VM_MOVE_MEM 36
 
+#define V3_VM_RESET    40
+
 #define V3_VM_FB_INPUT 257
 #define V3_VM_FB_QUERY 258
 
@@ -90,6 +92,16 @@ struct v3_mem_move_cmd{
     unsigned short     pcore_id;
 } __attribute__((packed));
 
+struct v3_reset_cmd {
+#define V3_RESET_VM_ALL    0
+#define V3_RESET_VM_HRT    1
+#define V3_RESET_VM_ROS    2
+#define V3_RESET_VM_CORE_RANGE  3
+    unsigned int type;
+    unsigned int first_core;  // for CORE_RANGE
+    unsigned int num_cores;   // for CORE_RANGE
+} __attribute__((packed));
+    
 struct v3_chkpt_info {
     char store[128];
     char url[256]; /* This might need to be bigger... */
index d352c36..440ff69 100644 (file)
@@ -195,6 +195,38 @@ static long v3_vm_ioctl(struct file * filp,
            v3_simulate_vm(guest->v3_ctx, arg);
            break;
        }
+       case V3_VM_RESET: {
+           struct v3_reset_cmd r;
+           void __user * argp = (void __user *)arg;
+           v3_vm_reset_type t;
+           uint32_t core_range[2];
+
+           if (copy_from_user(&r, argp, sizeof(struct v3_reset_cmd))) {
+               WARNING("Copy from user error getting reset info\n");
+               return -EFAULT;
+           }
+           
+           if (r.type==V3_RESET_VM_ALL) { 
+               t=V3_VM_RESET_ALL;
+           } else if (r.type==V3_RESET_VM_HRT) {
+               t=V3_VM_RESET_HRT;
+           } else if (r.type==V3_RESET_VM_ROS) {
+               t=V3_VM_RESET_ROS;
+           } else if (r.type==V3_RESET_VM_CORE_RANGE){
+               t=V3_VM_RESET_CORE_RANGE;
+               core_range[0]=r.first_core;
+               core_range[1]=r.first_core+r.num_cores-1;
+           } else {
+               ERROR("Unknown reset type %d requested\n",r.type);
+               return -EFAULT;
+           }
+           
+           if (v3_reset_vm_extended(guest->v3_ctx, t, core_range) == -1) {
+               WARNING("Error reseting VM\n");
+               return -EFAULT;
+           }
+           break;
+       }
 
 
 #ifdef V3_CONFIG_CHECKPOINT
index f10734c..db476d8 100644 (file)
@@ -16,6 +16,7 @@ BASE_EXECS =  v3_mem \
                 v3_create_bind \
                v3_free  \
                v3_launch \
+               v3_reset  \
                v3_stop   \
                v3_pause  \
                v3_continue \
index 8b448bc..6e15d4c 100644 (file)
@@ -47,6 +47,8 @@
 
 #define V3_VM_MOVE_MEM 36
 
+#define V3_VM_RESET 40
+
 #define V3_VM_FB_INPUT 257
 #define V3_VM_FB_QUERY 258
 
@@ -103,6 +105,15 @@ struct v3_chkpt_info {
 #define V3_CHKPT_OPT_SKIP_ARCHDEP 8  // don't write core arch dep data to store
 } __attribute__((packed));
 
+struct v3_reset_cmd {
+#define V3_RESET_VM_ALL    0
+#define V3_RESET_VM_HRT    1
+#define V3_RESET_VM_ROS    2
+#define V3_RESET_VM_CORE_RANGE  3
+    unsigned int type;
+    unsigned int first_core;  // for CORE_RANGE
+    unsigned int num_cores;   // for CORE_RANGE
+} __attribute__((packed));
 
 
 struct v3_hw_pci_dev {
index 293befa..1299269 100644 (file)
@@ -25,7 +25,7 @@ int main(int argc, char* argv[]) {
 
     printf("Freeing VM %d\n", vm_idx);
     
-    if (v3_dev_ioctl(V3_FREE_GUEST, vm_idx) < 0) {
+    if (v3_dev_ioctl(V3_FREE_GUEST, (void*)vm_idx) < 0) {
         fprintf(stderr, "Error freeing VM %d (%s)\n", vm_idx,argv[1]);
         return -1;
     }
diff --git a/linux_usr/v3_reset.c b/linux_usr/v3_reset.c
new file mode 100644 (file)
index 0000000..7335b78
--- /dev/null
@@ -0,0 +1,87 @@
+/* 
+ * V3 VM reset
+ * (c) Peter Dinda 2015
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h> 
+#include <errno.h>
+#include <assert.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include "v3_ctrl.h"
+
+void usage()
+{
+    printf("usage: v3_reset <vm_device> all|hrt|ros|range [first_core num_cores]\n\n");
+    printf("Resets the VM or a part of it.\n");
+    printf("  all   : full reset of entire VM\n");
+    printf("  hrt   : reset of all HRT cores for an HVM VM\n");
+    printf("  ros   : reset of ROS cores for an HVM VM\n");
+    printf("  range : reset of cores first_core to first_core+num_cores-1\n\n");
+}
+
+int main(int argc, char* argv[]) {
+    int vm_fd;
+    char * vm_dev = NULL;
+    struct v3_reset_cmd cmd; 
+
+    if (argc < 3) {
+       usage();
+       return -1;
+    }
+
+    vm_dev = argv[1];
+
+    if (!strcasecmp(argv[2],"all")) { 
+       cmd.type=V3_RESET_VM_ALL;
+    } else if (!strcasecmp(argv[2],"hrt")) { 
+       cmd.type=V3_RESET_VM_HRT;
+    } else if (!strcasecmp(argv[2],"ros")) { 
+       cmd.type=V3_RESET_VM_ROS;
+    } else if (!strcasecmp(argv[2],"range")) { 
+       cmd.type=V3_RESET_VM_CORE_RANGE;
+       if (argc!=5) { 
+           usage();
+           return -1;
+       } else {
+           cmd.first_core = atoi(argv[3]);
+           cmd.num_cores = atoi(argv[4]);
+       }
+    }
+
+    printf("Doing VM reset:  %s ",
+          cmd.type==V3_RESET_VM_ALL ? "ALL" :
+          cmd.type==V3_RESET_VM_HRT ? "HRT" :
+          cmd.type==V3_RESET_VM_ROS ? "ROS" :
+          cmd.type==V3_RESET_VM_CORE_RANGE ? "RANGE" : "UNKNOWN");
+    if (cmd.type==V3_RESET_VM_CORE_RANGE) { 
+       printf("cores %u to %u\n", cmd.first_core, cmd.first_core+cmd.num_cores-1);
+    } else {
+       printf("\n");
+    }
+
+    vm_fd = open(vm_dev, O_RDONLY);
+
+    if (vm_fd == -1) {
+       printf("Error opening VM device: %s\n", vm_dev);
+       return -1;
+    }
+
+    int err = ioctl(vm_fd, V3_VM_RESET, &cmd); 
+
+    if (err < 0) {
+       printf("Error sending reset commad to vm\n");
+       return -1;
+    }
+
+    close(vm_fd); 
+
+    return 0; 
+}
+
+