Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


move vnet code outside of palacios core directory
[palacios.git] / linux_module / palacios-vm.c
1 /* 
2  * VM specific Controls
3  * (c) Jack Lange, 2010
4  */
5
6 #include <linux/device.h>
7 #include <linux/cdev.h>
8 #include <linux/errno.h>
9 #include <linux/percpu.h>
10 #include <linux/fs.h>
11 #include <linux/uaccess.h>
12 #include <linux/poll.h>
13 #include <linux/anon_inodes.h>
14 #include <linux/sched.h>
15
16 #include <linux/smp_lock.h>
17 #include <linux/file.h>
18 #include <linux/spinlock.h>
19
20
21 #include <palacios/vmm.h>
22
23 #include "palacios.h"
24 #include "palacios-vm.h"
25
26 #ifdef V3_CONFIG_STREAM
27 #include "palacios-stream.h"
28 #endif
29
30 #ifdef V3_CONFIG_CONSOLE
31 #include "palacios-console.h"
32 #endif
33
34 #ifdef V3_CONFIG_EXT_INSPECTOR
35 #include "palacios-inspector.h"
36 #endif
37
38
39 extern struct class * v3_class;
40 #define STREAM_NAME_LEN 128
41
42 static long v3_vm_ioctl(struct file * filp,
43                         unsigned int ioctl, unsigned long arg) {
44
45     struct v3_guest * guest = filp->private_data;
46
47     printk("V3 IOCTL %d\n", ioctl);
48
49     switch (ioctl) {
50
51         case V3_VM_STOP: {
52             printk("Stopping VM\n");
53             stop_palacios_vm(guest);
54             break;
55         }
56
57         case V3_VM_CONSOLE_CONNECT: {
58 #ifdef V3_CONFIG_CONSOLE
59             return connect_console(guest);
60 #else
61             printk("Console support not available\n");
62             return -EFAULT;
63 #endif
64             break;
65         }
66
67         case V3_VM_STREAM_CONNECT: {
68 #ifdef V3_CONFIG_STREAM
69             void __user * argp = (void __user *)arg;
70             char path_name[STREAM_NAME_LEN];
71
72             if (copy_from_user(path_name, argp, STREAM_NAME_LEN)) {
73                 printk("%s(%d): copy from user error...\n", __FILE__, __LINE__);
74                 return -EFAULT;
75             }
76
77             return open_stream(path_name);
78 #else
79             printk("Stream support Not available\n");
80             return -EFAULT;
81 #endif
82             break;
83         }
84
85         default: 
86             printk("\tUnhandled\n");
87             return -EINVAL;
88     }
89
90     return 0;
91 }
92
93 static int v3_vm_open(struct inode * inode, struct file * filp) {
94     struct v3_guest * guest = container_of(inode->i_cdev, struct v3_guest, cdev);
95     filp->private_data = guest;
96     return 0;
97 }
98
99
100 static ssize_t v3_vm_read(struct file * filp, char __user * buf, size_t size, loff_t * offset) {
101     
102     return 0;
103 }
104
105
106 static ssize_t v3_vm_write(struct file * filp, const char __user * buf, size_t size, loff_t * offset) {
107
108     return 0;
109 }
110
111
112 static struct file_operations v3_vm_fops = {
113     .owner = THIS_MODULE,
114     .unlocked_ioctl = v3_vm_ioctl,
115     .compat_ioctl = v3_vm_ioctl,
116     .open = v3_vm_open,
117     .read = v3_vm_read, 
118     .write = v3_vm_write,
119 };
120
121
122 extern int vm_running;
123 extern u32 pg_allocs;
124 extern u32 pg_frees;
125 extern u32 mallocs;
126 extern u32 frees;
127
128 int start_palacios_vm(void * arg)  {
129     struct v3_guest * guest = (struct v3_guest *)arg;
130     int err;
131
132     lock_kernel();
133     daemonize(guest->name);
134     // allow_signal(SIGKILL);
135     unlock_kernel();
136     
137
138     guest->v3_ctx = v3_create_vm(guest->img, (void *)guest, guest->name);
139
140     if (guest->v3_ctx == NULL) { 
141         printk("palacios: failed to create vm\n");
142         complete(&(guest->start_done));
143         return -1;
144     }
145
146     printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
147
148     cdev_init(&(guest->cdev), &v3_vm_fops);
149
150     guest->cdev.owner = THIS_MODULE;
151     guest->cdev.ops = &v3_vm_fops;
152
153
154     printk("Adding VM device\n");
155     err = cdev_add(&(guest->cdev), guest->vm_dev, 1);
156
157     if (err) {
158         printk("Fails to add cdev\n");
159         v3_free_vm(guest->v3_ctx);
160         complete(&(guest->start_done));
161         return -1;
162     }
163
164     if (device_create(v3_class, NULL, guest->vm_dev, guest, "v3-vm%d", MINOR(guest->vm_dev)) == NULL){
165         printk("Fails to create device\n");
166         cdev_del(&(guest->cdev));
167         v3_free_vm(guest->v3_ctx);
168         complete(&(guest->start_done));
169         return -1;
170     }
171
172     complete(&(guest->start_done));
173
174     printk("palacios: launching vm\n");
175
176
177 #if V3_CONFIG_EXT_INSPECTOR
178     inspect_vm(guest);
179 #endif
180
181
182     if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
183         printk("palacios: launch of vm failed\n");
184         device_destroy(v3_class, guest->vm_dev);
185         cdev_del(&(guest->cdev));
186         v3_free_vm(guest->v3_ctx);
187         return -1;
188     }
189     
190     complete(&(guest->thread_done));
191
192     printk("palacios: vm completed.  returning.\n");
193
194     return 0;
195 }
196
197
198
199
200 int stop_palacios_vm(struct v3_guest * guest) {
201
202     v3_stop_vm(guest->v3_ctx);
203
204     wait_for_completion(&(guest->thread_done));
205
206     v3_free_vm(guest->v3_ctx);
207     
208     device_destroy(v3_class, guest->vm_dev);
209
210     cdev_del(&(guest->cdev));
211
212     kfree(guest->img);
213     kfree(guest);
214
215     return 0;
216 }