|
@@ -416,8 +416,12 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
|
|
|
if (val & _PAGE_PRESENT) {
|
|
|
unsigned long pfn = (val & PTE_PFN_MASK) >> PAGE_SHIFT;
|
|
|
pteval_t flags = val & PTE_FLAGS_MASK;
|
|
|
- unsigned long mfn = pfn_to_mfn(pfn);
|
|
|
+ unsigned long mfn;
|
|
|
|
|
|
+ if (!xen_feature(XENFEAT_auto_translated_physmap))
|
|
|
+ mfn = get_phys_to_machine(pfn);
|
|
|
+ else
|
|
|
+ mfn = pfn;
|
|
|
/*
|
|
|
* If there's no mfn for the pfn, then just create an
|
|
|
* empty non-present pte. Unfortunately this loses
|
|
@@ -427,8 +431,18 @@ static pteval_t pte_pfn_to_mfn(pteval_t val)
|
|
|
if (unlikely(mfn == INVALID_P2M_ENTRY)) {
|
|
|
mfn = 0;
|
|
|
flags = 0;
|
|
|
+ } else {
|
|
|
+ /*
|
|
|
+ * Paramount to do this test _after_ the
|
|
|
+ * INVALID_P2M_ENTRY as INVALID_P2M_ENTRY &
|
|
|
+ * IDENTITY_FRAME_BIT resolves to true.
|
|
|
+ */
|
|
|
+ mfn &= ~FOREIGN_FRAME_BIT;
|
|
|
+ if (mfn & IDENTITY_FRAME_BIT) {
|
|
|
+ mfn &= ~IDENTITY_FRAME_BIT;
|
|
|
+ flags |= _PAGE_IOMAP;
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
val = ((pteval_t)mfn << PAGE_SHIFT) | flags;
|
|
|
}
|
|
|
|