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.


missed file commit
[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 #ifdef V3_CONFIG_GRAPHICS_CONSOLE
39 #include "palacios-graphics-console.h"
40 #endif
41
42 #ifdef V3_CONFIG_HOST_DEVICE
43 #include "palacios-host-dev.h"
44 #endif
45
46 extern struct class * v3_class;
47 #define STREAM_NAME_LEN 128
48
49 static long v3_vm_ioctl(struct file * filp,
50                         unsigned int ioctl, unsigned long arg) {
51
52     struct v3_guest * guest = filp->private_data;
53
54     printk("V3 IOCTL %d\n", ioctl);
55
56     switch (ioctl) {
57
58         case V3_VM_STOP: {
59             printk("Stopping VM\n");
60             stop_palacios_vm(guest);
61             break;
62         }
63
64         case V3_VM_CONSOLE_CONNECT: {
65 #ifdef V3_CONFIG_CONSOLE
66             return connect_console(guest);
67 #else
68             printk("Console support not available\n");
69             return -EFAULT;
70 #endif
71             break;
72         }
73
74         case V3_VM_STREAM_CONNECT: {
75 #ifdef V3_CONFIG_STREAM
76             void __user * argp = (void __user *)arg;
77             char path_name[STREAM_NAME_LEN];
78
79             if (copy_from_user(path_name, argp, STREAM_NAME_LEN)) {
80                 printk("%s(%d): copy from user error...\n", __FILE__, __LINE__);
81                 return -EFAULT;
82             }
83
84             return open_stream(path_name);
85 #else
86             printk("Stream support Not available\n");
87             return -EFAULT;
88 #endif
89             break;
90         }
91
92         case V3_VM_HOST_DEV_CONNECT: {
93 #ifdef V3_CONFIG_HOST_DEV
94             if (copy_from_user(host_dev_url, argp, HOST_DEV_URL_LEN)) {
95                 printk("copy from user error getting url for host device connect...\n");
96                 return -EFAULT;
97             }
98
99             return connect_host_dev(guest,host_dev_url);
100 #else
101             printk("palacios: Host device support not available\n");
102             return -EFAULT;
103 #endif
104             break;
105         }
106
107         case V3_VM_FB_INPUT: 
108 #ifdef V3_CONFIG_GRAPHICS_CONSOLE
109             return palacios_graphics_console_user_input(&(guest->graphics_console),
110                                                         (struct v3_fb_input __user *) arg) ;
111 #else
112             return -EFAULT;
113 #endif
114             break;
115             
116         case V3_VM_FB_QUERY: 
117 #ifdef V3_CONFIG_GRAPHICS_CONSOLE
118             return palacios_graphics_console_user_query(&(guest->graphics_console),
119                                                         (struct v3_fb_query_response __user *) arg);
120 #else
121             return -EFAULT;
122 #endif
123             break;
124
125
126         default: 
127             printk("\tUnhandled\n");
128             return -EINVAL;
129     }
130
131     return 0;
132 }
133
134 static int v3_vm_open(struct inode * inode, struct file * filp) {
135     struct v3_guest * guest = container_of(inode->i_cdev, struct v3_guest, cdev);
136     filp->private_data = guest;
137     return 0;
138 }
139
140
141 static ssize_t v3_vm_read(struct file * filp, char __user * buf, size_t size, loff_t * offset) {
142     
143     return 0;
144 }
145
146
147 static ssize_t v3_vm_write(struct file * filp, const char __user * buf, size_t size, loff_t * offset) {
148
149     return 0;
150 }
151
152
153 static struct file_operations v3_vm_fops = {
154     .owner = THIS_MODULE,
155     .unlocked_ioctl = v3_vm_ioctl,
156     .compat_ioctl = v3_vm_ioctl,
157     .open = v3_vm_open,
158     .read = v3_vm_read, 
159     .write = v3_vm_write,
160 };
161
162
163 extern int vm_running;
164 extern u32 pg_allocs;
165 extern u32 pg_frees;
166 extern u32 mallocs;
167 extern u32 frees;
168
169 int start_palacios_vm(void * arg)  {
170     struct v3_guest * guest = (struct v3_guest *)arg;
171     int err;
172
173     lock_kernel();
174     daemonize(guest->name);
175     // allow_signal(SIGKILL);
176     unlock_kernel();
177     
178
179     guest->v3_ctx = v3_create_vm(guest->img, (void *)guest, guest->name);
180
181     if (guest->v3_ctx == NULL) { 
182         printk("palacios: failed to create vm\n");
183         complete(&(guest->start_done));
184         return -1;
185     }
186
187     printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
188
189     cdev_init(&(guest->cdev), &v3_vm_fops);
190
191     guest->cdev.owner = THIS_MODULE;
192     guest->cdev.ops = &v3_vm_fops;
193
194
195     printk("Adding VM device\n");
196     err = cdev_add(&(guest->cdev), guest->vm_dev, 1);
197
198     if (err) {
199         printk("Fails to add cdev\n");
200         v3_free_vm(guest->v3_ctx);
201         complete(&(guest->start_done));
202         return -1;
203     }
204
205     if (device_create(v3_class, NULL, guest->vm_dev, guest, "v3-vm%d", MINOR(guest->vm_dev)) == NULL){
206         printk("Fails to create device\n");
207         cdev_del(&(guest->cdev));
208         v3_free_vm(guest->v3_ctx);
209         complete(&(guest->start_done));
210         return -1;
211     }
212
213     complete(&(guest->start_done));
214
215     printk("palacios: launching vm\n");
216
217
218 #if V3_CONFIG_EXT_INSPECTOR
219     inspect_vm(guest);
220 #endif
221
222
223     if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
224         printk("palacios: launch of vm failed\n");
225         device_destroy(v3_class, guest->vm_dev);
226         cdev_del(&(guest->cdev));
227         v3_free_vm(guest->v3_ctx);
228         return -1;
229     }
230     
231     complete(&(guest->thread_done));
232
233     printk("palacios: vm completed.  returning.\n");
234
235     return 0;
236 }
237
238
239
240
241 int stop_palacios_vm(struct v3_guest * guest) {
242
243     v3_stop_vm(guest->v3_ctx);
244
245     wait_for_completion(&(guest->thread_done));
246
247     v3_free_vm(guest->v3_ctx);
248     
249     device_destroy(v3_class, guest->vm_dev);
250
251     cdev_del(&(guest->cdev));
252
253     kfree(guest->img);
254     kfree(guest);
255
256     return 0;
257 }