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>
22 #include "palacios-mm.h"
23 #include "palacios-vm.h"
24 #include "palacios-stream.h"
25 #include "palacios-file.h"
26 #include "palacios-serial.h"
27 #include "palacios-socket.h"
28 #include "palacios-vnet.h"
29 #include "palacios-packet.h"
31 MODULE_LICENSE("GPL");
37 static int v3_major_num = 0;
39 static u8 v3_minor_map[MAX_VMS / 8] = {[0 ... (MAX_VMS / 8) - 1] = 0};
42 struct class * v3_class = NULL;
43 static struct cdev ctrl_dev;
45 void * v3_base_addr = NULL;
46 unsigned int v3_pages = 0;
48 static int register_vm( void ) {
52 for (i = 0; i < sizeof(v3_minor_map); i++) {
53 if (v3_minor_map[i] != 0xff) {
54 for (j = 0; j < 8; j++) {
55 if (!v3_minor_map[i] & (0x1 << j)) {
57 v3_minor_map[i] |= (0x1 << j);
77 static long v3_dev_ioctl(struct file * filp,
78 unsigned int ioctl, unsigned long arg) {
79 void __user * argp = (void __user *)arg;
80 printk("V3 IOCTL %d\n", ioctl);
86 struct v3_guest_img user_image;
87 struct v3_guest * guest = kmalloc(sizeof(struct v3_guest), GFP_KERNEL);
90 printk("Error allocating Kernel guest_image\n");
94 memset(guest, 0, sizeof(struct v3_guest));
96 printk("Starting V3 Guest...\n");
98 vm_minor = register_vm();
100 if (vm_minor == -1) {
101 printk("Too many VMs are currently running\n");
105 guest->vm_dev = MKDEV(v3_major_num, vm_minor);
107 if (copy_from_user(&user_image, argp, sizeof(struct v3_guest_img))) {
108 printk("copy from user error getting guest image...\n");
112 guest->img_size = user_image.size;
114 printk("Allocating kernel memory for guest image (%llu bytes)\n", user_image.size);
115 guest->img = kmalloc(guest->img_size, GFP_KERNEL);
117 if (IS_ERR(guest->img)) {
118 printk("Error: Could not allocate space for guest image\n");
122 if (copy_from_user(guest->img, user_image.guest_data, guest->img_size)) {
123 printk("Error loading guest data\n");
127 strncpy(guest->name, user_image.name, 127);
129 printk("Launching VM\n");
131 INIT_LIST_HEAD(&(guest->streams));
132 INIT_LIST_HEAD(&(guest->files));
133 INIT_LIST_HEAD(&(guest->sockets));
134 init_completion(&(guest->start_done));
135 init_completion(&(guest->thread_done));
137 kthread_run(start_palacios_vm, guest, guest->name);
139 wait_for_completion(&(guest->start_done));
141 return guest->vm_dev;
144 case V3_ADD_MEMORY: {
145 struct v3_mem_region mem;
147 memset(&mem, 0, sizeof(struct v3_mem_region));
149 if (copy_from_user(&mem, argp, sizeof(struct v3_mem_region))) {
150 printk("copy from user error getting mem_region...\n");
154 printk("Adding %llu pages to Palacios memory\n", mem.num_pages);
156 if (add_palacios_memory(mem.base_addr, mem.num_pages) == -1) {
157 printk("Error adding memory to Palacios\n");
164 void * vaddr = __va(alloc_palacios_pgs(131072, 4096));
165 memset(vaddr, 0xfe492fe2, mem.num_pages * 4096);
172 case V3_START_NETWORK: {
173 struct v3_network net;
174 memset(&net, 0, sizeof(struct v3_network));
176 if(copy_from_user(&net, argp, sizeof(struct v3_network))){
177 printk("copy from user error getting network service requests ... \n");
181 #ifdef CONFIG_PALACIOS_SOCKET
183 palacios_socket_init();
184 printk("Started Palacios Socket\n");
187 #ifdef CONFIG_PALACIOS_PACKET
189 palacios_init_packet(NULL);
190 printk("Started Palacios Direct Network Bridge\n");
193 #ifdef CONFIG_PALACIOS_VNET
195 palacios_init_vnet();
196 printk("Started Palacios VNET Service\n");
203 printk("\tUnhandled\n");
212 static struct file_operations v3_ctrl_fops = {
213 .owner = THIS_MODULE,
214 .unlocked_ioctl = v3_dev_ioctl,
215 .compat_ioctl = v3_dev_ioctl,
219 extern unsigned int v3_pages;
220 extern void * v3_base_addr;
222 static int __init v3_init(void) {
223 dev_t dev = MKDEV(0, 0); // We dynamicallly assign the major number
229 v3_class = class_create(THIS_MODULE, "vms");
230 if (IS_ERR(v3_class)) {
231 printk("Failed to register V3 VM device class\n");
232 return PTR_ERR(v3_class);
235 printk("intializing V3 Control device\n");
237 ret = alloc_chrdev_region(&dev, 0, MAX_VMS + 1, "v3vee");
240 printk("Error registering device region for V3 devices\n");
244 v3_major_num = MAJOR(dev);
246 dev = MKDEV(v3_major_num, MAX_VMS + 1);
249 printk("Creating V3 Control device: Major %d, Minor %d\n", v3_major_num, MINOR(dev));
250 cdev_init(&ctrl_dev, &v3_ctrl_fops);
251 ctrl_dev.owner = THIS_MODULE;
252 ctrl_dev.ops = &v3_ctrl_fops;
253 cdev_add(&ctrl_dev, dev, 1);
255 device_create(v3_class, NULL, dev, NULL, "v3vee");
258 printk("Error adding v3 control device\n");
262 if ((v3_pages > 0) && (v3_base_addr != NULL)) {
263 add_palacios_memory(__pa(v3_base_addr), v3_pages);
266 // Initialize Palacios
270 palacios_init_stream();
271 palacios_file_init();
272 palacios_init_console();
277 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
279 class_destroy(v3_class);
285 static void __exit v3_exit(void) {
286 extern u32 pg_allocs;
292 // should probably try to stop any guests
296 dev_t dev = MKDEV(v3_major_num, MAX_VMS + 1);
298 printk("Removing V3 Control device\n");
303 printk("Palacios Mallocs = %d, Frees = %d\n", mallocs, frees);
304 printk("Palacios Page Allocs = %d, Page Frees = %d\n", pg_allocs, pg_frees);
306 unregister_chrdev_region(MKDEV(v3_major_num, 0), MAX_VMS + 1);
310 device_destroy(v3_class, dev);
311 class_destroy(v3_class);
314 palacios_file_deinit();
315 palacios_deinit_stream();
317 palacios_deinit_mm();
319 printk("Palacios Module Mallocs = %d, Frees = %d\n", mod_allocs, mod_frees);
324 module_init(v3_init);
325 module_exit(v3_exit);
329 void * trace_malloc(size_t size, gfp_t flags) {
333 addr = kmalloc(size, flags);
339 void trace_free(const void * objp) {