diff options
author | Jeremy Fitzhardinge <jeremy@goop.org> | 2008-01-30 07:33:39 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:33:39 -0500 |
commit | 1c70e9bd832642b712181e32d1bbf2436058a3df (patch) | |
tree | 3e9a57b7ae9d0357bb9727ac4ed9f77a3eb88d52 /arch/x86/xen/enlighten.c | |
parent | a5a19c63f4e55e32dc0bc3d936d7f94793d8b380 (diff) |
xen: deal with pmd being allocated/freed
Deal properly with pmd-level pages being allocated and freed
dynamically. We can handle them more or less the same as pte pages.
Also, deal with early_ioremap pagetable manipulations.
Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r-- | arch/x86/xen/enlighten.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 845b4fd94463..de647bc6e74d 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -658,6 +658,13 @@ static __init void xen_alloc_pt_init(struct mm_struct *mm, u32 pfn) | |||
658 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | 658 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); |
659 | } | 659 | } |
660 | 660 | ||
661 | /* Early release_pt assumes that all pts are pinned, since there's | ||
662 | only init_mm and anything attached to that is pinned. */ | ||
663 | static void xen_release_pt_init(u32 pfn) | ||
664 | { | ||
665 | make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); | ||
666 | } | ||
667 | |||
661 | static void pin_pagetable_pfn(unsigned level, unsigned long pfn) | 668 | static void pin_pagetable_pfn(unsigned level, unsigned long pfn) |
662 | { | 669 | { |
663 | struct mmuext_op op; | 670 | struct mmuext_op op; |
@@ -669,7 +676,7 @@ static void pin_pagetable_pfn(unsigned level, unsigned long pfn) | |||
669 | 676 | ||
670 | /* This needs to make sure the new pte page is pinned iff its being | 677 | /* This needs to make sure the new pte page is pinned iff its being |
671 | attached to a pinned pagetable. */ | 678 | attached to a pinned pagetable. */ |
672 | static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | 679 | static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level) |
673 | { | 680 | { |
674 | struct page *page = pfn_to_page(pfn); | 681 | struct page *page = pfn_to_page(pfn); |
675 | 682 | ||
@@ -678,7 +685,7 @@ static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | |||
678 | 685 | ||
679 | if (!PageHighMem(page)) { | 686 | if (!PageHighMem(page)) { |
680 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); | 687 | make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); |
681 | pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn); | 688 | pin_pagetable_pfn(level, pfn); |
682 | } else | 689 | } else |
683 | /* make sure there are no stray mappings of | 690 | /* make sure there are no stray mappings of |
684 | this page */ | 691 | this page */ |
@@ -686,6 +693,16 @@ static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | |||
686 | } | 693 | } |
687 | } | 694 | } |
688 | 695 | ||
696 | static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | ||
697 | { | ||
698 | xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L1_TABLE); | ||
699 | } | ||
700 | |||
701 | static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) | ||
702 | { | ||
703 | xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L2_TABLE); | ||
704 | } | ||
705 | |||
689 | /* This should never happen until we're OK to use struct page */ | 706 | /* This should never happen until we're OK to use struct page */ |
690 | static void xen_release_pt(u32 pfn) | 707 | static void xen_release_pt(u32 pfn) |
691 | { | 708 | { |
@@ -788,6 +805,9 @@ static __init void xen_pagetable_setup_done(pgd_t *base) | |||
788 | /* This will work as long as patching hasn't happened yet | 805 | /* This will work as long as patching hasn't happened yet |
789 | (which it hasn't) */ | 806 | (which it hasn't) */ |
790 | pv_mmu_ops.alloc_pt = xen_alloc_pt; | 807 | pv_mmu_ops.alloc_pt = xen_alloc_pt; |
808 | pv_mmu_ops.alloc_pd = xen_alloc_pd; | ||
809 | pv_mmu_ops.release_pt = xen_release_pt; | ||
810 | pv_mmu_ops.release_pd = xen_release_pt; | ||
791 | pv_mmu_ops.set_pte = xen_set_pte; | 811 | pv_mmu_ops.set_pte = xen_set_pte; |
792 | 812 | ||
793 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { | 813 | if (!xen_feature(XENFEAT_auto_translated_physmap)) { |
@@ -1011,10 +1031,10 @@ static const struct pv_mmu_ops xen_mmu_ops __initdata = { | |||
1011 | .pte_update_defer = paravirt_nop, | 1031 | .pte_update_defer = paravirt_nop, |
1012 | 1032 | ||
1013 | .alloc_pt = xen_alloc_pt_init, | 1033 | .alloc_pt = xen_alloc_pt_init, |
1014 | .release_pt = xen_release_pt, | 1034 | .release_pt = xen_release_pt_init, |
1015 | .alloc_pd = paravirt_nop, | 1035 | .alloc_pd = xen_alloc_pt_init, |
1016 | .alloc_pd_clone = paravirt_nop, | 1036 | .alloc_pd_clone = paravirt_nop, |
1017 | .release_pd = paravirt_nop, | 1037 | .release_pd = xen_release_pt_init, |
1018 | 1038 | ||
1019 | #ifdef CONFIG_HIGHPTE | 1039 | #ifdef CONFIG_HIGHPTE |
1020 | .kmap_atomic_pte = xen_kmap_atomic_pte, | 1040 | .kmap_atomic_pte = xen_kmap_atomic_pte, |