X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fmain.c;h=098d8f13b07d61a9e1c19621f629a1a5e0890300;hb=ffd6d915b585a4a17a2d5b081313f0968885a105;hp=b7fecea7324436fe15316de83d178cb62b462990;hpb=a3534432fa8e7a9fe4730c151ca52350ca0a2faf;p=palacios.releases.git diff --git a/linux_module/main.c b/linux_module/main.c index b7fecea..098d8f1 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -21,6 +21,8 @@ #include +#include + #include "palacios.h" #include "mm.h" #include "vm.h" @@ -44,7 +46,7 @@ int mod_frees = 0; static int v3_major_num = 0; static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0}; -static struct proc_dir_entry *dir; +static struct proc_dir_entry *dir = 0; struct class * v3_class = NULL; static struct cdev ctrl_dev; @@ -74,7 +76,7 @@ static long v3_dev_ioctl(struct file * filp, 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); + struct v3_guest * guest = palacios_alloc(sizeof(struct v3_guest)); if (IS_ERR(guest)) { ERROR("Palacios: Error allocating Kernel guest_image\n"); @@ -89,14 +91,14 @@ static long v3_dev_ioctl(struct file * filp, if (vm_minor == -1) { ERROR("Palacios Error: Too many VMs are currently running\n"); - return -EFAULT; + goto out_err; } guest->vm_dev = MKDEV(v3_major_num, vm_minor); if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) { ERROR("Palacios Error: copy from user error getting guest image...\n"); - return -EFAULT; + goto out_err1; } guest->img_size = user_image.size; @@ -106,12 +108,12 @@ static long v3_dev_ioctl(struct file * filp, if (IS_ERR(guest->img)) { ERROR("Palacios Error: Could not allocate space for guest image\n"); - return -EFAULT; + goto out_err1; } if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) { ERROR("Palacios: Error loading guest data\n"); - return -EFAULT; + goto out_err2; } strncpy(guest->name, user_image.name, 127); @@ -120,16 +122,32 @@ static long v3_dev_ioctl(struct file * filp, if (create_palacios_vm(guest) == -1) { ERROR("Palacios: Error creating guest\n"); - return -EFAULT; + goto out_err2; } return vm_minor; + + +out_err2: + vfree(guest->img); +out_err1: + guest_map[vm_minor] = NULL; +out_err: + palacios_free(guest); + + return -1; + break; } case V3_FREE_GUEST: { unsigned long vm_idx = arg; struct v3_guest * guest = guest_map[vm_idx]; + if (!guest) { + ERROR("No VM at index %ld\n",vm_idx); + return -1; + } + INFO("Freeing VM (%s) (%p)\n", guest->name, guest); free_palacios_vm(guest); @@ -156,9 +174,18 @@ static long v3_dev_ioctl(struct file * filp, break; } - default: - ERROR("\tUnhandled\n"); + + default: { + struct global_ctrl * ctrl = get_global_ctrl(ioctl); + + if (ctrl) { + return ctrl->handler(ioctl, arg); + } + + WARNING("\tUnhandled global ctrl cmd: %d\n", ioctl); + return -EINVAL; + } } return 0; @@ -174,6 +201,11 @@ static struct file_operations v3_ctrl_fops = { +struct proc_dir_entry *palacios_get_procdir(void) +{ + return dir; +} + static int read_guests(char * buf, char ** start, off_t off, int count, int * eof, void * data) { @@ -295,13 +327,25 @@ static void __exit v3_exit(void) { extern u32 pg_frees; extern u32 mallocs; extern u32 frees; + int i = 0; + struct v3_guest * guest; + dev_t dev; - // should probably try to stop any guests + /* Stop and free any running VMs */ + for (i = 0; i < MAX_VMS; i++) { + if (guest_map[i] != NULL) { + guest = (struct v3_guest *)guest_map[i]; + if (v3_stop_vm(guest->v3_ctx) < 0) + ERROR("Couldn't stop VM %d\n", i); + free_palacios_vm(guest); + guest_map[i] = NULL; + } + } - dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1); + dev = MKDEV(v3_major_num, MAX_VMS + 1); INFO("Removing V3 Control device\n");