diff options
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r-- | arch/x86/xen/mmu.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index 3f2a67fe6ad6..265601d5a6ae 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -179,46 +179,54 @@ out: | |||
179 | preempt_enable(); | 179 | preempt_enable(); |
180 | } | 180 | } |
181 | 181 | ||
182 | pteval_t xen_pte_val(pte_t pte) | 182 | /* Assume pteval_t is equivalent to all the other *val_t types. */ |
183 | static pteval_t pte_mfn_to_pfn(pteval_t val) | ||
183 | { | 184 | { |
184 | pteval_t ret = pte.pte; | 185 | if (val & _PAGE_PRESENT) { |
186 | unsigned long mfn = (val & PTE_MASK) >> PAGE_SHIFT; | ||
187 | pteval_t flags = val & ~PTE_MASK; | ||
188 | val = (mfn_to_pfn(mfn) << PAGE_SHIFT) | flags; | ||
189 | } | ||
185 | 190 | ||
186 | if (ret & _PAGE_PRESENT) | 191 | return val; |
187 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | 192 | } |
188 | 193 | ||
189 | return ret; | 194 | static pteval_t pte_pfn_to_mfn(pteval_t val) |
195 | { | ||
196 | if (val & _PAGE_PRESENT) { | ||
197 | unsigned long pfn = (val & PTE_MASK) >> PAGE_SHIFT; | ||
198 | pteval_t flags = val & ~PTE_MASK; | ||
199 | val = (pfn_to_mfn(pfn) << PAGE_SHIFT) | flags; | ||
200 | } | ||
201 | |||
202 | return val; | ||
203 | } | ||
204 | |||
205 | pteval_t xen_pte_val(pte_t pte) | ||
206 | { | ||
207 | return pte_mfn_to_pfn(pte.pte); | ||
190 | } | 208 | } |
191 | 209 | ||
192 | pgdval_t xen_pgd_val(pgd_t pgd) | 210 | pgdval_t xen_pgd_val(pgd_t pgd) |
193 | { | 211 | { |
194 | pgdval_t ret = pgd.pgd; | 212 | return pte_mfn_to_pfn(pgd.pgd); |
195 | if (ret & _PAGE_PRESENT) | ||
196 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
197 | return ret; | ||
198 | } | 213 | } |
199 | 214 | ||
200 | pte_t xen_make_pte(pteval_t pte) | 215 | pte_t xen_make_pte(pteval_t pte) |
201 | { | 216 | { |
202 | if (pte & _PAGE_PRESENT) | 217 | pte = pte_pfn_to_mfn(pte); |
203 | pte = phys_to_machine(XPADDR(pte)).maddr; | 218 | return native_make_pte(pte); |
204 | |||
205 | return (pte_t){ .pte = pte }; | ||
206 | } | 219 | } |
207 | 220 | ||
208 | pgd_t xen_make_pgd(pgdval_t pgd) | 221 | pgd_t xen_make_pgd(pgdval_t pgd) |
209 | { | 222 | { |
210 | if (pgd & _PAGE_PRESENT) | 223 | pgd = pte_pfn_to_mfn(pgd); |
211 | pgd = phys_to_machine(XPADDR(pgd)).maddr; | 224 | return native_make_pgd(pgd); |
212 | |||
213 | return (pgd_t){ pgd }; | ||
214 | } | 225 | } |
215 | 226 | ||
216 | pmdval_t xen_pmd_val(pmd_t pmd) | 227 | pmdval_t xen_pmd_val(pmd_t pmd) |
217 | { | 228 | { |
218 | pmdval_t ret = native_pmd_val(pmd); | 229 | return pte_mfn_to_pfn(pmd.pmd); |
219 | if (ret & _PAGE_PRESENT) | ||
220 | ret = machine_to_phys(XMADDR(ret)).paddr | _PAGE_PRESENT; | ||
221 | return ret; | ||
222 | } | 230 | } |
223 | #ifdef CONFIG_X86_PAE | 231 | #ifdef CONFIG_X86_PAE |
224 | void xen_set_pud(pud_t *ptr, pud_t val) | 232 | void xen_set_pud(pud_t *ptr, pud_t val) |
@@ -265,9 +273,7 @@ void xen_pmd_clear(pmd_t *pmdp) | |||
265 | 273 | ||
266 | pmd_t xen_make_pmd(pmdval_t pmd) | 274 | pmd_t xen_make_pmd(pmdval_t pmd) |
267 | { | 275 | { |
268 | if (pmd & _PAGE_PRESENT) | 276 | pmd = pte_pfn_to_mfn(pmd); |
269 | pmd = phys_to_machine(XPADDR(pmd)).maddr; | ||
270 | |||
271 | return native_make_pmd(pmd); | 277 | return native_make_pmd(pmd); |
272 | } | 278 | } |
273 | #else /* !PAE */ | 279 | #else /* !PAE */ |