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;
}
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");
+ printk("Palacios: Error allocating Kernel guest_image\n");
return -EFAULT;
}
memset(guest, 0, sizeof(struct v3_guest));
- printk("Starting V3 Guest...\n");
+ printk("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");
+ printk("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");
+ printk("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);
+ printk("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");
+ printk("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");
+ printk("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) {
+ printk("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];
+
+ printk("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: {