diff options
author | Jeremy Fitzhardinge <jeremy@xensource.com> | 2007-07-17 21:37:04 -0400 |
---|---|---|
committer | Jeremy Fitzhardinge <jeremy@goop.org> | 2007-07-18 11:47:42 -0400 |
commit | 3b827c1b3aadf3adb4c602d19863f2d24e7cbc18 (patch) | |
tree | c889f2e3023102be09173d53dd3620567c9e6fe3 /arch/i386/xen/enlighten.c | |
parent | 5ead97c84fa7d63a6a7a2f4e9f18f452bd109045 (diff) |
xen: virtual mmu
Xen pagetable handling, including the machinery to implement direct
pagetables.
Xen presents the real CPU's pagetables directly to guests, with no
added shadowing or other layer of abstraction. Naturally this means
the hypervisor must maintain close control over what the guest can put
into the pagetable.
When the guest modifies the pte/pmd/pgd, it must convert its
domain-specific notion of a "physical" pfn into a global machine frame
number (mfn) before inserting the entry into the pagetable. Xen will
check to make sure the domain is allowed to create a mapping of the
given mfn.
Xen also requires that all mappings the guest has of its own active
pagetable are read-only. This is relatively easy to implement in
Linux because all pagetables share the same pte pages for kernel
mappings, so updating the pte in one pagetable will implicitly update
the mapping in all pagetables.
Normally a pagetable becomes active when you point to it with cr3 (or
the Xen equivalent), but when you do so, Xen must check the whole
pagetable for correctness, which is clearly a performance problem.
Xen solves this with pinning which keeps a pagetable effectively
active even if its currently unused, which means that all the normal
update rules are enforced. This means that it need not revalidate the
pagetable when loading cr3.
This patch has a first-cut implementation of pinning, but it is more
fully implemented in a later patch.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Chris Wright <chrisw@sous-sol.org>
Diffstat (limited to 'arch/i386/xen/enlighten.c')
-rw-r--r-- | arch/i386/xen/enlighten.c | 30 |
1 files changed, 26 insertions, 4 deletions
diff --git a/arch/i386/xen/enlighten.c b/arch/i386/xen/enlighten.c index 2d484f9320de..c0b0aa7af145 100644 --- a/arch/i386/xen/enlighten.c +++ b/arch/i386/xen/enlighten.c | |||
@@ -39,6 +39,7 @@ | |||
39 | #include <asm/pgtable.h> | 39 | #include <asm/pgtable.h> |
40 | 40 | ||
41 | #include "xen-ops.h" | 41 | #include "xen-ops.h" |
42 | #include "mmu.h" | ||
42 | #include "multicalls.h" | 43 | #include "multicalls.h" |
43 | 44 | ||
44 | EXPORT_SYMBOL_GPL(hypercall_page); | 45 | EXPORT_SYMBOL_GPL(hypercall_page); |
@@ -579,11 +580,9 @@ static __init void xen_pagetable_setup_done(pgd_t *base) | |||
579 | * Should be set_fixmap(), but shared_info is a machine | 580 | * Should be set_fixmap(), but shared_info is a machine |
580 | * address with no corresponding pseudo-phys address. | 581 | * address with no corresponding pseudo-phys address. |
581 | */ | 582 | */ |
582 | #if 0 | ||
583 | set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP), | 583 | set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP), |
584 | PFN_DOWN(xen_start_info->shared_info), | 584 | PFN_DOWN(xen_start_info->shared_info), |
585 | PAGE_KERNEL); | 585 | PAGE_KERNEL); |
586 | #endif | ||
587 | 586 | ||
588 | HYPERVISOR_shared_info = | 587 | HYPERVISOR_shared_info = |
589 | (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); | 588 | (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP); |
@@ -592,9 +591,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base) | |||
592 | HYPERVISOR_shared_info = | 591 | HYPERVISOR_shared_info = |
593 | (struct shared_info *)__va(xen_start_info->shared_info); | 592 | (struct shared_info *)__va(xen_start_info->shared_info); |
594 | 593 | ||
595 | #if 0 | ||
596 | xen_pgd_pin(base); | 594 | xen_pgd_pin(base); |
597 | #endif | ||
598 | 595 | ||
599 | xen_vcpu_setup(smp_processor_id()); | 596 | xen_vcpu_setup(smp_processor_id()); |
600 | } | 597 | } |
@@ -690,6 +687,31 @@ static const struct paravirt_ops xen_paravirt_ops __initdata = { | |||
690 | .release_pd = xen_release_pd, | 687 | .release_pd = xen_release_pd, |
691 | .release_pt = xen_release_pt, | 688 | .release_pt = xen_release_pt, |
692 | 689 | ||
690 | .set_pte = xen_set_pte, | ||
691 | .set_pte_at = xen_set_pte_at, | ||
692 | .set_pmd = xen_set_pmd, | ||
693 | |||
694 | .pte_val = xen_pte_val, | ||
695 | .pgd_val = xen_pgd_val, | ||
696 | |||
697 | .make_pte = xen_make_pte, | ||
698 | .make_pgd = xen_make_pgd, | ||
699 | |||
700 | #ifdef CONFIG_X86_PAE | ||
701 | .set_pte_atomic = xen_set_pte_atomic, | ||
702 | .set_pte_present = xen_set_pte_at, | ||
703 | .set_pud = xen_set_pud, | ||
704 | .pte_clear = xen_pte_clear, | ||
705 | .pmd_clear = xen_pmd_clear, | ||
706 | |||
707 | .make_pmd = xen_make_pmd, | ||
708 | .pmd_val = xen_pmd_val, | ||
709 | #endif /* PAE */ | ||
710 | |||
711 | .activate_mm = xen_activate_mm, | ||
712 | .dup_mmap = xen_dup_mmap, | ||
713 | .exit_mmap = xen_exit_mmap, | ||
714 | |||
693 | .set_lazy_mode = xen_set_lazy_mode, | 715 | .set_lazy_mode = xen_set_lazy_mode, |
694 | }; | 716 | }; |
695 | 717 | ||