From: Peter Dinda Date: Thu, 18 Jun 2015 22:33:54 +0000 (-0500) Subject: Expose VM reset capability to Linux and Linux user X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=ccbe7e2ab17a32e671114f258abc1d047151be2e Expose VM reset capability to Linux and Linux user --- diff --git a/linux_module/main.c b/linux_module/main.c index 38a2fd4..2199d88 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -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, diff --git a/linux_module/palacios.h b/linux_module/palacios.h index 4c8cf62..63d948f 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -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... */ diff --git a/linux_module/vm.c b/linux_module/vm.c index d352c36..440ff69 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -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 diff --git a/linux_usr/Makefile b/linux_usr/Makefile index f10734c..db476d8 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -16,6 +16,7 @@ BASE_EXECS = v3_mem \ v3_create_bind \ v3_free \ v3_launch \ + v3_reset \ v3_stop \ v3_pause \ v3_continue \ diff --git a/linux_usr/v3_ctrl.h b/linux_usr/v3_ctrl.h index 8b448bc..6e15d4c 100644 --- a/linux_usr/v3_ctrl.h +++ b/linux_usr/v3_ctrl.h @@ -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 { diff --git a/linux_usr/v3_free.c b/linux_usr/v3_free.c index 293befa..1299269 100644 --- a/linux_usr/v3_free.c +++ b/linux_usr/v3_free.c @@ -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 index 0000000..7335b78 --- /dev/null +++ b/linux_usr/v3_reset.c @@ -0,0 +1,87 @@ +/* + * V3 VM reset + * (c) Peter Dinda 2015 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v3_ctrl.h" + +void usage() +{ + printf("usage: v3_reset 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; +} + +