aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/lguest
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2011-07-22 01:09:48 -0400
committerRusty Russell <rusty@rustcorp.com.au>2011-07-22 01:09:48 -0400
commit5dea1c88ed11a1221581c4b202f053c4fc138704 (patch)
tree59e15d3c696712e26ffb229ff987f33bcc72affe /arch/x86/lguest
parente0377e25206328998d036cafddcd00a7c3252e3e (diff)
lguest: use a special 1:1 linear pagetable mode until first switch.
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 d50d8fe19 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>
Diffstat (limited to 'arch/x86/lguest')
-rw-r--r--arch/x86/lguest/boot.c11
-rw-r--r--arch/x86/lguest/i386_head.S9
2 files changed, 12 insertions, 8 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index db832fd65ecb..719a32c60516 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -520,17 +520,16 @@ static unsigned long lguest_read_cr2(void)
520 520
521/* See lguest_set_pte() below. */ 521/* See lguest_set_pte() below. */
522static bool cr3_changed = false; 522static bool cr3_changed = false;
523static unsigned long current_cr3;
523 524
524/* 525/*
525 * cr3 is the current toplevel pagetable page: the principle is the same as 526 * cr3 is the current toplevel pagetable page: the principle is the same as
526 * cr0. Keep a local copy, and tell the Host when it changes. The only 527 * cr0. Keep a local copy, and tell the Host when it changes.
527 * difference is that our local copy is in lguest_data because the Host needs
528 * to set it upon our initial hypercall.
529 */ 528 */
530static void lguest_write_cr3(unsigned long cr3) 529static void lguest_write_cr3(unsigned long cr3)
531{ 530{
532 lguest_data.pgdir = cr3;
533 lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); 531 lazy_hcall1(LHCALL_NEW_PGTABLE, cr3);
532 current_cr3 = cr3;
534 533
535 /* These two page tables are simple, linear, and used during boot */ 534 /* These two page tables are simple, linear, and used during boot */
536 if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) 535 if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table))
@@ -539,7 +538,7 @@ static void lguest_write_cr3(unsigned long cr3)
539 538
540static unsigned long lguest_read_cr3(void) 539static unsigned long lguest_read_cr3(void)
541{ 540{
542 return lguest_data.pgdir; 541 return current_cr3;
543} 542}
544 543
545/* cr4 is used to enable and disable PGE, but we don't care. */ 544/* cr4 is used to enable and disable PGE, but we don't care. */
@@ -758,7 +757,7 @@ static void lguest_pmd_clear(pmd_t *pmdp)
758static void lguest_flush_tlb_single(unsigned long addr) 757static void lguest_flush_tlb_single(unsigned long addr)
759{ 758{
760 /* Simply set it to zero: if it was not, it will fault back in. */ 759 /* Simply set it to zero: if it was not, it will fault back in. */
761 lazy_hcall3(LHCALL_SET_PTE, lguest_data.pgdir, addr, 0); 760 lazy_hcall3(LHCALL_SET_PTE, current_cr3, addr, 0);
762} 761}
763 762
764/* 763/*
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S
index 4f420c2f2d55..863b03a9fbff 100644
--- a/arch/x86/lguest/i386_head.S
+++ b/arch/x86/lguest/i386_head.S
@@ -27,13 +27,18 @@
27.section .init.text, "ax", @progbits 27.section .init.text, "ax", @progbits
28ENTRY(lguest_entry) 28ENTRY(lguest_entry)
29 /* 29 /*
30 * We make the "initialization" hypercall now to tell the Host about 30 * We make the "initialization" hypercall now to tell the Host where
31 * us, and also find out where it put our page tables. 31 * our lguest_data struct is.
32 */ 32 */
33 movl $LHCALL_LGUEST_INIT, %eax 33 movl $LHCALL_LGUEST_INIT, %eax
34 movl $lguest_data - __PAGE_OFFSET, %ebx 34 movl $lguest_data - __PAGE_OFFSET, %ebx
35 int $LGUEST_TRAP_ENTRY 35 int $LGUEST_TRAP_ENTRY
36 36
37 /* Now turn our pagetables on; setup by arch/x86/kernel/head_32.S. */
38 movl $LHCALL_NEW_PGTABLE, %eax
39 movl $(initial_page_table - __PAGE_OFFSET), %ebx
40 int $LGUEST_TRAP_ENTRY
41
37 /* Set up the initial stack so we can run C code. */ 42 /* Set up the initial stack so we can run C code. */
38 movl $(init_thread_union+THREAD_SIZE),%esp 43 movl $(init_thread_union+THREAD_SIZE),%esp
39 44