diff options
Diffstat (limited to 'arch/x86/xen/mmu.c')
-rw-r--r-- | arch/x86/xen/mmu.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c index d4d52f5a1cf7..aba77b2b7d18 100644 --- a/arch/x86/xen/mmu.c +++ b/arch/x86/xen/mmu.c | |||
@@ -246,11 +246,21 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr) | |||
246 | { | 246 | { |
247 | unsigned long address = (unsigned long)vaddr; | 247 | unsigned long address = (unsigned long)vaddr; |
248 | unsigned int level; | 248 | unsigned int level; |
249 | pte_t *pte = lookup_address(address, &level); | 249 | pte_t *pte; |
250 | unsigned offset = address & ~PAGE_MASK; | 250 | unsigned offset; |
251 | 251 | ||
252 | BUG_ON(pte == NULL); | 252 | /* |
253 | * if the PFN is in the linear mapped vaddr range, we can just use | ||
254 | * the (quick) virt_to_machine() p2m lookup | ||
255 | */ | ||
256 | if (virt_addr_valid(vaddr)) | ||
257 | return virt_to_machine(vaddr); | ||
253 | 258 | ||
259 | /* otherwise we have to do a (slower) full page-table walk */ | ||
260 | |||
261 | pte = lookup_address(address, &level); | ||
262 | BUG_ON(pte == NULL); | ||
263 | offset = address & ~PAGE_MASK; | ||
254 | return XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset); | 264 | return XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset); |
255 | } | 265 | } |
256 | 266 | ||
@@ -410,7 +420,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr, | |||
410 | 420 | ||
411 | xen_mc_batch(); | 421 | xen_mc_batch(); |
412 | 422 | ||
413 | u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; | 423 | u.ptr = arbitrary_virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD; |
414 | u.val = pte_val_ma(pte); | 424 | u.val = pte_val_ma(pte); |
415 | xen_extend_mmu_update(&u); | 425 | xen_extend_mmu_update(&u); |
416 | 426 | ||