X-Git-Url: http://v3vee.org/palacios/gitweb/gitweb.cgi?a=blobdiff_plain;f=linux_module%2Fmain.c;h=57fe2ef219d8c3758c3d2a67e100d6416b734343;hb=18004a8cb830010315b412162da2d92b95a960ee;hp=621ab5806442575193a07aedfef41817ffeb6a20;hpb=276cfa264720edddc1677e35c6a300596965de7d;p=palacios.git diff --git a/linux_module/main.c b/linux_module/main.c index 621ab58..57fe2ef 100644 --- a/linux_module/main.c +++ b/linux_module/main.c @@ -5,6 +5,7 @@ #include +#include #include #include #include @@ -28,43 +29,34 @@ MODULE_LICENSE("GPL"); +// Module parameter +int cpu_list[NR_CPUS] = {}; +int cpu_list_len = 0; +module_param_array(cpu_list, int, &cpu_list_len, 0644); +MODULE_PARM_DESC(cpu_list, "Comma-delimited list of CPUs that Palacios will run on"); + int mod_allocs = 0; int mod_frees = 0; static int v3_major_num = 0; -static u8 v3_minor_map[MAX_VMS / 8] = {[0 ... (MAX_VMS / 8) - 1] = 0}; - +static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0}; struct class * v3_class = NULL; static struct cdev ctrl_dev; -static int register_vm( void ) { - int i, j = 0; - int avail = 0; - - for (i = 0; i < sizeof(v3_minor_map); i++) { - if (v3_minor_map[i] != 0xff) { - for (j = 0; j < 8; j++) { - if (!(v3_minor_map[i] & (0x1 << j))) { - avail = 1; - v3_minor_map[i] |= (0x1 << j); - break; - } - } - - if (avail == 1) { - break; - } +static int register_vm(struct v3_guest * guest) { + int i = 0; + + for (i = 0; i < MAX_VMS; i++) { + if (guest_map[i] == NULL) { + guest_map[i] = guest; + return i; } } - if (avail == 0) { - return -1; - } - - return (i * 8) + j; + return -1; } @@ -72,85 +64,73 @@ static int register_vm( void ) { static long v3_dev_ioctl(struct file * filp, unsigned int ioctl, unsigned long arg) { void __user * argp = (void __user *)arg; - printk("V3 IOCTL %d\n", ioctl); + DEBUG("V3 IOCTL %d\n", ioctl); 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); if (IS_ERR(guest)) { - printk("Error allocating Kernel guest_image\n"); + ERROR("Palacios: Error allocating Kernel guest_image\n"); return -EFAULT; } memset(guest, 0, sizeof(struct v3_guest)); - printk("Starting V3 Guest...\n"); + INFO("Palacios: Creating V3 Guest...\n"); - vm_minor = register_vm(); + vm_minor = register_vm(guest); if (vm_minor == -1) { - printk("Too many VMs are currently running\n"); + ERROR("Palacios Error: Too many VMs are currently running\n"); return -EFAULT; } guest->vm_dev = MKDEV(v3_major_num, vm_minor); if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) { - printk("copy from user error getting guest image...\n"); + ERROR("Palacios Error: copy from user error getting guest image...\n"); return -EFAULT; } guest->img_size = user_image.size; - printk("Allocating kernel memory for guest image (%llu bytes)\n", user_image.size); + DEBUG("Palacios: Allocating kernel memory for guest image (%llu bytes)\n", user_image.size); guest->img = vmalloc(guest->img_size); if (IS_ERR(guest->img)) { - printk("Error: Could not allocate space for guest image\n"); + ERROR("Palacios Error: Could not allocate space for guest image\n"); return -EFAULT; } if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) { - printk("Error loading guest data\n"); + ERROR("Palacios: Error loading guest data\n"); return -EFAULT; } strncpy(guest->name, user_image.name, 127); - printk("Launching VM\n"); - INIT_LIST_HEAD(&(guest->exts)); - init_completion(&(guest->start_done)); - init_completion(&(guest->thread_done)); - - { - struct task_struct * launch_thread = NULL; - // At some point we're going to want to allow the user to specify a CPU mask - // But for now, well just launch from the local core, and rely on the global cpu mask - - preempt_disable(); - launch_thread = kthread_create(start_palacios_vm, guest, guest->name); - - if (IS_ERR(launch_thread)) { - preempt_enable(); - printk("Palacios error creating launch thread for vm (%s)\n", guest->name); - return -EFAULT; - } - - kthread_bind(launch_thread, smp_processor_id()); - preempt_enable(); - - wake_up_process(launch_thread); + if (create_palacios_vm(guest) == -1) { + ERROR("Palacios: Error creating guest\n"); + return -EFAULT; } - wait_for_completion(&(guest->start_done)); + return vm_minor; + break; + } + case V3_FREE_GUEST: { + unsigned long vm_idx = arg; + struct v3_guest * guest = guest_map[vm_idx]; + + INFO("Freeing VM (%s) (%p)\n", guest->name, guest); - return guest->vm_dev; + free_palacios_vm(guest); + guest_map[vm_idx] = NULL; break; } case V3_ADD_MEMORY: { @@ -159,14 +139,14 @@ static long v3_dev_ioctl(struct file * filp, memset(&mem, 0, sizeof(struct v3_mem_region)); if (copy_from_user(&mem, argp, sizeof(struct v3_mem_region))) { - printk("copy from user error getting mem_region...\n"); + ERROR("copy from user error getting mem_region...\n"); return -EFAULT; } - printk("Adding %llu pages to Palacios memory\n", mem.num_pages); + DEBUG("Adding %llu pages to Palacios memory\n", mem.num_pages); if (add_palacios_memory(mem.base_addr, mem.num_pages) == -1) { - printk("Error adding memory to Palacios\n"); + ERROR("Error adding memory to Palacios\n"); return -EFAULT; } @@ -174,7 +154,7 @@ static long v3_dev_ioctl(struct file * filp, } default: - printk("\tUnhandled\n"); + ERROR("\tUnhandled\n"); return -EINVAL; } @@ -198,9 +178,7 @@ static int __init v3_init(void) { palacios_init_mm(); - // Initialize Palacios - palacios_vmm_init(); @@ -210,16 +188,16 @@ static int __init v3_init(void) { v3_class = class_create(THIS_MODULE, "vms"); if (IS_ERR(v3_class)) { - printk("Failed to register V3 VM device class\n"); + ERROR("Failed to register V3 VM device class\n"); return PTR_ERR(v3_class); } - printk("intializing V3 Control device\n"); + INFO("intializing V3 Control device\n"); ret = alloc_chrdev_region(&dev, 0, MAX_VMS + 1, "v3vee"); if (ret < 0) { - printk("Error registering device region for V3 devices\n"); + ERROR("Error registering device region for V3 devices\n"); goto failure2; } @@ -228,7 +206,7 @@ static int __init v3_init(void) { dev = MKDEV(v3_major_num, MAX_VMS + 1); - printk("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev)); + DEBUG("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev)); cdev_init(&ctrl_dev, &v3_ctrl_fops); ctrl_dev.owner = THIS_MODULE; ctrl_dev.ops = &v3_ctrl_fops; @@ -237,7 +215,7 @@ static int __init v3_init(void) { device_create(v3_class, NULL, dev, NULL, "v3vee"); if (ret != 0) { - printk("Error adding v3 control device\n"); + ERROR("Error adding v3 control device\n"); goto failure1; } @@ -267,13 +245,13 @@ static void __exit v3_exit(void) { dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1); - printk("Removing V3 Control device\n"); + INFO("Removing V3 Control device\n"); palacios_vmm_exit(); - printk("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees); - printk("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees); + DEBUG("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees); + DEBUG("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees); unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1); @@ -287,7 +265,7 @@ static void __exit v3_exit(void) { palacios_deinit_mm(); - printk("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees); + DEBUG("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees); }