diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/xen/enlighten.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/mmu.c | 39 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 2 |
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 | ||
885 | static __init void xen_pagetable_setup_done(pgd_t *base) | 887 | static __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 */ | ||
73 | static unsigned long p2m_top_mfn[TOP_ENTRIES] | ||
74 | __attribute__((section(".bss.page_aligned"))); | ||
75 | |||
76 | static unsigned long p2m_top_mfn_list[TOP_ENTRIES / P2M_ENTRIES_PER_PAGE] | ||
77 | __attribute__((section(".bss.page_aligned"))); | ||
78 | |||
72 | static inline unsigned p2m_top_index(unsigned long pfn) | 79 | static 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 */ | ||
91 | void 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 */ | ||
83 | void __init xen_build_dynamic_phys_to_machine(void) | 114 | void __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 | ||
108 | static void alloc_p2m(unsigned long **pp) | 139 | static 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 | ||
123 | void set_phys_to_machine(unsigned long pfn, unsigned long mfn) | 156 | void 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; | |||
18 | extern struct shared_info xen_dummy_shared_info; | 18 | extern struct shared_info xen_dummy_shared_info; |
19 | extern struct shared_info *HYPERVISOR_shared_info; | 19 | extern struct shared_info *HYPERVISOR_shared_info; |
20 | 20 | ||
21 | void xen_setup_mfn_list_list(void); | ||
22 | |||
21 | char * __init xen_memory_setup(void); | 23 | char * __init xen_memory_setup(void); |
22 | void __init xen_arch_setup(void); | 24 | void __init xen_arch_setup(void); |
23 | void __init xen_init_IRQ(void); | 25 | void __init xen_init_IRQ(void); |