Commit f2347dfc authored by Linus Torvalds's avatar Linus Torvalds

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: fix irq vectors.
  lguest: fix early_ioremap.
  lguest: fix example launcher compile after moved asm-x86 dir.
parents 74c75f52 526e5ab2
# This creates the demonstration utility "lguest" which runs a Linux guest. # This creates the demonstration utility "lguest" which runs a Linux guest.
CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 -I../../include -I../../arch/x86/include
LDLIBS:=-lz LDLIBS:=-lz
all: lguest all: lguest
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#include "linux/virtio_console.h" #include "linux/virtio_console.h"
#include "linux/virtio_rng.h" #include "linux/virtio_rng.h"
#include "linux/virtio_ring.h" #include "linux/virtio_ring.h"
#include "asm-x86/bootparam.h" #include "asm/bootparam.h"
/*L:110 We can ignore the 39 include files we need for this program, but I do /*L:110 We can ignore the 39 include files we need for this program, but I do
* want to draw attention to the use of kernel-style types. * want to draw attention to the use of kernel-style types.
* *
......
...@@ -367,10 +367,9 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx, ...@@ -367,10 +367,9 @@ static void lguest_cpuid(unsigned int *ax, unsigned int *bx,
* lazily after a task switch, and Linux uses that gratefully, but wouldn't a * lazily after a task switch, and Linux uses that gratefully, but wouldn't a
* name like "FPUTRAP bit" be a little less cryptic? * name like "FPUTRAP bit" be a little less cryptic?
* *
* We store cr0 (and cr3) locally, because the Host never changes it. The * We store cr0 locally because the Host never changes it. The Guest sometimes
* Guest sometimes wants to read it and we'd prefer not to bother the Host * wants to read it and we'd prefer not to bother the Host unnecessarily. */
* unnecessarily. */ static unsigned long current_cr0;
static unsigned long current_cr0, current_cr3;
static void lguest_write_cr0(unsigned long val) static void lguest_write_cr0(unsigned long val)
{ {
lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0); lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0);
...@@ -399,17 +398,23 @@ static unsigned long lguest_read_cr2(void) ...@@ -399,17 +398,23 @@ static unsigned long lguest_read_cr2(void)
return lguest_data.cr2; return lguest_data.cr2;
} }
/* See lguest_set_pte() below. */
static bool cr3_changed = false;
/* cr3 is the current toplevel pagetable page: the principle is the same as /* cr3 is the current toplevel pagetable page: the principle is the same as
* cr0. Keep a local copy, and tell the Host when it changes. */ * cr0. Keep a local copy, and tell the Host when it changes. The only
* difference is that our local copy is in lguest_data because the Host needs
* to set it upon our initial hypercall. */
static void lguest_write_cr3(unsigned long cr3) static void lguest_write_cr3(unsigned long cr3)
{ {
lguest_data.pgdir = cr3;
lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0); lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0);
current_cr3 = cr3; cr3_changed = true;
} }
static unsigned long lguest_read_cr3(void) static unsigned long lguest_read_cr3(void)
{ {
return current_cr3; return lguest_data.pgdir;
} }
/* cr4 is used to enable and disable PGE, but we don't care. */ /* cr4 is used to enable and disable PGE, but we don't care. */
...@@ -498,13 +503,13 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) ...@@ -498,13 +503,13 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
* to forget all of them. Fortunately, this is very rare. * to forget all of them. Fortunately, this is very rare.
* *
* ... except in early boot when the kernel sets up the initial pagetables, * ... except in early boot when the kernel sets up the initial pagetables,
* which makes booting astonishingly slow. So we don't even tell the Host * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell
* anything changed until we've done the first page table switch. */ * the Host anything changed until we've done the first page table switch,
* which brings boot back to 0.25 seconds. */
static void lguest_set_pte(pte_t *ptep, pte_t pteval) static void lguest_set_pte(pte_t *ptep, pte_t pteval)
{ {
*ptep = pteval; *ptep = pteval;
/* Don't bother with hypercall before initial setup. */ if (cr3_changed)
if (current_cr3)
lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0); lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
} }
...@@ -521,7 +526,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval) ...@@ -521,7 +526,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval)
static void lguest_flush_tlb_single(unsigned long addr) static void lguest_flush_tlb_single(unsigned long addr)
{ {
/* Simply set it to zero: if it was not, it will fault back in. */ /* Simply set it to zero: if it was not, it will fault back in. */
lazy_hcall(LHCALL_SET_PTE, current_cr3, addr, 0); lazy_hcall(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
} }
/* This is what happens after the Guest has removed a large number of entries. /* This is what happens after the Guest has removed a large number of entries.
...@@ -581,6 +586,9 @@ static void __init lguest_init_IRQ(void) ...@@ -581,6 +586,9 @@ static void __init lguest_init_IRQ(void)
for (i = 0; i < LGUEST_IRQS; i++) { for (i = 0; i < LGUEST_IRQS; i++) {
int vector = FIRST_EXTERNAL_VECTOR + i; int vector = FIRST_EXTERNAL_VECTOR + i;
/* Some systems map "vectors" to interrupts weirdly. Lguest has
* a straightforward 1 to 1 mapping, so force that here. */
__get_cpu_var(vector_irq)[vector] = i;
if (vector != SYSCALL_VECTOR) { if (vector != SYSCALL_VECTOR) {
set_intr_gate(vector, interrupt[vector]); set_intr_gate(vector, interrupt[vector]);
set_irq_chip_and_handler_name(i, &lguest_irq_controller, set_irq_chip_and_handler_name(i, &lguest_irq_controller,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment