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.c74
1 files changed, 46 insertions, 28 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index 8b9ee27805fd..27ee26aedf94 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -95,7 +95,7 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info;
95 * 95 *
96 * 0: not available, 1: available 96 * 0: not available, 1: available
97 */ 97 */
98static int have_vcpu_info_placement = 0; 98static int have_vcpu_info_placement = 1;
99 99
100static void __init xen_vcpu_setup(int cpu) 100static void __init xen_vcpu_setup(int cpu)
101{ 101{
@@ -103,6 +103,7 @@ static void __init xen_vcpu_setup(int cpu)
103 int err; 103 int err;
104 struct vcpu_info *vcpup; 104 struct vcpu_info *vcpup;
105 105
106 BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info);
106 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu]; 107 per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
107 108
108 if (!have_vcpu_info_placement) 109 if (!have_vcpu_info_placement)
@@ -666,10 +667,10 @@ static void xen_release_pt_init(u32 pfn)
666 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 667 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
667} 668}
668 669
669static void pin_pagetable_pfn(unsigned level, unsigned long pfn) 670static void pin_pagetable_pfn(unsigned cmd, unsigned long pfn)
670{ 671{
671 struct mmuext_op op; 672 struct mmuext_op op;
672 op.cmd = level; 673 op.cmd = cmd;
673 op.arg1.mfn = pfn_to_mfn(pfn); 674 op.arg1.mfn = pfn_to_mfn(pfn);
674 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF)) 675 if (HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF))
675 BUG(); 676 BUG();
@@ -686,7 +687,8 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
686 687
687 if (!PageHighMem(page)) { 688 if (!PageHighMem(page)) {
688 make_lowmem_page_readonly(__va(PFN_PHYS(pfn))); 689 make_lowmem_page_readonly(__va(PFN_PHYS(pfn)));
689 pin_pagetable_pfn(level, pfn); 690 if (level == PT_PTE)
691 pin_pagetable_pfn(MMUEXT_PIN_L1_TABLE, pfn);
690 } else 692 } else
691 /* make sure there are no stray mappings of 693 /* make sure there are no stray mappings of
692 this page */ 694 this page */
@@ -696,27 +698,39 @@ static void xen_alloc_ptpage(struct mm_struct *mm, u32 pfn, unsigned level)
696 698
697static void xen_alloc_pt(struct mm_struct *mm, u32 pfn) 699static void xen_alloc_pt(struct mm_struct *mm, u32 pfn)
698{ 700{
699 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L1_TABLE); 701 xen_alloc_ptpage(mm, pfn, PT_PTE);
700} 702}
701 703
702static void xen_alloc_pd(struct mm_struct *mm, u32 pfn) 704static void xen_alloc_pd(struct mm_struct *mm, u32 pfn)
703{ 705{
704 xen_alloc_ptpage(mm, pfn, MMUEXT_PIN_L2_TABLE); 706 xen_alloc_ptpage(mm, pfn, PT_PMD);
705} 707}
706 708
707/* 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 */
708static void xen_release_pt(u32 pfn) 710static void xen_release_ptpage(u32 pfn, unsigned level)
709{ 711{
710 struct page *page = pfn_to_page(pfn); 712 struct page *page = pfn_to_page(pfn);
711 713
712 if (PagePinned(page)) { 714 if (PagePinned(page)) {
713 if (!PageHighMem(page)) { 715 if (!PageHighMem(page)) {
714 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn); 716 if (level == PT_PTE)
717 pin_pagetable_pfn(MMUEXT_UNPIN_TABLE, pfn);
715 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn))); 718 make_lowmem_page_readwrite(__va(PFN_PHYS(pfn)));
716 } 719 }
720 ClearPagePinned(page);
717 } 721 }
718} 722}
719 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
720#ifdef CONFIG_HIGHPTE 734#ifdef CONFIG_HIGHPTE
721static 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)
722{ 736{
@@ -805,33 +819,43 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
805 PFN_DOWN(__pa(xen_start_info->pt_base))); 819 PFN_DOWN(__pa(xen_start_info->pt_base)));
806} 820}
807 821
808static __init void xen_pagetable_setup_done(pgd_t *base) 822static __init void setup_shared_info(void)
809{ 823{
810 /* This will work as long as patching hasn't happened yet
811 (which it hasn't) */
812 pv_mmu_ops.alloc_pt = xen_alloc_pt;
813 pv_mmu_ops.alloc_pd = xen_alloc_pd;
814 pv_mmu_ops.release_pt = xen_release_pt;
815 pv_mmu_ops.release_pd = xen_release_pt;
816 pv_mmu_ops.set_pte = xen_set_pte;
817
818 if (!xen_feature(XENFEAT_auto_translated_physmap)) { 824 if (!xen_feature(XENFEAT_auto_translated_physmap)) {
825 unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
826
819 /* 827 /*
820 * Create a mapping for the shared info page. 828 * Create a mapping for the shared info page.
821 * Should be set_fixmap(), but shared_info is a machine 829 * Should be set_fixmap(), but shared_info is a machine
822 * address with no corresponding pseudo-phys address. 830 * address with no corresponding pseudo-phys address.
823 */ 831 */
824 set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP), 832 set_pte_mfn(addr,
825 PFN_DOWN(xen_start_info->shared_info), 833 PFN_DOWN(xen_start_info->shared_info),
826 PAGE_KERNEL); 834 PAGE_KERNEL);
827 835
828 HYPERVISOR_shared_info = 836 HYPERVISOR_shared_info = (struct shared_info *)addr;
829 (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
830
831 } else 837 } else
832 HYPERVISOR_shared_info = 838 HYPERVISOR_shared_info =
833 (struct shared_info *)__va(xen_start_info->shared_info); 839 (struct shared_info *)__va(xen_start_info->shared_info);
834 840
841#ifndef CONFIG_SMP
842 /* In UP this is as good a place as any to set up shared info */
843 xen_setup_vcpu_info_placement();
844#endif
845}
846
847static __init void xen_pagetable_setup_done(pgd_t *base)
848{
849 /* This will work as long as patching hasn't happened yet
850 (which it hasn't) */
851 pv_mmu_ops.alloc_pt = xen_alloc_pt;
852 pv_mmu_ops.alloc_pd = xen_alloc_pd;
853 pv_mmu_ops.release_pt = xen_release_pt;
854 pv_mmu_ops.release_pd = xen_release_pd;
855 pv_mmu_ops.set_pte = xen_set_pte;
856
857 setup_shared_info();
858
835 /* Actually pin the pagetable down, but we can't set PG_pinned 859 /* Actually pin the pagetable down, but we can't set PG_pinned
836 yet because the page structures don't exist yet. */ 860 yet because the page structures don't exist yet. */
837 { 861 {
@@ -1182,15 +1206,9 @@ asmlinkage void __init xen_start_kernel(void)
1182 x86_write_percpu(xen_cr3, __pa(pgd)); 1206 x86_write_percpu(xen_cr3, __pa(pgd));
1183 x86_write_percpu(xen_current_cr3, __pa(pgd)); 1207 x86_write_percpu(xen_current_cr3, __pa(pgd));
1184 1208
1185#ifdef CONFIG_SMP
1186 /* Don't do the full vcpu_info placement stuff until we have a 1209 /* Don't do the full vcpu_info placement stuff until we have a
1187 possible map. */ 1210 possible map and a non-dummy shared_info. */
1188 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; 1211 per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
1189#else
1190 /* May as well do it now, since there's no good time to call
1191 it later on UP. */
1192 xen_setup_vcpu_info_placement();
1193#endif
1194 1212
1195 pv_info.kernel_rpl = 1; 1213 pv_info.kernel_rpl = 1;
1196 if (xen_feature(XENFEAT_supervisor_mode_kernel)) 1214 if (xen_feature(XENFEAT_supervisor_mode_kernel))