|
@@ -246,11 +246,21 @@ xmaddr_t arbitrary_virt_to_machine(void *vaddr)
|
|
|
{
|
|
|
unsigned long address = (unsigned long)vaddr;
|
|
|
unsigned int level;
|
|
|
- pte_t *pte = lookup_address(address, &level);
|
|
|
- unsigned offset = address & ~PAGE_MASK;
|
|
|
+ pte_t *pte;
|
|
|
+ unsigned offset;
|
|
|
|
|
|
- BUG_ON(pte == NULL);
|
|
|
+ /*
|
|
|
+ * if the PFN is in the linear mapped vaddr range, we can just use
|
|
|
+ * the (quick) virt_to_machine() p2m lookup
|
|
|
+ */
|
|
|
+ if (virt_addr_valid(vaddr))
|
|
|
+ return virt_to_machine(vaddr);
|
|
|
|
|
|
+ /* otherwise we have to do a (slower) full page-table walk */
|
|
|
+
|
|
|
+ pte = lookup_address(address, &level);
|
|
|
+ BUG_ON(pte == NULL);
|
|
|
+ offset = address & ~PAGE_MASK;
|
|
|
return XMADDR(((phys_addr_t)pte_mfn(*pte) << PAGE_SHIFT) + offset);
|
|
|
}
|
|
|
|
|
@@ -410,7 +420,7 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
|
|
|
|
|
|
xen_mc_batch();
|
|
|
|
|
|
- u.ptr = virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
|
|
|
+ u.ptr = arbitrary_virt_to_machine(ptep).maddr | MMU_PT_UPDATE_PRESERVE_AD;
|
|
|
u.val = pte_val_ma(pte);
|
|
|
xen_extend_mmu_update(&u);
|
|
|
|