Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 118214
b: refs/heads/master
c: ad5173f
h: refs/heads/master
v: v3
  • Loading branch information
Rusty Russell committed Oct 31, 2008
1 parent 570f366 commit db618a3
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 13 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d5d02d6dd394b295abcadd6b0ce4932c07916fdf
refs/heads/master: ad5173ff8a387191dbacf889becb92c59aba5d59
29 changes: 17 additions & 12 deletions trunk/arch/x86/lguest/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* name like "FPUTRAP bit" be a little less cryptic?
*
* We store cr0 (and cr3) locally, because the Host never changes it. The
* Guest sometimes wants to read it and we'd prefer not to bother the Host
* unnecessarily. */
static unsigned long current_cr0, current_cr3;
* We store cr0 locally because the Host never changes it. The Guest sometimes
* wants to read it and we'd prefer not to bother the Host unnecessarily. */
static unsigned long current_cr0;
static void lguest_write_cr0(unsigned long val)
{
lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0);
Expand Down Expand Up @@ -399,17 +398,23 @@ static unsigned long lguest_read_cr2(void)
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
* 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)
{
lguest_data.pgdir = cr3;
lazy_hcall(LHCALL_NEW_PGTABLE, cr3, 0, 0);
current_cr3 = cr3;
cr3_changed = true;
}

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. */
Expand Down Expand Up @@ -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.
*
* ... 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
* anything changed until we've done the first page table switch. */
* which makes booting astonishingly slow: 1.83 seconds! So we don't even tell
* 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)
{
*ptep = pteval;
/* Don't bother with hypercall before initial setup. */
if (current_cr3)
if (cr3_changed)
lazy_hcall(LHCALL_FLUSH_TLB, 1, 0, 0);
}

Expand All @@ -521,7 +526,7 @@ static void lguest_set_pte(pte_t *ptep, pte_t pteval)
static void lguest_flush_tlb_single(unsigned long addr)
{
/* 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.
Expand Down

0 comments on commit db618a3

Please sign in to comment.