2 Palacios main control interface
7 #include <linux/module.h>
8 #include <linux/errno.h>
9 #include <linux/percpu.h>
11 #include <linux/uaccess.h>
12 #include <linux/device.h>
13 #include <linux/cdev.h>
17 #include <linux/file.h>
18 #include <linux/spinlock.h>
19 #include <linux/kthread.h>
25 #include "linux-exts.h"
29 MODULE_LICENSE("GPL");
35 static int v3_major_num = 0;
37 static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0};
39 struct class * v3_class = NULL;
40 static struct cdev ctrl_dev;
42 static int register_vm(struct v3_guest * guest) {
45 for (i = 0; i < MAX_VMS; i++) {
46 if (guest_map[i] == NULL) {
57 static long v3_dev_ioctl(struct file * filp,
58 unsigned int ioctl, unsigned long arg) {
59 void __user * argp = (void __user *)arg;
60 printk("V3 IOCTL %d\n", ioctl);
64 case V3_CREATE_GUEST:{
66 struct v3_guest_img user_image;
67 struct v3_guest * guest = kmalloc(sizeof(struct v3_guest), GFP_KERNEL);
70 printk("Palacios: Error allocating Kernel guest_image\n");
74 memset(guest, 0, sizeof(struct v3_guest));
76 printk("Palacios: Creating V3 Guest...\n");
78 vm_minor = register_vm(guest);
81 printk("Palacios Error: Too many VMs are currently running\n");
85 guest->vm_dev = MKDEV(v3_major_num, vm_minor);
87 if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) {
88 printk("Palacios Error: copy from user error getting guest image...\n");
92 guest->img_size = user_image.size;
94 printk("Palacios: Allocating kernel memory for guest image (%llu bytes)\n", user_image.size);
95 guest->img = vmalloc(guest->img_size);
97 if (IS_ERR(guest->img)) {
98 printk("Palacios Error: Could not allocate space for guest image\n");
102 if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) {
103 printk("Palacios: Error loading guest data\n");
107 strncpy(guest->name, user_image.name, 127);
109 INIT_LIST_HEAD(&(guest->exts));
111 if (create_palacios_vm(guest) == -1) {
112 printk("Palacios: Error creating guest\n");
119 case V3_FREE_GUEST: {
120 unsigned long vm_idx = arg;
121 struct v3_guest * guest = guest_map[vm_idx];
123 printk("Freeing VM (%s) (%p)\n", guest->name, guest);
125 free_palacios_vm(guest);
126 guest_map[vm_idx] = NULL;
129 case V3_ADD_MEMORY: {
130 struct v3_mem_region mem;
132 memset(&mem, 0, sizeof(struct v3_mem_region));
134 if (copy_from_user(&mem, argp, sizeof(struct v3_mem_region))) {
135 printk("copy from user error getting mem_region...\n");
139 printk("Adding %llu pages to Palacios memory\n", mem.num_pages);
141 if (add_palacios_memory(mem.base_addr, mem.num_pages) == -1) {
142 printk("Error adding memory to Palacios\n");
150 printk("\tUnhandled\n");
159 static struct file_operations v3_ctrl_fops = {
160 .owner = THIS_MODULE,
161 .unlocked_ioctl = v3_dev_ioctl,
162 .compat_ioctl = v3_dev_ioctl,
167 static int __init v3_init(void) {
168 dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number
175 // Initialize Palacios
180 // initialize extensions
181 init_lnx_extensions();
184 v3_class = class_create(THIS_MODULE, "vms");
185 if (IS_ERR(v3_class)) {
186 printk("Failed to register V3 VM device class\n");
187 return PTR_ERR(v3_class);
190 printk("intializing V3 Control device\n");
192 ret = alloc_chrdev_region(&dev, 0, MAX_VMS + 1, "v3vee");
195 printk("Error registering device region for V3 devices\n");
199 v3_major_num = MAJOR(dev);
201 dev = MKDEV(v3_major_num, MAX_VMS + 1);
204 printk("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev));
205 cdev_init(&ctrl_dev, &v3_ctrl_fops);
206 ctrl_dev.owner = THIS_MODULE;
207 ctrl_dev.ops = &v3_ctrl_fops;
208 cdev_add(&ctrl_dev, dev, 1);
210 device_create(v3_class, NULL, dev, NULL, "v3vee");
213 printk("Error adding v3 control device\n");
222 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
224 class_destroy(v3_class);
230 static void __exit v3_exit(void) {
231 extern u32 pg_allocs;
237 // should probably try to stop any guests
241 dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1);
243 printk("Removing V3 Control device\n");
248 printk("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
249 printk("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
251 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
255 device_destroy(v3_class, dev);
256 class_destroy(v3_class);
259 deinit_lnx_extensions();
261 palacios_deinit_mm();
263 printk("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees);
268 module_init(v3_init);
269 module_exit(v3_exit);
273 void * trace_malloc(size_t size, gfp_t flags) {
277 addr = kmalloc(size, flags);
283 void trace_free(const void * objp) {