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.


943bbff17c2ea77e020fe355e99975e2b0d7f3a5
[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 #ifdef CONFIG_DEBUG_FS
21 #include <linux/debugfs.h>
22 #endif
23
24 #include <palacios/vmm.h>
25
26 #include "palacios.h"
27 #include "palacios-console.h"
28 #include "palacios-serial.h"
29 #include "palacios-vm.h"
30
31
32 extern struct class * v3_class;
33 #define STREAM_NAME_LEN 128
34
35 static long v3_vm_ioctl(struct file * filp,
36                         unsigned int ioctl, unsigned long arg) {
37     void __user * argp = (void __user *)arg;
38     char path_name[STREAM_NAME_LEN];
39
40     struct v3_guest * guest = filp->private_data;
41
42     printk("V3 IOCTL %d\n", ioctl);
43
44     switch (ioctl) {
45
46         case V3_VM_CONSOLE_CONNECT: {
47             return connect_console(guest);
48             break;
49         }
50         case V3_VM_SERIAL_CONNECT: {
51             if (copy_from_user(path_name, argp, STREAM_NAME_LEN)) {
52                 printk("copy from user error getting guest image...\n");
53                 return -EFAULT;
54             }
55
56             return open_serial(path_name);
57             break;
58         }
59         case V3_VM_STOP: {
60             printk("Stopping VM\n");
61             stop_palacios_vm(guest);
62             break;
63         }
64         default: 
65             printk("\tUnhandled\n");
66             return -EINVAL;
67     }
68
69     return 0;
70 }
71
72 static int v3_vm_open(struct inode * inode, struct file * filp) {
73     struct v3_guest * guest = container_of(inode->i_cdev, struct v3_guest, cdev);
74     filp->private_data = guest;
75     return 0;
76 }
77
78
79 static ssize_t v3_vm_read(struct file * filp, char __user * buf, size_t size, loff_t * offset) {
80     
81     return 0;
82 }
83
84
85 static ssize_t v3_vm_write(struct file * filp, const char __user * buf, size_t size, loff_t * offset) {
86     
87
88     return 0;
89 }
90
91
92 static struct file_operations v3_vm_fops = {
93     .owner = THIS_MODULE,
94     .unlocked_ioctl = v3_vm_ioctl,
95     .compat_ioctl = v3_vm_ioctl,
96     .open = v3_vm_open,
97     .read = v3_vm_read, 
98     .write = v3_vm_write,
99 };
100
101
102
103 extern int vm_running;
104 extern u32 pg_allocs;
105 extern u32 pg_frees;
106 extern u32 mallocs;
107 extern u32 frees;
108
109 #include <palacios/vmm_inspector.h>
110
111 int start_palacios_vm(void * arg)  {
112     struct v3_guest * guest = (struct v3_guest *)arg;
113     int err;
114
115     lock_kernel();
116     daemonize(guest->name);
117 //    allow_signal(SIGKILL);
118     unlock_kernel();
119     
120
121     guest->v3_ctx = v3_create_vm(guest->img, (void *)guest, guest->name);
122
123     if (guest->v3_ctx == NULL) { 
124         printk("palacios: failed to create vm\n");
125         return -1;
126     }
127
128     printk("Creating VM device: Major %d, Minor %d\n", MAJOR(guest->vm_dev), MINOR(guest->vm_dev));
129
130     cdev_init(&(guest->cdev), &v3_vm_fops);     
131
132     guest->cdev.owner = THIS_MODULE;
133     guest->cdev.ops = &v3_vm_fops;
134
135
136     printk("Adding VM device\n");
137     err = cdev_add(&(guest->cdev), guest->vm_dev, 1);
138
139     if (err) {
140         printk("Fails to add cdev\n");
141         return -1;
142     }
143
144     if (device_create(v3_class, NULL, guest->vm_dev, guest, "v3-vm%d", MINOR(guest->vm_dev)) == NULL){
145         printk("Fails to create device\n");
146         return -1;
147     }
148
149     complete(&(guest->start_done));
150
151     printk("palacios: launching vm\n");   
152
153
154
155 #if 0
156     // Inspection Test
157     {
158         struct v3_inspection_value rax;
159         v3_inspect_node_t * core = NULL;
160         v3_inspect_node_t * gprs = NULL;
161         v3_inspect_node_t * root = v3_get_inspection_root(guest->v3_ctx);
162         
163         if (!root) {
164             printk("NULL root inspection tree\n");
165         }
166
167         core = v3_get_inspection_subtree(root, "core.0");
168         if (!core) {
169             printk("NULL core inspection tree\n");
170         }
171
172         gprs = v3_get_inspection_subtree(core, "GPRS");
173         if (!gprs) {
174             printk("NULL gprs inspection tree\n");
175         }
176         
177         v3_get_inspection_value(gprs, "RAX", &rax);
178
179         debugfs_create_u64("RAX", 0644, NULL, (u64 *)rax.value);
180     }
181 #endif
182
183
184     if (v3_start_vm(guest->v3_ctx, 0xffffffff) < 0) { 
185         printk("palacios: launch of vm failed\n");
186         return -1;
187     }
188     
189     complete(&(guest->thread_done));
190
191     printk("palacios: vm completed.  returning.\n");
192
193     return 0;
194 }
195
196
197
198
199 int stop_palacios_vm(struct v3_guest * guest) {
200
201     v3_stop_vm(guest->v3_ctx);
202
203     wait_for_completion(&(guest->thread_done));
204
205     v3_free_vm(guest->v3_ctx);
206     
207     device_destroy(v3_class, guest->vm_dev);
208
209     cdev_del(&(guest->cdev));
210
211     kfree(guest->img);
212     kfree(guest);
213
214     return 0;
215 }