diff options
Diffstat (limited to 'drivers/lguest/lguest_user.c')
-rw-r--r-- | drivers/lguest/lguest_user.c | 147 |
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. */ |
16 | static int break_guest_out(struct lguest *lg, const unsigned long __user *input) | 17 | static 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. */ |
39 | static int user_send_irq(struct lguest *lg, const unsigned long __user *input) | 40 | static 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) | |||
55 | static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o) | 56 | static 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 | |||
100 | static 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 | ||
184 | free_regs: | 208 | free_regs: |
185 | free_page(lg->regs_page); | 209 | /* FIXME: This should be in free_vcpu */ |
210 | free_page(lg->cpus[0].regs_page); | ||
186 | release_guest: | 211 | release_guest: |
187 | kfree(lg); | 212 | kfree(lg); |
188 | unlock: | 213 | unlock: |
@@ -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, | |||
241 | static int close(struct inode *inode, struct file *file) | 273 | static 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)); |