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>
这个提交包含在:
@@ -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))
|
||||
@@ -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. */
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -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
|
||||
|
||||
|
在新工单中引用
屏蔽一个用户