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");
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,
#define V3_VM_MOVE_MEM 36
+#define V3_VM_RESET 40
+
#define V3_VM_FB_INPUT 257
#define V3_VM_FB_QUERY 258
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... */
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
v3_create_bind \
v3_free \
v3_launch \
+ v3_reset \
v3_stop \
v3_pause \
v3_continue \
#define V3_VM_MOVE_MEM 36
+#define V3_VM_RESET 40
+
#define V3_VM_FB_INPUT 257
#define V3_VM_FB_QUERY 258
#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 {
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;
}
--- /dev/null
+/*
+ * 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;
+}
+
+