From: Patrick G. Bridges Date: Fri, 7 Oct 2011 15:06:15 +0000 (-0600) Subject: Merge branch 'devel' of ssh://newskysaw.cs.northwestern.edu/home/palacios/palacios... X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?p=palacios.git;a=commitdiff_plain;h=81361b1fc66eb2ca2e1eb80d3c3b98c6accde9d0;hp=1943835daca938e18862fd97fe80ad1a062a617c Merge branch 'devel' of ssh://newskysaw.cs.northwestern.edu/home/palacios/palacios into devel --- diff --git a/linux_module/main.c b/linux_module/main.c index 9317635..62a0fb5 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -61,7 +61,7 @@ static long v3_dev_ioctl(struct file * filp, switch (ioctl) { - case V3_START_GUEST:{ + case V3_CREATE_GUEST:{ int vm_minor = 0; struct v3_guest_img user_image; struct v3_guest * guest = kmalloc(sizeof(struct v3_guest), GFP_KERNEL); @@ -73,7 +73,7 @@ static long v3_dev_ioctl(struct file * filp, memset(guest, 0, sizeof(struct v3_guest)); - printk("Palacios: Starting V3 Guest...\n"); + printk("Palacios: Creating V3 Guest...\n"); vm_minor = register_vm(guest); @@ -106,32 +106,23 @@ static long v3_dev_ioctl(struct file * filp, strncpy(guest->name, user_image.name, 127); - printk("Palacios: Launching VM\n"); - INIT_LIST_HEAD(&(guest->exts)); - if (start_palacios_vm(guest) == -1) { - printk("Palacios: Error starting guest\n"); + if (create_palacios_vm(guest) == -1) { + printk("Palacios: Error creating guest\n"); return -EFAULT; } - return guest->vm_dev; + return vm_minor; break; } - case V3_STOP_GUEST: { + case V3_FREE_GUEST: { unsigned long vm_idx = arg; struct v3_guest * guest = guest_map[vm_idx]; - printk("Stopping VM idx=%d\n", vm_idx); - printk("Stopping VM (%s) (%p)\n", guest->name, guest); - - - if (irqs_disabled()) { - printk("WHAT!!?? IRQs are disabled??\n"); - break; - } + printk("Freeing VM (%s) (%p)\n", guest->name, guest); - stop_palacios_vm(guest); + free_palacios_vm(guest); guest_map[vm_idx] = NULL; break; } diff --git a/linux_module/palacios.h b/linux_module/palacios.h index 1ac8c03..5eca55d 100644 --- a/linux_module/palacios.h +++ b/linux_module/palacios.h @@ -8,8 +8,6 @@ /* Global Control IOCTLs */ -#define V3_START_GUEST 10 -#define V3_STOP_GUEST 11 #define V3_CREATE_GUEST 12 #define V3_FREE_GUEST 13 diff --git a/linux_module/vm.c b/linux_module/vm.c index abb798f..9869334 100644 --- a/linux_module/vm.c +++ b/linux_module/vm.c @@ -127,6 +127,27 @@ static long v3_vm_ioctl(struct file * filp, printk("V3 IOCTL %d\n", ioctl); switch (ioctl) { + case V3_VM_LAUNCH: { + printk("palacios: launching vm\n"); + + if (v3_start_vm(guest->v3_ctx, 0xfffffffe) < 0) { + printk("palacios: launch of vm failed\n"); + return -1; + } + + break; + } + case V3_VM_STOP: { + printk("Stopping VM (%s) (%p)\n", guest->name, guest); + + if (irqs_disabled()) { + printk("WHAT!!?? IRQs are disabled??\n"); + break; + } + + v3_stop_vm(guest->v3_ctx); + break; + } case V3_VM_PAUSE: { printk("Pausing VM (%s)\n", guest->name); v3_pause_vm(guest->v3_ctx); @@ -246,7 +267,7 @@ extern u32 pg_frees; extern u32 mallocs; extern u32 frees; -int start_palacios_vm(struct v3_guest * guest) { +int create_palacios_vm(struct v3_guest * guest) { int err; init_vm_extensions(guest); @@ -283,17 +304,7 @@ int start_palacios_vm(struct v3_guest * guest) { return -1; } - 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; - } - - printk("palacios: vm completed. returning.\n"); + printk("palacios: vm created at /dev/v3-vm%d\n", MINOR(guest->vm_dev)); return 0; } @@ -301,11 +312,8 @@ int start_palacios_vm(struct v3_guest * guest) { -int stop_palacios_vm(struct v3_guest * guest) { - - - v3_stop_vm(guest->v3_ctx); +int free_palacios_vm(struct v3_guest * guest) { v3_free_vm(guest->v3_ctx); diff --git a/linux_module/vm.h b/linux_module/vm.h index f8df6c7..53af2af 100644 --- a/linux_module/vm.h +++ b/linux_module/vm.h @@ -8,8 +8,8 @@ #include "palacios.h" -int start_palacios_vm(struct v3_guest * guest); -int stop_palacios_vm(struct v3_guest * guest); +int create_palacios_vm(struct v3_guest * guest); +int free_palacios_vm(struct v3_guest * guest); int add_guest_ctrl(struct v3_guest * guest, unsigned int cmd, diff --git a/linux_usr/Makefile b/linux_usr/Makefile index c36a212..5bdf906 100644 --- a/linux_usr/Makefile +++ b/linux_usr/Makefile @@ -2,13 +2,14 @@ all: v3_ctrl v3_stop v3_cons v3_mem v3_monitor v3_stream v3_user_host_dev_exampl -v3_ctrl : v3_ctrl.c v3_pause.c v3_continue.c v3_ctrl.h - gcc -static v3_ctrl.c -o v3_ctrl +v3_ctrl : v3_ctrl.c v3_pause.c v3_continue.c v3_launch.c v3_stop.c v3_create.c v3_free.c + gcc -static v3_launch.c -o v3_launch + gcc -static v3_stop.c -o v3_stop gcc -static v3_pause.c -o v3_pause gcc -static v3_continue.c -o v3_continue + gcc -static v3_create.c -o v3_create + gcc -static v3_free.c -o v3_free -v3_stop : v3_stop.c v3_ctrl.h - gcc -static v3_stop.c -o v3_stop v3_save : v3_save.c v3_ctrl.h gcc -static v3_save.c -o v3_save @@ -19,8 +20,8 @@ v3_mem : v3_mem.c v3_ctrl.h gcc -static v3_mem.c -o v3_mem v3_cons : v3_cons.c v3_cons_sc.c v3_ctrl.h - gcc v3_cons.c -o v3_cons -lcurses - gcc v3_cons_sc.c -o v3_cons_sc -lcurses + gcc -static v3_cons.c -o v3_cons -lcurses + gcc -static v3_cons_sc.c -o v3_cons_sc -lcurses v3_stream : v3_stream.c v3_ctrl.h gcc -static v3_stream.c -o v3_stream diff --git a/linux_usr/v3_create.c b/linux_usr/v3_create.c new file mode 100644 index 0000000..a73297f --- /dev/null +++ b/linux_usr/v3_create.c @@ -0,0 +1,113 @@ +/* + * V3 Control utility + * (c) Jack lange, 2010 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v3_ctrl.h" + +int read_file(int fd, int size, unsigned char * buf); + +int main(int argc, char* argv[]) { + char * filename = argv[1]; + char * name = argv[2]; + int guest_fd = 0; + int v3_fd = 0; + struct v3_guest_img guest_img; + struct stat guest_stats; + int dev_idx = 0; + + memset(&guest_img, 0, sizeof(struct v3_guest_img)); + + if (argc <= 2) { + printf("Usage: ./v3_ctrl \n"); + return -1; + } + + printf("Launching guest: %s\n", filename); + + guest_fd = open(filename, O_RDONLY); + + if (guest_fd == -1) { + printf("Error Opening guest image: %s\n", filename); + return -1; + } + + if (fstat(guest_fd, &guest_stats) == -1) { + printf("ERROR: Could not stat guest image file -- %s\n", filename); + return -1; + } + + + guest_img.size = guest_stats.st_size; + + // load guest image into user memory + guest_img.guest_data = malloc(guest_img.size); + + read_file(guest_fd, guest_img.size, guest_img.guest_data); + + close(guest_fd); + + printf("Loaded guest image. Launching to V3Vee\n"); + + strncpy(guest_img.name, name, 127); + + + v3_fd = open(v3_dev, O_RDONLY); + + if (v3_fd == -1) { + printf("Error opening V3Vee control device\n"); + return -1; + } + + dev_idx = ioctl(v3_fd, V3_CREATE_GUEST, &guest_img); + + + if (dev_idx < 0) { + printf("Error (%d) creating VM\n", dev_idx); + return -1; + } + + printf("VM (%s) created at /dev/v3-vm%d\n", name, dev_idx); + + /* Close the file descriptor. */ + close(v3_fd); + + + + return 0; +} + + + +int read_file(int fd, int size, unsigned char * buf) { + int left_to_read = size; + int have_read = 0; + + while (left_to_read != 0) { + int bytes_read = read(fd, buf + have_read, left_to_read); + + if (bytes_read <= 0) { + break; + } + + have_read += bytes_read; + left_to_read -= bytes_read; + } + + if (left_to_read != 0) { + printf("Error could not finish reading file\n"); + return -1; + } + + return 0; +} diff --git a/linux_usr/v3_ctrl.h b/linux_usr/v3_ctrl.h index 0826825..442c2d9 100644 --- a/linux_usr/v3_ctrl.h +++ b/linux_usr/v3_ctrl.h @@ -6,8 +6,6 @@ #ifndef _v3_ctrl_h #define _v3_ctrl_h -#define V3_START_GUEST 10 -#define V3_STOP_GUEST 11 #define V3_CREATE_GUEST 12 #define V3_FREE_GUEST 13 diff --git a/linux_usr/v3_free.c b/linux_usr/v3_free.c new file mode 100644 index 0000000..8e3c41f --- /dev/null +++ b/linux_usr/v3_free.c @@ -0,0 +1,52 @@ +/* + * V3 Control utility + * (c) Jack lange, 2011 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v3_ctrl.h" + +int main(int argc, char* argv[]) { + int vm_fd = 0; + unsigned long vm_idx = 0; + + + if (argc <= 1) { + printf("Usage: ./v3_free \n"); + return -1; + } + + + vm_idx = atoi(argv[1]); + + printf("Freeing VM %d\n", vm_idx); + + vm_fd = open("/dev/v3vee", O_RDONLY); + + if (vm_fd == -1) { + printf("Error opening V3Vee VM device\n"); + return -1; + } + + ioctl(vm_fd, V3_FREE_GUEST, vm_idx); + + + + /* Close the file descriptor. */ + close(vm_fd); + + + + return 0; +} + + diff --git a/linux_usr/v3_launch.c b/linux_usr/v3_launch.c new file mode 100644 index 0000000..6eb4dde --- /dev/null +++ b/linux_usr/v3_launch.c @@ -0,0 +1,48 @@ +/* + * V3 Control utility + * (c) Jack lange, 2010 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "v3_ctrl.h" + +int main(int argc, char* argv[]) { + int vm_fd = 0; + char * filename = argv[1]; + + if (argc <= 1) { + printf("Usage: ./v3_launch \n"); + return -1; + } + + printf("Launching VM (%s)\n", filename); + + vm_fd = open(filename, O_RDONLY); + + if (vm_fd == -1) { + printf("Error opening V3Vee VM device\n"); + return -1; + } + + ioctl(vm_fd, V3_VM_LAUNCH, NULL); + + + + /* Close the file descriptor. */ + close(vm_fd); + + + + return 0; +} + + diff --git a/linux_usr/v3_stop.c b/linux_usr/v3_stop.c index 061cd28..a5f3249 100644 --- a/linux_usr/v3_stop.c +++ b/linux_usr/v3_stop.c @@ -15,31 +15,25 @@ #include "v3_ctrl.h" -int read_file(int fd, int size, unsigned char * buf); - int main(int argc, char* argv[]) { int vm_fd = 0; - unsigned long vm_idx = 0; - + char * filename = argv[1]; if (argc <= 1) { - printf("Usage: ./v3_stop \n"); + printf("Usage: ./v3_stop \n"); return -1; } - - vm_idx = atoi(argv[1]); - - printf("Stopping VM\n"); + printf("Stopping VM (%s)\n", filename); - vm_fd = open("/dev/v3vee", O_RDONLY); + vm_fd = open(filename, O_RDONLY); if (vm_fd == -1) { printf("Error opening V3Vee VM device\n"); return -1; } - ioctl(vm_fd, V3_STOP_GUEST, vm_idx); + ioctl(vm_fd, V3_VM_STOP, NULL); diff --git a/palacios/src/palacios/vmcs.c b/palacios/src/palacios/vmcs.c index 2d36a3f..1de8e6a 100644 --- a/palacios/src/palacios/vmcs.c +++ b/palacios/src/palacios/vmcs.c @@ -277,8 +277,12 @@ int v3_vmx_restore_vmcs(struct guest_info * info) { int v3_update_vmcs_host_state(struct guest_info * info) { int vmx_ret = 0; addr_t tmp; - struct vmx_data * arch_data = (struct vmx_data *)(info->vmm_data); struct v3_msr tmp_msr; + addr_t gdtr_base; + struct { + uint16_t selector; + addr_t base; + } __attribute__((packed)) tmp_seg; #ifdef __V3_64BIT__ __asm__ __volatile__ ( "movq %%cr0, %0; " @@ -322,12 +326,48 @@ int v3_update_vmcs_host_state(struct guest_info * info) { vmx_ret |= check_vmcs_write(VMCS_HOST_CR4, tmp); + __asm__ __volatile__( + "sgdt (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + gdtr_base = tmp_seg.base; + vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, tmp_seg.base); + + __asm__ __volatile__( + "sidt (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, tmp_seg.base); + + __asm__ __volatile__( + "str (%0);" + : + : "q"(&tmp_seg) + : "memory" + ); + vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, tmp_seg.selector); + + /* The GDTR *index* is bits 3-15 of the selector. */ + { + struct tss_descriptor * desc = NULL; + desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3))); + + tmp_seg.base = ((desc->base1) | + (desc->base2 << 16) | + (desc->base3 << 24) | +#ifdef __V3_64BIT__ + ((uint64_t)desc->base4 << 32) +#else + (0) +#endif + ); - vmx_ret |= check_vmcs_write(VMCS_HOST_GDTR_BASE, arch_data->host_state.gdtr.base); - vmx_ret |= check_vmcs_write(VMCS_HOST_IDTR_BASE, arch_data->host_state.idtr.base); - vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, arch_data->host_state.tr.base); - - + vmx_ret |= check_vmcs_write(VMCS_HOST_TR_BASE, tmp_seg.base); + } #ifdef __V3_64BIT__ @@ -408,8 +448,6 @@ int v3_update_vmcs_host_state(struct guest_info * info) { #endif vmx_ret |= check_vmcs_write(VMCS_HOST_GS_SELECTOR, tmp); - vmx_ret |= check_vmcs_write(VMCS_HOST_TR_SELECTOR, arch_data->host_state.tr.selector); - #define SYSENTER_CS_MSR 0x00000174 #define SYSENTER_ESP_MSR 0x00000175 diff --git a/palacios/src/palacios/vmm.c b/palacios/src/palacios/vmm.c index 87746ef..341996a 100644 --- a/palacios/src/palacios/vmm.c +++ b/palacios/src/palacios/vmm.c @@ -414,13 +414,9 @@ int v3_move_vm_core(struct v3_vm_info * vm, int vcore_id, int target_cpu) { */ core->pcpu_id = target_cpu; - V3_Print("core now at %d\n", core->pcpu_id); - + V3_Print("core now at %d\n", core->pcpu_id); } - - - v3_lower_barrier(vm); return 0; diff --git a/palacios/src/palacios/vmx.c b/palacios/src/palacios/vmx.c index 1b286ae..bdfc8c0 100644 --- a/palacios/src/palacios/vmx.c +++ b/palacios/src/palacios/vmx.c @@ -136,53 +136,6 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) /******* Setup Host State **********/ /* Cache GDTR, IDTR, and TR in host struct */ - addr_t gdtr_base; - struct { - uint16_t selector; - addr_t base; - } __attribute__((packed)) tmp_seg; - - - __asm__ __volatile__( - "sgdt (%0);" - : - : "q"(&tmp_seg) - : "memory" - ); - gdtr_base = tmp_seg.base; - vmx_state->host_state.gdtr.base = gdtr_base; - - __asm__ __volatile__( - "sidt (%0);" - : - : "q"(&tmp_seg) - : "memory" - ); - vmx_state->host_state.idtr.base = tmp_seg.base; - - __asm__ __volatile__( - "str (%0);" - : - : "q"(&tmp_seg) - : "memory" - ); - vmx_state->host_state.tr.selector = tmp_seg.selector; - - /* The GDTR *index* is bits 3-15 of the selector. */ - struct tss_descriptor * desc = NULL; - desc = (struct tss_descriptor *)(gdtr_base + (8 * (tmp_seg.selector >> 3))); - - tmp_seg.base = ((desc->base1) | - (desc->base2 << 16) | - (desc->base3 << 24) | -#ifdef __V3_64BIT__ - ((uint64_t)desc->base4 << 32) -#else - (0) -#endif - ); - - vmx_state->host_state.tr.base = tmp_seg.base; /********** Setup VMX Control Fields ***********/ @@ -213,10 +166,6 @@ static int init_vmcs_bios(struct guest_info * core, struct vmx_data * vmx_state) - - - - #ifdef __V3_64BIT__ // Ensure host runs in 64-bit mode at each VM EXIT vmx_state->exit_ctrls.host_64_on = 1;