aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-28 21:16:26 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-28 21:16:26 -0400
commit7874d35173d549c1a2b2f77c4b1f94379fa65698 (patch)
tree995aa7212619dbdebb43b124cae2378562dd3065 /drivers
parent5dfb66ba8c4a96eb732942c9f78629e4db1a51d4 (diff)
parent8c79873da0d2bedf4ad6b868c54e426bb0a2fe38 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus
* git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus: lguest: turn Waker into a thread, not a process lguest: Enlarge virtio rings lguest: Use GSO/IFF_VNET_HDR extensions on tun/tap lguest: Remove 'network: no dma buffer!' warning lguest: Adaptive timeout lguest: Tell Guest net not to notify us on every packet xmit lguest: net block unneeded receive queue update notifications lguest: wrap last_avail accesses. lguest: use cpu capability accessors lguest: virtio-rng support lguest: Support assigning a MAC address lguest: Don't leak /dev/zero fd lguest: fix verbose printing of device features. lguest: fix switcher_page leak on unload lguest: Guest int3 fix lguest: set max_pfn_mapped, growl loudly at Yinghai Lu
Diffstat (limited to 'drivers')
-rw-r--r--drivers/lguest/core.c1
-rw-r--r--drivers/lguest/interrupts_and_traps.c24
-rw-r--r--drivers/lguest/x86/core.c4
3 files changed, 20 insertions, 9 deletions
diff --git a/drivers/lguest/core.c b/drivers/lguest/core.c
index 5eea4356d703..90663e01a56e 100644
--- a/drivers/lguest/core.c
+++ b/drivers/lguest/core.c
@@ -135,6 +135,7 @@ static void unmap_switcher(void)
135 /* Now we just need to free the pages we copied the switcher into */ 135 /* Now we just need to free the pages we copied the switcher into */
136 for (i = 0; i < TOTAL_SWITCHER_PAGES; i++) 136 for (i = 0; i < TOTAL_SWITCHER_PAGES; i++)
137 __free_pages(switcher_page[i], 0); 137 __free_pages(switcher_page[i], 0);
138 kfree(switcher_page);
138} 139}
139 140
140/*H:032 141/*H:032
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index 0414ddf87587..a1039068f95c 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -406,7 +406,8 @@ void load_guest_idt_entry(struct lg_cpu *cpu, unsigned int num, u32 lo, u32 hi)
406 * deliver_trap() to bounce it back into the Guest. */ 406 * deliver_trap() to bounce it back into the Guest. */
407static void default_idt_entry(struct desc_struct *idt, 407static void default_idt_entry(struct desc_struct *idt,
408 int trap, 408 int trap,
409 const unsigned long handler) 409 const unsigned long handler,
410 const struct desc_struct *base)
410{ 411{
411 /* A present interrupt gate. */ 412 /* A present interrupt gate. */
412 u32 flags = 0x8e00; 413 u32 flags = 0x8e00;
@@ -415,6 +416,10 @@ static void default_idt_entry(struct desc_struct *idt,
415 * the Guest to use the "int" instruction to trigger it. */ 416 * the Guest to use the "int" instruction to trigger it. */
416 if (trap == LGUEST_TRAP_ENTRY) 417 if (trap == LGUEST_TRAP_ENTRY)
417 flags |= (GUEST_PL << 13); 418 flags |= (GUEST_PL << 13);
419 else if (base)
420 /* Copy priv. level from what Guest asked for. This allows
421 * debug (int 3) traps from Guest userspace, for example. */
422 flags |= (base->b & 0x6000);
418 423
419 /* Now pack it into the IDT entry in its weird format. */ 424 /* Now pack it into the IDT entry in its weird format. */
420 idt->a = (LGUEST_CS<<16) | (handler&0x0000FFFF); 425 idt->a = (LGUEST_CS<<16) | (handler&0x0000FFFF);
@@ -428,7 +433,7 @@ void setup_default_idt_entries(struct lguest_ro_state *state,
428 unsigned int i; 433 unsigned int i;
429 434
430 for (i = 0; i < ARRAY_SIZE(state->guest_idt); i++) 435 for (i = 0; i < ARRAY_SIZE(state->guest_idt); i++)
431 default_idt_entry(&state->guest_idt[i], i, def[i]); 436 default_idt_entry(&state->guest_idt[i], i, def[i], NULL);
432} 437}
433 438
434/*H:240 We don't use the IDT entries in the "struct lguest" directly, instead 439/*H:240 We don't use the IDT entries in the "struct lguest" directly, instead
@@ -442,6 +447,8 @@ void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt,
442 /* We can simply copy the direct traps, otherwise we use the default 447 /* We can simply copy the direct traps, otherwise we use the default
443 * ones in the Switcher: they will return to the Host. */ 448 * ones in the Switcher: they will return to the Host. */
444 for (i = 0; i < ARRAY_SIZE(cpu->arch.idt); i++) { 449 for (i = 0; i < ARRAY_SIZE(cpu->arch.idt); i++) {
450 const struct desc_struct *gidt = &cpu->arch.idt[i];
451
445 /* If no Guest can ever override this trap, leave it alone. */ 452 /* If no Guest can ever override this trap, leave it alone. */
446 if (!direct_trap(i)) 453 if (!direct_trap(i))
447 continue; 454 continue;
@@ -449,12 +456,15 @@ void copy_traps(const struct lg_cpu *cpu, struct desc_struct *idt,
449 /* Only trap gates (type 15) can go direct to the Guest. 456 /* Only trap gates (type 15) can go direct to the Guest.
450 * Interrupt gates (type 14) disable interrupts as they are 457 * Interrupt gates (type 14) disable interrupts as they are
451 * entered, which we never let the Guest do. Not present 458 * entered, which we never let the Guest do. Not present
452 * entries (type 0x0) also can't go direct, of course. */ 459 * entries (type 0x0) also can't go direct, of course.
453 if (idt_type(cpu->arch.idt[i].a, cpu->arch.idt[i].b) == 0xF) 460 *
454 idt[i] = cpu->arch.idt[i]; 461 * If it can't go direct, we still need to copy the priv. level:
462 * they might want to give userspace access to a software
463 * interrupt. */
464 if (idt_type(gidt->a, gidt->b) == 0xF)
465 idt[i] = *gidt;
455 else 466 else
456 /* Reset it to the default. */ 467 default_idt_entry(&idt[i], i, def[i], gidt);
457 default_idt_entry(&idt[i], i, def[i]);
458 } 468 }
459} 469}
460 470
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 95dfda52b4f9..bf7942327bda 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -480,7 +480,7 @@ void __init lguest_arch_host_init(void)
480 * bit on its CPU, depending on the argument (0 == unset). */ 480 * bit on its CPU, depending on the argument (0 == unset). */
481 on_each_cpu(adjust_pge, (void *)0, 1); 481 on_each_cpu(adjust_pge, (void *)0, 1);
482 /* Turn off the feature in the global feature set. */ 482 /* Turn off the feature in the global feature set. */
483 clear_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability); 483 clear_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
484 } 484 }
485 put_online_cpus(); 485 put_online_cpus();
486}; 486};
@@ -491,7 +491,7 @@ void __exit lguest_arch_host_fini(void)
491 /* If we had PGE before we started, turn it back on now. */ 491 /* If we had PGE before we started, turn it back on now. */
492 get_online_cpus(); 492 get_online_cpus();
493 if (cpu_had_pge) { 493 if (cpu_had_pge) {
494 set_bit(X86_FEATURE_PGE, boot_cpu_data.x86_capability); 494 set_cpu_cap(&boot_cpu_data, X86_FEATURE_PGE);
495 /* adjust_pge's argument "1" means set PGE. */ 495 /* adjust_pge's argument "1" means set PGE. */
496 on_each_cpu(adjust_pge, (void *)1, 1); 496 on_each_cpu(adjust_pge, (void *)1, 1);
497 } 497 }