aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest/lguest_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest/lguest_user.c')
-rw-r--r--drivers/lguest/lguest_user.c147
1 files changed, 92 insertions, 55 deletions
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 3b92a61ba8d2..85d42d3d01a9 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -6,6 +6,7 @@
6#include <linux/uaccess.h> 6#include <linux/uaccess.h>
7#include <linux/miscdevice.h> 7#include <linux/miscdevice.h>
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/sched.h>
9#include "lg.h" 10#include "lg.h"
10 11
11/*L:055 When something happens, the Waker process needs a way to stop the 12/*L:055 When something happens, the Waker process needs a way to stop the
@@ -13,7 +14,7 @@
13 * LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher 14 * LHREQ_BREAK and the value "1" to /dev/lguest to do this. Once the Launcher
14 * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release 15 * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release
15 * the Waker. */ 16 * the Waker. */
16static int break_guest_out(struct lguest *lg, const unsigned long __user *input) 17static int break_guest_out(struct lg_cpu *cpu, const unsigned long __user*input)
17{ 18{
18 unsigned long on; 19 unsigned long on;
19 20
@@ -22,21 +23,21 @@ static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
22 return -EFAULT; 23 return -EFAULT;
23 24
24 if (on) { 25 if (on) {
25 lg->break_out = 1; 26 cpu->break_out = 1;
26 /* Pop it out of the Guest (may be running on different CPU) */ 27 /* Pop it out of the Guest (may be running on different CPU) */
27 wake_up_process(lg->tsk); 28 wake_up_process(cpu->tsk);
28 /* Wait for them to reset it */ 29 /* Wait for them to reset it */
29 return wait_event_interruptible(lg->break_wq, !lg->break_out); 30 return wait_event_interruptible(cpu->break_wq, !cpu->break_out);
30 } else { 31 } else {
31 lg->break_out = 0; 32 cpu->break_out = 0;
32 wake_up(&lg->break_wq); 33 wake_up(&cpu->break_wq);
33 return 0; 34 return 0;
34 } 35 }
35} 36}
36 37
37/*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt 38/*L:050 Sending an interrupt is done by writing LHREQ_IRQ and an interrupt
38 * number to /dev/lguest. */ 39 * number to /dev/lguest. */
39static int user_send_irq(struct lguest *lg, const unsigned long __user *input) 40static int user_send_irq(struct lg_cpu *cpu, const unsigned long __user *input)
40{ 41{
41 unsigned long irq; 42 unsigned long irq;
42 43
@@ -46,7 +47,7 @@ static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
46 return -EINVAL; 47 return -EINVAL;
47 /* Next time the Guest runs, the core code will see if it can deliver 48 /* Next time the Guest runs, the core code will see if it can deliver
48 * this interrupt. */ 49 * this interrupt. */
49 set_bit(irq, lg->irqs_pending); 50 set_bit(irq, cpu->irqs_pending);
50 return 0; 51 return 0;
51} 52}
52 53
@@ -55,13 +56,21 @@ static int user_send_irq(struct lguest *lg, const unsigned long __user *input)
55static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) 56static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
56{ 57{
57 struct lguest *lg = file->private_data; 58 struct lguest *lg = file->private_data;
59 struct lg_cpu *cpu;
60 unsigned int cpu_id = *o;
58 61
59 /* You must write LHREQ_INITIALIZE first! */ 62 /* You must write LHREQ_INITIALIZE first! */
60 if (!lg) 63 if (!lg)
61 return -EINVAL; 64 return -EINVAL;
62 65
66 /* Watch out for arbitrary vcpu indexes! */
67 if (cpu_id >= lg->nr_cpus)
68 return -EINVAL;
69
70 cpu = &lg->cpus[cpu_id];
71
63 /* If you're not the task which owns the Guest, go away. */ 72 /* If you're not the task which owns the Guest, go away. */
64 if (current != lg->tsk) 73 if (current != cpu->tsk)
65 return -EPERM; 74 return -EPERM;
66 75
67 /* If the guest is already dead, we indicate why */ 76 /* If the guest is already dead, we indicate why */
@@ -81,11 +90,53 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
81 90
82 /* If we returned from read() last time because the Guest notified, 91 /* If we returned from read() last time because the Guest notified,
83 * clear the flag. */ 92 * clear the flag. */
84 if (lg->pending_notify) 93 if (cpu->pending_notify)
85 lg->pending_notify = 0; 94 cpu->pending_notify = 0;
86 95
87 /* Run the Guest until something interesting happens. */ 96 /* Run the Guest until something interesting happens. */
88 return run_guest(lg, (unsigned long __user *)user); 97 return run_guest(cpu, (unsigned long __user *)user);
98}
99
100static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
101{
102 if (id >= NR_CPUS)
103 return -EINVAL;
104
105 cpu->id = id;
106 cpu->lg = container_of((cpu - id), struct lguest, cpus[0]);
107 cpu->lg->nr_cpus++;
108 init_clockdev(cpu);
109
110 /* We need a complete page for the Guest registers: they are accessible
111 * to the Guest and we can only grant it access to whole pages. */
112 cpu->regs_page = get_zeroed_page(GFP_KERNEL);
113 if (!cpu->regs_page)
114 return -ENOMEM;
115
116 /* We actually put the registers at the bottom of the page. */
117 cpu->regs = (void *)cpu->regs_page + PAGE_SIZE - sizeof(*cpu->regs);
118
119 /* Now we initialize the Guest's registers, handing it the start
120 * address. */
121 lguest_arch_setup_regs(cpu, start_ip);
122
123 /* Initialize the queue for the waker to wait on */
124 init_waitqueue_head(&cpu->break_wq);
125
126 /* We keep a pointer to the Launcher task (ie. current task) for when
127 * other Guests want to wake this one (inter-Guest I/O). */
128 cpu->tsk = current;
129
130 /* We need to keep a pointer to the Launcher's memory map, because if
131 * the Launcher dies we need to clean it up. If we don't keep a
132 * reference, it is destroyed before close() is called. */
133 cpu->mm = get_task_mm(cpu->tsk);
134
135 /* We remember which CPU's pages this Guest used last, for optimization
136 * when the same Guest runs on the same CPU twice. */
137 cpu->last_pages = NULL;
138
139 return 0;
89} 140}
90 141
91/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit) 142/*L:020 The initialization write supplies 4 pointer sized (32 or 64 bit)
@@ -134,15 +185,10 @@ static int initialize(struct file *file, const unsigned long __user *input)
134 lg->mem_base = (void __user *)(long)args[0]; 185 lg->mem_base = (void __user *)(long)args[0];
135 lg->pfn_limit = args[1]; 186 lg->pfn_limit = args[1];
136 187
137 /* We need a complete page for the Guest registers: they are accessible 188 /* This is the first cpu */
138 * to the Guest and we can only grant it access to whole pages. */ 189 err = lg_cpu_start(&lg->cpus[0], 0, args[3]);
139 lg->regs_page = get_zeroed_page(GFP_KERNEL); 190 if (err)
140 if (!lg->regs_page) {
141 err = -ENOMEM;
142 goto release_guest; 191 goto release_guest;
143 }
144 /* We actually put the registers at the bottom of the page. */
145 lg->regs = (void *)lg->regs_page + PAGE_SIZE - sizeof(*lg->regs);
146 192
147 /* Initialize the Guest's shadow page tables, using the toplevel 193 /* Initialize the Guest's shadow page tables, using the toplevel
148 * address the Launcher gave us. This allocates memory, so can 194 * address the Launcher gave us. This allocates memory, so can
@@ -151,28 +197,6 @@ static int initialize(struct file *file, const unsigned long __user *input)
151 if (err) 197 if (err)
152 goto free_regs; 198 goto free_regs;
153 199
154 /* Now we initialize the Guest's registers, handing it the start
155 * address. */
156 lguest_arch_setup_regs(lg, args[3]);
157
158 /* The timer for lguest's clock needs initialization. */
159 init_clockdev(lg);
160
161 /* We keep a pointer to the Launcher task (ie. current task) for when
162 * other Guests want to wake this one (inter-Guest I/O). */
163 lg->tsk = current;
164 /* We need to keep a pointer to the Launcher's memory map, because if
165 * the Launcher dies we need to clean it up. If we don't keep a
166 * reference, it is destroyed before close() is called. */
167 lg->mm = get_task_mm(lg->tsk);
168
169 /* Initialize the queue for the waker to wait on */
170 init_waitqueue_head(&lg->break_wq);
171
172 /* We remember which CPU's pages this Guest used last, for optimization
173 * when the same Guest runs on the same CPU twice. */
174 lg->last_pages = NULL;
175
176 /* We keep our "struct lguest" in the file's private_data. */ 200 /* We keep our "struct lguest" in the file's private_data. */
177 file->private_data = lg; 201 file->private_data = lg;
178 202
@@ -182,7 +206,8 @@ static int initialize(struct file *file, const unsigned long __user *input)
182 return sizeof(args); 206 return sizeof(args);
183 207
184free_regs: 208free_regs:
185 free_page(lg->regs_page); 209 /* FIXME: This should be in free_vcpu */
210 free_page(lg->cpus[0].regs_page);
186release_guest: 211release_guest:
187 kfree(lg); 212 kfree(lg);
188unlock: 213unlock:
@@ -202,30 +227,37 @@ static ssize_t write(struct file *file, const char __user *in,
202 struct lguest *lg = file->private_data; 227 struct lguest *lg = file->private_data;
203 const unsigned long __user *input = (const unsigned long __user *)in; 228 const unsigned long __user *input = (const unsigned long __user *)in;
204 unsigned long req; 229 unsigned long req;
230 struct lg_cpu *uninitialized_var(cpu);
231 unsigned int cpu_id = *off;
205 232
206 if (get_user(req, input) != 0) 233 if (get_user(req, input) != 0)
207 return -EFAULT; 234 return -EFAULT;
208 input++; 235 input++;
209 236
210 /* If you haven't initialized, you must do that first. */ 237 /* If you haven't initialized, you must do that first. */
211 if (req != LHREQ_INITIALIZE && !lg) 238 if (req != LHREQ_INITIALIZE) {
212 return -EINVAL; 239 if (!lg || (cpu_id >= lg->nr_cpus))
240 return -EINVAL;
241 cpu = &lg->cpus[cpu_id];
242 if (!cpu)
243 return -EINVAL;
244 }
213 245
214 /* Once the Guest is dead, all you can do is read() why it died. */ 246 /* Once the Guest is dead, all you can do is read() why it died. */
215 if (lg && lg->dead) 247 if (lg && lg->dead)
216 return -ENOENT; 248 return -ENOENT;
217 249
218 /* If you're not the task which owns the Guest, you can only break */ 250 /* If you're not the task which owns the Guest, you can only break */
219 if (lg && current != lg->tsk && req != LHREQ_BREAK) 251 if (lg && current != cpu->tsk && req != LHREQ_BREAK)
220 return -EPERM; 252 return -EPERM;
221 253
222 switch (req) { 254 switch (req) {
223 case LHREQ_INITIALIZE: 255 case LHREQ_INITIALIZE:
224 return initialize(file, input); 256 return initialize(file, input);
225 case LHREQ_IRQ: 257 case LHREQ_IRQ:
226 return user_send_irq(lg, input); 258 return user_send_irq(cpu, input);
227 case LHREQ_BREAK: 259 case LHREQ_BREAK:
228 return break_guest_out(lg, input); 260 return break_guest_out(cpu, input);
229 default: 261 default:
230 return -EINVAL; 262 return -EINVAL;
231 } 263 }
@@ -241,6 +273,7 @@ static ssize_t write(struct file *file, const char __user *in,
241static int close(struct inode *inode, struct file *file) 273static int close(struct inode *inode, struct file *file)
242{ 274{
243 struct lguest *lg = file->private_data; 275 struct lguest *lg = file->private_data;
276 unsigned int i;
244 277
245 /* If we never successfully initialized, there's nothing to clean up */ 278 /* If we never successfully initialized, there's nothing to clean up */
246 if (!lg) 279 if (!lg)
@@ -249,19 +282,23 @@ static int close(struct inode *inode, struct file *file)
249 /* We need the big lock, to protect from inter-guest I/O and other 282 /* We need the big lock, to protect from inter-guest I/O and other
250 * Launchers initializing guests. */ 283 * Launchers initializing guests. */
251 mutex_lock(&lguest_lock); 284 mutex_lock(&lguest_lock);
252 /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */ 285
253 hrtimer_cancel(&lg->hrt);
254 /* Free up the shadow page tables for the Guest. */ 286 /* Free up the shadow page tables for the Guest. */
255 free_guest_pagetable(lg); 287 free_guest_pagetable(lg);
256 /* Now all the memory cleanups are done, it's safe to release the 288
257 * Launcher's memory management structure. */ 289 for (i = 0; i < lg->nr_cpus; i++) {
258 mmput(lg->mm); 290 /* Cancels the hrtimer set via LHCALL_SET_CLOCKEVENT. */
291 hrtimer_cancel(&lg->cpus[i].hrt);
292 /* We can free up the register page we allocated. */
293 free_page(lg->cpus[i].regs_page);
294 /* Now all the memory cleanups are done, it's safe to release
295 * the Launcher's memory management structure. */
296 mmput(lg->cpus[i].mm);
297 }
259 /* If lg->dead doesn't contain an error code it will be NULL or a 298 /* If lg->dead doesn't contain an error code it will be NULL or a
260 * kmalloc()ed string, either of which is ok to hand to kfree(). */ 299 * kmalloc()ed string, either of which is ok to hand to kfree(). */
261 if (!IS_ERR(lg->dead)) 300 if (!IS_ERR(lg->dead))
262 kfree(lg->dead); 301 kfree(lg->dead);
263 /* We can free up the register page we allocated. */
264 free_page(lg->regs_page);
265 /* We clear the entire structure, which also marks it as free for the 302 /* We clear the entire structure, which also marks it as free for the
266 * next user. */ 303 * next user. */
267 memset(lg, 0, sizeof(*lg)); 304 memset(lg, 0, sizeof(*lg));