aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/lguest
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/lguest')
-rw-r--r--drivers/lguest/lguest_device.c93
-rw-r--r--drivers/lguest/lguest_user.c4
-rw-r--r--drivers/lguest/x86/core.c15
3 files changed, 61 insertions, 51 deletions
diff --git a/drivers/lguest/lguest_device.c b/drivers/lguest/lguest_device.c
index 2bc9bf7e88e5..1a8de57289eb 100644
--- a/drivers/lguest/lguest_device.c
+++ b/drivers/lguest/lguest_device.c
@@ -20,14 +20,11 @@
20/* The pointer to our (page) of device descriptions. */ 20/* The pointer to our (page) of device descriptions. */
21static void *lguest_devices; 21static void *lguest_devices;
22 22
23/* Unique numbering for lguest devices. */
24static unsigned int dev_index;
25
26/* For Guests, device memory can be used as normal memory, so we cast away the 23/* For Guests, device memory can be used as normal memory, so we cast away the
27 * __iomem to quieten sparse. */ 24 * __iomem to quieten sparse. */
28static inline void *lguest_map(unsigned long phys_addr, unsigned long pages) 25static inline void *lguest_map(unsigned long phys_addr, unsigned long pages)
29{ 26{
30 return (__force void *)ioremap(phys_addr, PAGE_SIZE*pages); 27 return (__force void *)ioremap_cache(phys_addr, PAGE_SIZE*pages);
31} 28}
32 29
33static inline void lguest_unmap(void *addr) 30static inline void lguest_unmap(void *addr)
@@ -85,27 +82,34 @@ static unsigned desc_size(const struct lguest_device_desc *desc)
85 + desc->config_len; 82 + desc->config_len;
86} 83}
87 84
88/* This tests (and acknowleges) a feature bit. */ 85/* This gets the device's feature bits. */
89static bool lg_feature(struct virtio_device *vdev, unsigned fbit) 86static u32 lg_get_features(struct virtio_device *vdev)
90{ 87{
88 unsigned int i;
89 u32 features = 0;
91 struct lguest_device_desc *desc = to_lgdev(vdev)->desc; 90 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
92 u8 *features; 91 u8 *in_features = lg_features(desc);
93 92
94 /* Obviously if they ask for a feature off the end of our feature 93 /* We do this the slow but generic way. */
95 * bitmap, it's not set. */ 94 for (i = 0; i < min(desc->feature_len * 8, 32); i++)
96 if (fbit / 8 > desc->feature_len) 95 if (in_features[i / 8] & (1 << (i % 8)))
97 return false; 96 features |= (1 << i);
98 97
99 /* The feature bitmap comes after the virtqueues. */ 98 return features;
100 features = lg_features(desc); 99}
101 if (!(features[fbit / 8] & (1 << (fbit % 8)))) 100
102 return false; 101static void lg_set_features(struct virtio_device *vdev, u32 features)
103 102{
104 /* We set the matching bit in the other half of the bitmap to tell the 103 unsigned int i;
105 * Host we want to use this feature. We don't use this yet, but we 104 struct lguest_device_desc *desc = to_lgdev(vdev)->desc;
106 * could in future. */ 105 /* Second half of bitmap is features we accept. */
107 features[desc->feature_len + fbit / 8] |= (1 << (fbit % 8)); 106 u8 *out_features = lg_features(desc) + desc->feature_len;
108 return true; 107
108 memset(out_features, 0, desc->feature_len);
109 for (i = 0; i < min(desc->feature_len * 8, 32); i++) {
110 if (features & (1 << i))
111 out_features[i / 8] |= (1 << (i % 8));
112 }
109} 113}
110 114
111/* Once they've found a field, getting a copy of it is easy. */ 115/* Once they've found a field, getting a copy of it is easy. */
@@ -137,20 +141,26 @@ static u8 lg_get_status(struct virtio_device *vdev)
137 return to_lgdev(vdev)->desc->status; 141 return to_lgdev(vdev)->desc->status;
138} 142}
139 143
144/* To notify on status updates, we (ab)use the NOTIFY hypercall, with the
145 * descriptor address of the device. A zero status means "reset". */
146static void set_status(struct virtio_device *vdev, u8 status)
147{
148 unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices;
149
150 /* We set the status. */
151 to_lgdev(vdev)->desc->status = status;
152 hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
153}
154
140static void lg_set_status(struct virtio_device *vdev, u8 status) 155static void lg_set_status(struct virtio_device *vdev, u8 status)
141{ 156{
142 BUG_ON(!status); 157 BUG_ON(!status);
143 to_lgdev(vdev)->desc->status = status; 158 set_status(vdev, status);
144} 159}
145 160
146/* To reset the device, we (ab)use the NOTIFY hypercall, with the descriptor
147 * address of the device. The Host will zero the status and all the
148 * features. */
149static void lg_reset(struct virtio_device *vdev) 161static void lg_reset(struct virtio_device *vdev)
150{ 162{
151 unsigned long offset = (void *)to_lgdev(vdev)->desc - lguest_devices; 163 set_status(vdev, 0);
152
153 hcall(LHCALL_NOTIFY, (max_pfn<<PAGE_SHIFT) + offset, 0, 0);
154} 164}
155 165
156/* 166/*
@@ -286,7 +296,8 @@ static void lg_del_vq(struct virtqueue *vq)
286 296
287/* The ops structure which hooks everything together. */ 297/* The ops structure which hooks everything together. */
288static struct virtio_config_ops lguest_config_ops = { 298static struct virtio_config_ops lguest_config_ops = {
289 .feature = lg_feature, 299 .get_features = lg_get_features,
300 .set_features = lg_set_features,
290 .get = lg_get, 301 .get = lg_get,
291 .set = lg_set, 302 .set = lg_set,
292 .get_status = lg_get_status, 303 .get_status = lg_get_status,
@@ -311,8 +322,10 @@ static struct device lguest_root = {
311 * As Andrew Tridgell says, "Untested code is buggy code". 322 * As Andrew Tridgell says, "Untested code is buggy code".
312 * 323 *
313 * It's worth reading this carefully: we start with a pointer to the new device 324 * It's worth reading this carefully: we start with a pointer to the new device
314 * descriptor in the "lguest_devices" page. */ 325 * descriptor in the "lguest_devices" page, and the offset into the device
315static void add_lguest_device(struct lguest_device_desc *d) 326 * descriptor page so we can uniquely identify it if things go badly wrong. */
327static void add_lguest_device(struct lguest_device_desc *d,
328 unsigned int offset)
316{ 329{
317 struct lguest_device *ldev; 330 struct lguest_device *ldev;
318 331
@@ -320,18 +333,14 @@ static void add_lguest_device(struct lguest_device_desc *d)
320 * it. */ 333 * it. */
321 ldev = kzalloc(sizeof(*ldev), GFP_KERNEL); 334 ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
322 if (!ldev) { 335 if (!ldev) {
323 printk(KERN_EMERG "Cannot allocate lguest dev %u\n", 336 printk(KERN_EMERG "Cannot allocate lguest dev %u type %u\n",
324 dev_index++); 337 offset, d->type);
325 return; 338 return;
326 } 339 }
327 340
328 /* This devices' parent is the lguest/ dir. */ 341 /* This devices' parent is the lguest/ dir. */
329 ldev->vdev.dev.parent = &lguest_root; 342 ldev->vdev.dev.parent = &lguest_root;
330 /* We have a unique device index thanks to the dev_index counter. */ 343 /* We have a unique device index thanks to the dev_index counter. */
331 ldev->vdev.index = dev_index++;
332 /* The device type comes straight from the descriptor. There's also a
333 * device vendor field in the virtio_device struct, which we leave as
334 * 0. */
335 ldev->vdev.id.device = d->type; 344 ldev->vdev.id.device = d->type;
336 /* We have a simple set of routines for querying the device's 345 /* We have a simple set of routines for querying the device's
337 * configuration information and setting its status. */ 346 * configuration information and setting its status. */
@@ -343,8 +352,8 @@ static void add_lguest_device(struct lguest_device_desc *d)
343 * virtio_device and calls device_register(). This makes the bus 352 * virtio_device and calls device_register(). This makes the bus
344 * infrastructure look for a matching driver. */ 353 * infrastructure look for a matching driver. */
345 if (register_virtio_device(&ldev->vdev) != 0) { 354 if (register_virtio_device(&ldev->vdev) != 0) {
346 printk(KERN_ERR "Failed to register lguest device %u\n", 355 printk(KERN_ERR "Failed to register lguest dev %u type %u\n",
347 ldev->vdev.index); 356 offset, d->type);
348 kfree(ldev); 357 kfree(ldev);
349 } 358 }
350} 359}
@@ -365,7 +374,7 @@ static void scan_devices(void)
365 break; 374 break;
366 375
367 printk("Device at %i has size %u\n", i, desc_size(d)); 376 printk("Device at %i has size %u\n", i, desc_size(d));
368 add_lguest_device(d); 377 add_lguest_device(d, i);
369 } 378 }
370} 379}
371 380
diff --git a/drivers/lguest/lguest_user.c b/drivers/lguest/lguest_user.c
index 645e6e040bfb..e73a000473cc 100644
--- a/drivers/lguest/lguest_user.c
+++ b/drivers/lguest/lguest_user.c
@@ -102,7 +102,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
102static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip) 102static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
103{ 103{
104 /* We have a limited number the number of CPUs in the lguest struct. */ 104 /* We have a limited number the number of CPUs in the lguest struct. */
105 if (id >= NR_CPUS) 105 if (id >= ARRAY_SIZE(cpu->lg->cpus))
106 return -EINVAL; 106 return -EINVAL;
107 107
108 /* Set up this CPU's id, and pointer back to the lguest struct. */ 108 /* Set up this CPU's id, and pointer back to the lguest struct. */
@@ -251,8 +251,6 @@ static ssize_t write(struct file *file, const char __user *in,
251 if (!lg || (cpu_id >= lg->nr_cpus)) 251 if (!lg || (cpu_id >= lg->nr_cpus))
252 return -EINVAL; 252 return -EINVAL;
253 cpu = &lg->cpus[cpu_id]; 253 cpu = &lg->cpus[cpu_id];
254 if (!cpu)
255 return -EINVAL;
256 254
257 /* Once the Guest is dead, you can only read() why it died. */ 255 /* Once the Guest is dead, you can only read() why it died. */
258 if (lg->dead) 256 if (lg->dead)
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 5126d5d9ea0e..2e554a4ab337 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -176,7 +176,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
176 * we set it now, so we can trap and pass that trap to the Guest if it 176 * we set it now, so we can trap and pass that trap to the Guest if it
177 * uses the FPU. */ 177 * uses the FPU. */
178 if (cpu->ts) 178 if (cpu->ts)
179 lguest_set_ts(); 179 unlazy_fpu(current);
180 180
181 /* SYSENTER is an optimized way of doing system calls. We can't allow 181 /* SYSENTER is an optimized way of doing system calls. We can't allow
182 * it because it always jumps to privilege level 0. A normal Guest 182 * it because it always jumps to privilege level 0. A normal Guest
@@ -196,6 +196,10 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
196 * trap made the switcher code come back, and an error code which some 196 * trap made the switcher code come back, and an error code which some
197 * traps set. */ 197 * traps set. */
198 198
199 /* Restore SYSENTER if it's supposed to be on. */
200 if (boot_cpu_has(X86_FEATURE_SEP))
201 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
202
199 /* If the Guest page faulted, then the cr2 register will tell us the 203 /* If the Guest page faulted, then the cr2 register will tell us the
200 * bad virtual address. We have to grab this now, because once we 204 * bad virtual address. We have to grab this now, because once we
201 * re-enable interrupts an interrupt could fault and thus overwrite 205 * re-enable interrupts an interrupt could fault and thus overwrite
@@ -203,13 +207,12 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
203 if (cpu->regs->trapnum == 14) 207 if (cpu->regs->trapnum == 14)
204 cpu->arch.last_pagefault = read_cr2(); 208 cpu->arch.last_pagefault = read_cr2();
205 /* Similarly, if we took a trap because the Guest used the FPU, 209 /* Similarly, if we took a trap because the Guest used the FPU,
206 * we have to restore the FPU it expects to see. */ 210 * we have to restore the FPU it expects to see.
211 * math_state_restore() may sleep and we may even move off to
212 * a different CPU. So all the critical stuff should be done
213 * before this. */
207 else if (cpu->regs->trapnum == 7) 214 else if (cpu->regs->trapnum == 7)
208 math_state_restore(); 215 math_state_restore();
209
210 /* Restore SYSENTER if it's supposed to be on. */
211 if (boot_cpu_has(X86_FEATURE_SEP))
212 wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
213} 216}
214 217
215/*H:130 Now we've examined the hypercall code; our Guest can make requests. 218/*H:130 Now we've examined the hypercall code; our Guest can make requests.