@@ -773,20 +773,24 @@ int epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
if ( v->domain != d )
v = d->vcpu ? d->vcpu[0] : NULL;
- if ( !mfn_valid(mfn_x(mfn)) ||
- rangeset_contains_range(mmio_ro_ranges, mfn_x(mfn),
- mfn_x(mfn) + (1UL << order) - 1) )
+ /* INVALID_MFN should never happen here, but if it does then this
+ * should do the right thing instead of exploding */
+ if ( unlikely(rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn),
+ mfn_x(mfn) | ((1UL << order) - 1))) )
{
- *ipat = 1;
- return MTRR_TYPE_UNCACHABLE;
+ if ( rangeset_contains_range(mmio_ro_ranges, mfn_x(mfn),
+ mfn_x(mfn) | ((1UL << order) - 1)) )
+ {
+ *ipat = 1;
+ return MTRR_TYPE_UNCACHABLE;
+ }
+ /* Overlaps mmio_ro_ranges but is not entirely contained. No. */
+ return -1;
}
- if ( rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn),
- mfn_x(mfn) + (1UL << order) - 1) )
- return -1;
-
if ( direct_mmio )
{
+ /* Again, INVALID_MFN should do the right thing here. */
if ( (mfn_x(mfn) ^ d->arch.hvm_domain.vmx.apic_access_mfn) >> order )
return MTRR_TYPE_UNCACHABLE;
if ( order )
@@ -795,6 +799,12 @@ int epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
return MTRR_TYPE_WRBACK;
}
+ if ( unlikely(!mfn_valid(mfn_x(mfn))) )
+ {
+ *ipat = 1;
+ return MTRR_TYPE_UNCACHABLE;
+ }
+
if ( !need_iommu(d) && !cache_flush_permitted(d) )
{
*ipat = 1;