diff options
Diffstat (limited to 'arch/x86/xen/enlighten.c')
-rw-r--r-- | arch/x86/xen/enlighten.c | 29 |
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 | ||
670 | static void pin_pagetable_pfn(unsigned level, unsigned long pfn) | 670 | static 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 | ||
698 | static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) | 699 | static 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 | ||
703 | static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) | 704 | static 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 */ |
709 | static void xen_release_pt(u32 pfn) | 710 | static 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 | ||
724 | static void xen_release_pt(u32 pfn) | ||
725 | { | ||
726 | xen_release_ptpage(pfn, PT_PTE); | ||
727 | } | ||
728 | |||
729 | static void xen_release_pd(u32 pfn) | ||
730 | { | ||
731 | xen_release_ptpage(pfn, PT_PMD); | ||
732 | } | ||
733 | |||
721 | #ifdef CONFIG_HIGHPTE | 734 | #ifdef CONFIG_HIGHPTE |
722 | static void *xen_kmap_atomic_pte(struct page *page, enum km_type type) | 735 | static 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(); |