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.


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