2 Palacios main control interface
7 #include <linux/module.h>
8 #include <linux/moduleparam.h>
9 #include <linux/errno.h>
10 #include <linux/percpu.h>
12 #include <linux/uaccess.h>
13 #include <linux/device.h>
14 #include <linux/cdev.h>
18 #include <linux/file.h>
19 #include <linux/spinlock.h>
20 #include <linux/kthread.h>
22 #include <linux/proc_fs.h>
28 #include "linux-exts.h"
32 MODULE_LICENSE("GPL");
35 int cpu_list[NR_CPUS] = {};
37 module_param_array(cpu_list, int, &cpu_list_len, 0644);
38 MODULE_PARM_DESC(cpu_list, "Comma-delimited list of CPUs that Palacios will run on");
44 static int v3_major_num = 0;
46 static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0};
47 static struct proc_dir_entry *dir = 0;
49 struct class * v3_class = NULL;
50 static struct cdev ctrl_dev;
52 static int register_vm(struct v3_guest * guest) {
55 for (i = 0; i < MAX_VMS; i++) {
56 if (guest_map[i] == NULL) {
67 static long v3_dev_ioctl(struct file * filp,
68 unsigned int ioctl, unsigned long arg) {
69 void __user * argp = (void __user *)arg;
70 DEBUG("V3 IOCTL %d\n", ioctl);
74 case V3_CREATE_GUEST:{
76 struct v3_guest_img user_image;
77 struct v3_guest * guest = palacios_alloc(sizeof(struct v3_guest));
80 ERROR("Palacios: Error allocating Kernel guest_image\n");
84 memset(guest, 0, sizeof(struct v3_guest));
86 INFO("Palacios: Creating V3 Guest...\n");
88 vm_minor = register_vm(guest);
91 ERROR("Palacios Error: Too many VMs are currently running\n");
96 guest->vm_dev = MKDEV(v3_major_num, vm_minor);
98 if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) {
99 ERROR("Palacios Error: copy from user error getting guest image...\n");
100 palacios_free(guest);
104 guest->img_size = user_image.size;
106 DEBUG("Palacios: Allocating kernel memory for guest image (%llu bytes)\n", user_image.size);
107 guest->img = vmalloc(guest->img_size);
109 if (IS_ERR(guest->img)) {
110 ERROR("Palacios Error: Could not allocate space for guest image\n");
111 palacios_free(guest);
115 if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) {
116 ERROR("Palacios: Error loading guest data\n");
117 palacios_free(guest);
121 strncpy(guest->name, user_image.name, 127);
123 INIT_LIST_HEAD(&(guest->exts));
125 if (create_palacios_vm(guest) == -1) {
126 ERROR("Palacios: Error creating guest\n");
128 palacios_free(guest);
135 case V3_FREE_GUEST: {
136 unsigned long vm_idx = arg;
137 struct v3_guest * guest = guest_map[vm_idx];
139 INFO("Freeing VM (%s) (%p)\n", guest->name, guest);
141 free_palacios_vm(guest);
142 guest_map[vm_idx] = NULL;
145 case V3_ADD_MEMORY: {
146 struct v3_mem_region mem;
148 memset(&mem, 0, sizeof(struct v3_mem_region));
150 if (copy_from_user(&mem, argp, sizeof(struct v3_mem_region))) {
151 ERROR("copy from user error getting mem_region...\n");
155 DEBUG("Adding %llu pages to Palacios memory\n", mem.num_pages);
157 if (add_palacios_memory(mem.base_addr, mem.num_pages) == -1) {
158 ERROR("Error adding memory to Palacios\n");
166 ERROR("\tUnhandled\n");
175 static struct file_operations v3_ctrl_fops = {
176 .owner = THIS_MODULE,
177 .unlocked_ioctl = v3_dev_ioctl,
178 .compat_ioctl = v3_dev_ioctl,
183 struct proc_dir_entry *palacios_get_procdir(void)
188 static int read_guests(char * buf, char ** start, off_t off, int count,
189 int * eof, void * data)
194 for(i = 0; i < MAX_VMS; i++) {
195 if (guest_map[i] != NULL) {
197 len += snprintf(buf+len, count-len,
198 "%s\t/dev/v3-vm%d\n",
199 guest_map[i]->name, i);
207 static int show_mem(char * buf, char ** start, off_t off, int count,
208 int * eof, void * data)
212 len = snprintf(buf,count, "%p\n", (void *)get_palacios_base_addr());
213 len += snprintf(buf+len,count-len, "%lld\n", get_palacios_num_pages());
219 static int __init v3_init(void) {
220 dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number
226 // Initialize Palacios
230 // initialize extensions
231 init_lnx_extensions();
234 v3_class = class_create(THIS_MODULE, "vms");
235 if (IS_ERR(v3_class)) {
236 ERROR("Failed to register V3 VM device class\n");
237 return PTR_ERR(v3_class);
240 INFO("intializing V3 Control device\n");
242 ret = alloc_chrdev_region(&dev, 0, MAX_VMS + 1, "v3vee");
245 ERROR("Error registering device region for V3 devices\n");
249 v3_major_num = MAJOR(dev);
251 dev = MKDEV(v3_major_num, MAX_VMS + 1);
254 DEBUG("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev));
255 cdev_init(&ctrl_dev, &v3_ctrl_fops);
256 ctrl_dev.owner = THIS_MODULE;
257 ctrl_dev.ops = &v3_ctrl_fops;
258 cdev_add(&ctrl_dev, dev, 1);
260 device_create(v3_class, NULL, dev, NULL, "v3vee");
263 ERROR("Error adding v3 control device\n");
267 dir = proc_mkdir("v3vee", NULL);
269 struct proc_dir_entry *entry;
271 entry = create_proc_read_entry("v3-guests", 0444, dir,
274 INFO("/proc/v3vee/v3-guests successfully created\n");
276 ERROR("Could not create proc entry\n");
280 entry = create_proc_read_entry("v3-mem", 0444, dir,
283 INFO("/proc/v3vee/v3-mem successfully added\n");
285 ERROR("Could not create proc entry\n");
289 ERROR("Could not create proc entry\n");
296 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
298 class_destroy(v3_class);
304 static void __exit v3_exit(void) {
305 extern u32 pg_allocs;
311 // should probably try to stop any guests
315 dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1);
317 INFO("Removing V3 Control device\n");
322 DEBUG("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
323 DEBUG("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
325 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
329 device_destroy(v3_class, dev);
330 class_destroy(v3_class);
333 deinit_lnx_extensions();
335 palacios_deinit_mm();
337 remove_proc_entry("v3-guests", dir);
338 remove_proc_entry("v3-mem", dir);
339 remove_proc_entry("v3vee", NULL);
341 DEBUG("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees);
346 module_init(v3_init);
347 module_exit(v3_exit);
351 void * trace_malloc(size_t size, gfp_t flags) {
355 addr = kmalloc(size, flags);
361 void trace_free(const void * objp) {