Skip to content

Commit

Permalink
lguest: use a special 1:1 linear pagetable mode until first switch.
Browse files Browse the repository at this point in the history
The Host used to create some page tables for the Guest to use at the
top of Guest memory; it would then tell the Guest where this was.  In
particular, it created linear mappings for 0 and 0xC0000000 addresses
because lguest used to switch to its real page tables quite late in
boot.

However, since d50d8fe Linux initialized boot page tables in
head_32.S even before the "are we lguest?" boot jump.  So, now we can
simplify things: the Host pagetable code assumes 1:1 linear mapping
until it first calls the LHCALL_NEW_PGTABLE hypercall, which we now do
before we reach C code.

This also means that the Host doesn't need to know anything about the
Guest's PAGE_OFFSET.  (Non-Linux guests might not even have such a
thing).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
Rusty Russell committed Jul 22, 2011
1 parent e0377e2 commit 5dea1c8
Show file tree
Hide file tree
Showing 6 changed files with 98 additions and 205 deletions.
1 change: 0 additions & 1 deletion arch/x86/kernel/asm-offsets_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ void foo(void)
BLANK();
OFFSET(LGUEST_DATA_irq_enabled, lguest_data, irq_enabled);
OFFSET(LGUEST_DATA_irq_pending, lguest_data, irq_pending);
OFFSET(LGUEST_DATA_pgdir, lguest_data, pgdir);

BLANK();
OFFSET(LGUEST_PAGES_host_gdt_desc, lguest_pages, state.host_gdt_desc);
Expand Down
11 changes: 5 additions & 6 deletions arch/x86/lguest/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,17 +520,16 @@ static unsigned long lguest_read_cr2(void)

/* See lguest_set_pte() below. */
static bool cr3_changed = false;
static unsigned long current_cr3;

/*
* 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. The only
* difference is that our local copy is in lguest_data because the Host needs
* to set it upon our initial hypercall.
* cr0. Keep a local copy, and tell the Host when it changes.
*/
static void lguest_write_cr3(unsigned long cr3)
{
lguest_data.pgdir = cr3;
lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
current_cr3 = cr3;

/* These two page tables are simple, linear, and used during boot */
if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
Expand All @@ -539,7 +538,7 @@ static void lguest_write_cr3(unsigned long cr3)

static unsigned long lguest_read_cr3(void)
{
return lguest_data.pgdir;
return current_cr3;
}

/* cr4 is used to enable and disable PGE, but we don't care. */
Expand Down Expand Up @@ -758,7 +757,7 @@ static void lguest_pmd_clear(pmd_t *pmdp)
static void lguest_flush_tlb_single(unsigned long addr)
{
/* Simply set it to zero: if it was not, it will fault back in. */
lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0);
lazy_hcall3(LHCALL_SET_PTE, current_cr3, addr, 0);
}

/*
Expand Down
9 changes: 7 additions & 2 deletions arch/x86/lguest/i386_head.S
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@
.section .init.text, "ax", @progbits
ENTRY(lguest_entry)
/*
* We make the "initialization" hypercall now to tell the Host about
* us, and also find out where it put our page tables.
* We make the "initialization" hypercall now to tell the Host where
* our lguest_data struct is.
*/
movl $LHCALL_LGUEST_INIT, %eax
movl $lguest_data - __PAGE_OFFSET, %ebx
int $LGUEST_TRAP_ENTRY

/* Now turn our pagetables on; setup by arch/x86/kernel/head_32.S. */
movl $LHCALL_NEW_PGTABLE, %eax
movl $(initial_page_table - __PAGE_OFFSET), %ebx
int $LGUEST_TRAP_ENTRY

/* Set up the initial stack so we can run C code. */
movl $(init_thread_union+THREAD_SIZE),%esp

Expand Down
2 changes: 2 additions & 0 deletions drivers/lguest/lg.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ struct lg_cpu {

struct lguest_pages *last_pages;

/* Initialization mode: linear map everything. */
bool linear_pages;
int cpu_pgd; /* Which pgd this cpu is currently using */

/* If a hypercall was asked for, this points to the arguments. */
Expand Down
Loading

0 comments on commit 5dea1c8

Please sign in to comment.