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>
24 #include <palacios/vmm.h>
29 #include "allow_devmem.h"
31 #include "lockcheck.h"
33 #include "linux-exts.h"
36 MODULE_LICENSE("GPL");
39 int cpu_list[NR_CPUS] = {};
41 module_param_array(cpu_list, int, &cpu_list_len, 0644);
42 MODULE_PARM_DESC(cpu_list, "Comma-delimited list of CPUs that Palacios will run on");
44 static int allow_devmem = 0;
45 module_param(allow_devmem, int, 0);
46 MODULE_PARM_DESC(allow_devmem, "Allow general user-space /dev/mem access even if kernel is strict");
48 // Palacios options parameter
50 module_param(options, charp, 0);
51 MODULE_PARM_DESC(options, "Generic options to internal Palacios modules");
57 static int v3_major_num = 0;
59 static struct v3_guest * guest_map[MAX_VMS] = {[0 ... MAX_VMS - 1] = 0};
60 static struct proc_dir_entry *dir = 0;
62 struct class * v3_class = NULL;
63 static struct cdev ctrl_dev;
65 static int register_vm(struct v3_guest * guest) {
68 for (i = 0; i < MAX_VMS; i++) {
69 if (guest_map[i] == NULL) {
80 static long v3_dev_ioctl(struct file * filp,
81 unsigned int ioctl, unsigned long arg) {
82 void __user * argp = (void __user *)arg;
83 DEBUG("V3 IOCTL %d\n", ioctl);
87 case V3_CREATE_GUEST:{
89 struct v3_guest_img user_image;
90 struct v3_guest * guest = palacios_alloc(sizeof(struct v3_guest));
93 ERROR("Palacios: Error allocating Kernel guest_image\n");
97 memset(guest, 0, sizeof(struct v3_guest));
99 INFO("Palacios: Creating V3 Guest...\n");
101 vm_minor = register_vm(guest);
103 if (vm_minor == -1) {
104 ERROR("Palacios Error: Too many VMs are currently running\n");
108 guest->vm_dev = MKDEV(v3_major_num, vm_minor);
110 if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) {
111 ERROR("Palacios Error: copy from user error getting guest image...\n");
115 guest->img_size = user_image.size;
117 DEBUG("Palacios: Allocating kernel memory for guest image (%llu bytes)\n", user_image.size);
118 guest->img = palacios_valloc(guest->img_size);
120 if (IS_ERR(guest->img)) {
121 ERROR("Palacios Error: Could not allocate space for guest image\n");
125 if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) {
126 ERROR("Palacios: Error loading guest data\n");
130 strncpy(guest->name, user_image.name, 127);
132 INIT_LIST_HEAD(&(guest->exts));
134 if (create_palacios_vm(guest) == -1) {
135 ERROR("Palacios: Error creating guest\n");
143 palacios_vfree(guest->img);
145 guest_map[vm_minor] = NULL;
147 palacios_free(guest);
153 case V3_FREE_GUEST: {
154 unsigned long vm_idx = arg;
155 struct v3_guest * guest;
157 if (vm_idx > MAX_VMS) {
158 ERROR("Invalid VM index: %ld\n", vm_idx);
162 guest = guest_map[vm_idx];
165 ERROR("No VM at index %ld\n",vm_idx);
169 INFO("Freeing VM (%s) (%p)\n", guest->name, guest);
171 if (free_palacios_vm(guest)<0) {
172 ERROR("Cannot free guest at index %ld\n",vm_idx);
176 guest_map[vm_idx] = NULL;
179 case V3_ADD_MEMORY: {
180 struct v3_mem_region mem;
182 memset(&mem, 0, sizeof(struct v3_mem_region));
184 if (copy_from_user(&mem, argp, sizeof(struct v3_mem_region))) {
185 ERROR("copy from user error getting mem_region...\n");
189 DEBUG("Adding %llu pages to Palacios memory\n", mem.num_pages);
191 if (add_palacios_memory(mem.base_addr, mem.num_pages) == -1) {
192 ERROR("Error adding memory to Palacios\n");
199 case V3_RESET_MEMORY: {
200 if (palacios_init_mm() == -1) {
201 ERROR("Error resetting Palacios memory\n");
208 struct global_ctrl * ctrl = get_global_ctrl(ioctl);
211 return ctrl->handler(ioctl, arg);
214 WARNING("\tUnhandled global ctrl cmd: %d\n", ioctl);
225 static struct file_operations v3_ctrl_fops = {
226 .owner = THIS_MODULE,
227 .unlocked_ioctl = v3_dev_ioctl,
228 .compat_ioctl = v3_dev_ioctl,
233 struct proc_dir_entry *palacios_get_procdir(void)
239 #define MAX_VCORES 32
241 static int read_guests(char * buf, char ** start, off_t off, int count,
242 int * eof, void * data)
247 struct v3_vm_state *s =palacios_alloc(sizeof(struct v3_vm_state)+MAX_VCORES*sizeof(struct v3_vcore_state));
250 ERROR("No space for state structure\n");
254 for(i = 0; i < MAX_VMS; i++) {
255 if (guest_map[i] != NULL) {
259 len += snprintf(buf+len, count-len,
261 guest_map[i]->name, i);
268 s->num_vcores=MAX_VCORES; // max we can handle
269 if (v3_get_state_vm(guest_map[i]->v3_ctx, s)) {
270 ERROR("Cannot get VM info\n");
276 len+=snprintf(buf+len, count-len,
277 "%s [0x%p-0x%p] %lu vcores ",
278 s->state==V3_VM_INVALID ? "INVALID" :
279 s->state==V3_VM_RUNNING ? "running" :
280 s->state==V3_VM_STOPPED ? "stopped" :
281 s->state==V3_VM_PAUSED ? "paused" :
282 s->state==V3_VM_ERROR ? "ERROR" :
283 s->state==V3_VM_SIMULATING ? "simulating" : "UNKNOWN",
284 s->mem_base_paddr, s->mem_base_paddr+s->mem_size-1,
290 for (j=0;j<s->num_vcores;j++) {
291 len+=snprintf(buf+len, count-len,
292 "[vcore %lu %s on pcore %lu %llu exits rip=0x%p %s %s %s] ",
294 s->vcore[j].state==V3_VCORE_INVALID ? "INVALID" :
295 s->vcore[j].state==V3_VCORE_RUNNING ? "running" :
296 s->vcore[j].state==V3_VCORE_STOPPED ? "stopped" : "UNKNOWN",
298 s->vcore[j].num_exits,
299 s->vcore[j].last_rip,
300 s->vcore[j].cpu_mode==V3_VCORE_CPU_REAL ? "real" :
301 s->vcore[j].cpu_mode==V3_VCORE_CPU_PROTECTED ? "protected" :
302 s->vcore[j].cpu_mode==V3_VCORE_CPU_PROTECTED_PAE ? "protectedpae" :
303 s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG ? "long" :
304 s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG_32_COMPAT ? "long32" :
305 s->vcore[j].cpu_mode==V3_VCORE_CPU_LONG_16_COMPAT ? "long16" : "UNKNOWN",
306 s->vcore[j].mem_mode==V3_VCORE_MEM_MODE_PHYSICAL ? "physical" :
307 s->vcore[j].mem_mode==V3_VCORE_MEM_MODE_VIRTUAL ? "virtual" : "UNKNOWN",
308 s->vcore[j].mem_state==V3_VCORE_MEM_STATE_SHADOW ? "shadow" :
309 s->vcore[j].mem_state==V3_VCORE_MEM_STATE_NESTED ? "nested" : "UNKNOWN");
325 if (s) { palacios_free(s); }
330 static int show_mem(char * buf, char ** start, off_t off, int count,
331 int * eof, void * data)
335 len = snprintf(buf,count, "%p\n", (void *)get_palacios_base_addr());
336 len += snprintf(buf+len,count-len, "%lld\n", get_palacios_num_pages());
345 static int __init v3_init(void) {
347 dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number
356 palacios_allow_devmem();
359 // Initialize Palacios
360 palacios_vmm_init(options);
363 // initialize extensions
364 init_lnx_extensions();
367 v3_class = class_create(THIS_MODULE, "vms");
368 if (IS_ERR(v3_class)) {
369 ERROR("Failed to register V3 VM device class\n");
370 return PTR_ERR(v3_class);
373 INFO("intializing V3 Control device\n");
375 ret = alloc_chrdev_region(&dev, 0, MAX_VMS + 1, "v3vee");
378 ERROR("Error registering device region for V3 devices\n");
382 v3_major_num = MAJOR(dev);
384 dev = MKDEV(v3_major_num, MAX_VMS + 1);
387 DEBUG("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev));
388 cdev_init(&ctrl_dev, &v3_ctrl_fops);
389 ctrl_dev.owner = THIS_MODULE;
390 ctrl_dev.ops = &v3_ctrl_fops;
391 cdev_add(&ctrl_dev, dev, 1);
393 device_create(v3_class, NULL, dev, NULL, "v3vee");
396 ERROR("Error adding v3 control device\n");
400 dir = proc_mkdir("v3vee", NULL);
402 struct proc_dir_entry *entry;
404 entry = create_proc_read_entry("v3-guests", 0444, dir,
407 INFO("/proc/v3vee/v3-guests successfully created\n");
409 ERROR("Could not create proc entry\n");
413 entry = create_proc_read_entry("v3-mem", 0444, dir,
416 INFO("/proc/v3vee/v3-mem successfully added\n");
418 ERROR("Could not create proc entry\n");
422 ERROR("Could not create proc entry\n");
429 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
431 class_destroy(v3_class);
437 static void __exit v3_exit(void) {
438 extern u32 pg_allocs;
445 struct v3_guest * guest;
449 /* Stop and free any running VMs */
450 for (i = 0; i < MAX_VMS; i++) {
451 if (guest_map[i] != NULL) {
452 guest = (struct v3_guest *)guest_map[i];
454 if (v3_stop_vm(guest->v3_ctx) < 0)
455 ERROR("Couldn't stop VM %d\n", i);
457 free_palacios_vm(guest);
462 dev = MKDEV(v3_major_num, MAX_VMS + 1);
464 INFO("Removing V3 Control device\n");
469 DEBUG("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
470 DEBUG("Palacios Vmallocs = %d, Vfrees = %d\n", vmallocs, vfrees);
471 DEBUG("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
473 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
477 device_destroy(v3_class, dev);
478 class_destroy(v3_class);
481 deinit_lnx_extensions();
484 palacios_restore_devmem();
487 palacios_deinit_mm();
489 remove_proc_entry("v3-guests", dir);
490 remove_proc_entry("v3-mem", dir);
491 remove_proc_entry("v3vee", NULL);
493 DEBUG("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees);
501 module_init(v3_init);
502 module_exit(v3_exit);
506 void * trace_malloc(size_t size, gfp_t flags) {
510 addr = palacios_alloc_extended(size, flags);
516 void trace_free(const void * objp) {
518 palacios_free((void*)objp);