aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/xen/enlighten.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r--arch/x86/xen/enlighten.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index de4e6f05840b..27ee26aedf94 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -667,10 +667,10 @@ static void xen_release_pt_init(u32 pfn)
667 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 667 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
668} 668}
669 669
670static void pin_pagetable_pfn(unsigned level, unsigned long pfn) 670static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
671{ 671{
672 struct mmuext_op op; 672 struct mmuext_op op;
673 op.cmd = level; 673 op.cmd = cmd;
674 op.arg1.mfn = pfn_to_mfn(pfn); 674 op.arg1.mfn = pfn_to_mfn(pfn);
675 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 675 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
676 BUG(); 676 BUG();
@@ -687,7 +687,8 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
687 687
688 if (!PageHighMem(page)) { 688 if (!PageHighMem(page)) {
689 make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); 689 make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
690 pin_pagetable_pfn(level, pfn); 690 if (level == PT_PTE)
691 pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
691 } else 692 } else
692 /* make sure there are no stray mappings of 693 /* make sure there are no stray mappings of
693 this page */ 694 this page */
@@ -697,27 +698,39 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
697 698
698static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) 699static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
699{ 700{
700 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L1_TABLE); 701 xen_alloc_ptpage(mm, pfn, PT_PTE);
701} 702}
702 703
703static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) 704static void xen_alloc_pd(struct mm_struct *mm, u32 pfn)
704{ 705{
705 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L2_TABLE); 706 xen_alloc_ptpage(mm, pfn, PT_PMD);
706} 707}
707 708
708/* This should never happen until we're OK to use struct page */ 709/* This should never happen until we're OK to use struct page */
709static void xen_release_pt(u32 pfn) 710static void xen_release_ptpage(u32 pfn, unsigned level)
710{ 711{
711 struct page *page = pfn_to_page(pfn); 712 struct page *page = pfn_to_page(pfn);
712 713
713 if (PagePinned(page)) { 714 if (PagePinned(page)) {
714 if (!PageHighMem(page)) { 715 if (!PageHighMem(page)) {
715 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); 716 if (level == PT_PTE)
717 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
716 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 718 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
717 } 719 }
720 ClearPagePinned(page);
718 } 721 }
719} 722}
720 723
724static void xen_release_pt(u32 pfn)
725{
726 xen_release_ptpage(pfn, PT_PTE);
727}
728
729static void xen_release_pd(u32 pfn)
730{
731 xen_release_ptpage(pfn, PT_PMD);
732}
733
721#ifdef CONFIG_HIGHPTE 734#ifdef CONFIG_HIGHPTE
722static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) 735static void *xen_kmap_atomic_pte(struct page *page, enum km_type type)
723{ 736{
@@ -838,7 +851,7 @@ static __init void xen_pagetable_setup_done(pgd_t *base)
838 pv_mmu_ops.alloc_pt = xen_alloc_pt; 851 pv_mmu_ops.alloc_pt = xen_alloc_pt;
839 pv_mmu_ops.alloc_pd = xen_alloc_pd; 852 pv_mmu_ops.alloc_pd = xen_alloc_pd;
840 pv_mmu_ops.release_pt = xen_release_pt; 853 pv_mmu_ops.release_pt = xen_release_pt;
841 pv_mmu_ops.release_pd = xen_release_pt; 854 pv_mmu_ops.release_pd = xen_release_pd;
842 pv_mmu_ops.set_pte = xen_set_pte; 855 pv_mmu_ops.set_pte = xen_set_pte;
843 856
844 setup_shared_info(); 857 setup_shared_info();