aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/xen/enlighten.c2
-rw-r--r--arch/x86/xen/mmu.c39
-rw-r--r--arch/x86/xen/xen-ops.h2
3 files changed, 40 insertions, 3 deletions
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index d9faaa26c104..ce67dc8f36af 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -880,6 +880,8 @@ static __init void setup_shared_info(void)
880 /* In UP this is as good a place as any to set up shared info */ 880 /* In UP this is as good a place as any to set up shared info */
881 xen_setup_vcpu_info_placement(); 881 xen_setup_vcpu_info_placement();
882#endif 882#endif
883
884 xen_setup_mfn_list_list();
883} 885}
884 886
885static __init void xen_pagetable_setup_done(pgd_t *base) 887static __init void xen_pagetable_setup_done(pgd_t *base)
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index da7b45b05066..4740cda36563 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -69,6 +69,13 @@ static unsigned long *p2m_top[TOP_ENTRIES]
69 __attribute__((section(".data.page_aligned"))) = 69 __attribute__((section(".data.page_aligned"))) =
70 { [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] }; 70 { [ 0 ... TOP_ENTRIES - 1] = &p2m_missing[0] };
71 71
72/* Arrays of p2m arrays expressed in mfns used for save/restore */
73static unsigned long p2m_top_mfn[TOP_ENTRIES]
74 __attribute__((section(".bss.page_aligned")));
75
76static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE]
77 __attribute__((section(".bss.page_aligned")));
78
72static inline unsigned p2m_top_index(unsigned long pfn) 79static inline unsigned p2m_top_index(unsigned long pfn)
73{ 80{
74 BUG_ON(pfn >= MAX_DOMAIN_PAGES); 81 BUG_ON(pfn >= MAX_DOMAIN_PAGES);
@@ -80,11 +87,35 @@ static inline unsigned p2m_index(unsigned long pfn)
80 return pfn % P2M_ENTRIES_PER_PAGE; 87 return pfn % P2M_ENTRIES_PER_PAGE;
81} 88}
82 89
90/* Build the parallel p2m_top_mfn structures */
91void xen_setup_mfn_list_list(void)
92{
93 unsigned pfn, idx;
94
95 for(pfn = 0; pfn < MAX_DOMAIN_PAGES; pfn += P2M_ENTRIES_PER_PAGE) {
96 unsigned topidx = p2m_top_index(pfn);
97
98 p2m_top_mfn[topidx] = virt_to_mfn(p2m_top[topidx]);
99 }
100
101 for(idx = 0; idx < ARRAY_SIZE(p2m_top_mfn_list); idx++) {
102 unsigned topidx = idx * P2M_ENTRIES_PER_PAGE;
103 p2m_top_mfn_list[idx] = virt_to_mfn(&p2m_top_mfn[topidx]);
104 }
105
106 BUG_ON(HYPERVISOR_shared_info == &xen_dummy_shared_info);
107
108 HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
109 virt_to_mfn(p2m_top_mfn_list);
110 HYPERVISOR_shared_info->arch.max_pfn = xen_start_info->nr_pages;
111}
112
113/* Set up p2m_top to point to the domain-builder provided p2m pages */
83void __init xen_build_dynamic_phys_to_machine(void) 114void __init xen_build_dynamic_phys_to_machine(void)
84{ 115{
85 unsigned pfn;
86 unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list; 116 unsigned long *mfn_list = (unsigned long *)xen_start_info->mfn_list;
87 unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages); 117 unsigned long max_pfn = min(MAX_DOMAIN_PAGES, xen_start_info->nr_pages);
118 unsigned pfn;
88 119
89 for(pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES_PER_PAGE) { 120 for(pfn = 0; pfn < max_pfn; pfn += P2M_ENTRIES_PER_PAGE) {
90 unsigned topidx = p2m_top_index(pfn); 121 unsigned topidx = p2m_top_index(pfn);
@@ -105,7 +136,7 @@ unsigned long get_phys_to_machine(unsigned long pfn)
105 return p2m_top[topidx][idx]; 136 return p2m_top[topidx][idx];
106} 137}
107 138
108static void alloc_p2m(unsigned long **pp) 139static void alloc_p2m(unsigned long **pp, unsigned long *mfnp)
109{ 140{
110 unsigned long *p; 141 unsigned long *p;
111 unsigned i; 142 unsigned i;
@@ -118,6 +149,8 @@ static void alloc_p2m(unsigned long **pp)
118 149
119 if (cmpxchg(pp, p2m_missing, p) != p2m_missing) 150 if (cmpxchg(pp, p2m_missing, p) != p2m_missing)
120 free_page((unsigned long)p); 151 free_page((unsigned long)p);
152 else
153 *mfnp = virt_to_mfn(p);
121} 154}
122 155
123void set_phys_to_machine(unsigned long pfn, unsigned long mfn) 156void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
@@ -139,7 +172,7 @@ void set_phys_to_machine(unsigned long pfn, unsigned long mfn)
139 /* no need to allocate a page to store an invalid entry */ 172 /* no need to allocate a page to store an invalid entry */
140 if (mfn == INVALID_P2M_ENTRY) 173 if (mfn == INVALID_P2M_ENTRY)
141 return; 174 return;
142 alloc_p2m(&p2m_top[topidx]); 175 alloc_p2m(&p2m_top[topidx], &p2m_top_mfn[topidx]);
143 } 176 }
144 177
145 idx = p2m_index(pfn); 178 idx = p2m_index(pfn);
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h
index 826d6e4c3dac..a1bc89a8f169 100644
--- a/arch/x86/xen/xen-ops.h
+++ b/arch/x86/xen/xen-ops.h
@@ -18,6 +18,8 @@ extern struct start_info *xen_start_info;
18extern struct shared_info xen_dummy_shared_info; 18extern struct shared_info xen_dummy_shared_info;
19extern struct shared_info *HYPERVISOR_shared_info; 19extern struct shared_info *HYPERVISOR_shared_info;
20 20
21void xen_setup_mfn_list_list(void);
22
21char * __init xen_memory_setup(void); 23char * __init xen_memory_setup(void);
22void __init xen_arch_setup(void); 24void __init xen_arch_setup(void);
23void __init xen_init_IRQ(void); 25void __init xen_init_IRQ(void);