diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-28 21:16:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-28 21:16:26 -0400 |
commit | 7874d35173d549c1a2b2f77c4b1f94379fa65698 (patch) | |
tree | 995aa7212619dbdebb43b124cae2378562dd3065 /drivers | |
parent | 5dfb66ba8c4a96eb732942c9f78629e4db1a51d4 (diff) | |
parent | 8c79873da0d2bedf4ad6b868c54e426bb0a2fe38 (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.c | 1 | ||||
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 24 | ||||
-rw-r--r-- | drivers/lguest/x86/core.c | 4 |
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. */ |
407 | static void default_idt_entry(struct desc_struct *idt, | 407 | static 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 | } |