ept_entry_t *table, *ept_entry = NULL;
unsigned long gfn_remainder = gfn;
unsigned int i, target = order / EPT_TABLE_ORDER;
+ unsigned long fn_mask = !mfn_eq(mfn, INVALID_MFN) ? (gfn | mfn_x(mfn)) : gfn;
int ret, rc = 0;
bool_t entry_written = 0;
bool_t direct_mmio = (p2mt == p2m_mmio_direct);
* 2. gfn not exceeding guest physical address width.
* 3. passing a valid order.
*/
- if ( ((gfn | mfn_x(mfn)) & ((1UL << order) - 1)) ||
+ if ( (fn_mask & ((1UL << order) - 1)) ||
((u64)gfn >> ((ept_get_wl(ept) + 1) * EPT_TABLE_ORDER)) ||
(order % EPT_TABLE_ORDER) )
return -EINVAL;
#undef page_to_mfn
#define page_to_mfn(_pg) _mfn(__page_to_mfn(_pg))
-/* We may store INVALID_MFN in l1 PTEs. We need to clip this
- * to avoid trampling over higher-order bits (NX, p2m type, IOMMU flags). We
- * seem to not need to unclip on the return path, as callers are concerned only
- * with p2m type in such cases.
+/*
+ * We may store INVALID_MFN in PTEs. We need to clip this to avoid trampling
+ * over higher-order bits (NX, p2m type, IOMMU flags). We seem to not need
+ * to unclip on the read path, as callers are concerned only with p2m type in
+ * such cases.
*/
#define p2m_l1e_from_pfn(pfn, flags) \
l1e_from_pfn((pfn) & (PADDR_MASK >> PAGE_SHIFT), (flags))
+#define p2m_l2e_from_pfn(pfn, flags) \
+ l2e_from_pfn((pfn) & ((PADDR_MASK & ~(_PAGE_PSE_PAT | 0UL)) \
+ >> PAGE_SHIFT), (flags) | _PAGE_PSE)
+#define p2m_l3e_from_pfn(pfn, flags) \
+ l3e_from_pfn((pfn) & ((PADDR_MASK & ~(_PAGE_PSE_PAT | 0UL)) \
+ >> PAGE_SHIFT), (flags) | _PAGE_PSE)
/* PTE flags for the various types of p2m entry */
#define P2M_BASE_FLAGS \
l1_entry = __map_domain_page(pg);
for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ )
{
- new_entry = l1e_from_pfn(pfn + (i * L1_PAGETABLE_ENTRIES), flags);
+ new_entry = l1e_from_pfn(pfn | (i * L1_PAGETABLE_ENTRIES), flags);
p2m_add_iommu_flags(&new_entry, 1, IOMMUF_readable|IOMMUF_writable);
p2m->write_p2m_entry(p2m, gfn, l1_entry + i, new_entry, 2);
}
l1_entry = __map_domain_page(pg);
for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
{
- new_entry = l1e_from_pfn(pfn + i, flags);
+ new_entry = l1e_from_pfn(pfn | i, flags);
p2m_add_iommu_flags(&new_entry, 0, 0);
p2m->write_p2m_entry(p2m, gfn, l1_entry + i, new_entry, 1);
}
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
l3e_content = mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt)
- ? l3e_from_pfn(mfn_x(mfn),
- p2m_type_to_flags(p2mt, mfn, 2) | _PAGE_PSE)
+ ? p2m_l3e_from_pfn(mfn_x(mfn), p2m_type_to_flags(p2mt, mfn, 2))
: l3e_empty();
entry_content.l1 = l3e_content.l3;
}
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
- if ( mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt) )
- l2e_content = l2e_from_pfn(mfn_x(mfn),
- p2m_type_to_flags(p2mt, mfn, 1) |
- _PAGE_PSE);
- else
- l2e_content = l2e_empty();
-
+ l2e_content = mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt)
+ ? p2m_l2e_from_pfn(mfn_x(mfn), p2m_type_to_flags(p2mt, mfn, 1))
+ : l2e_empty();
entry_content.l1 = l2e_content.l2;
if ( entry_content.l1 != 0 )