mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
amd/npt/shadow: replace assert that prevents creating 2M/1G MMIO entries
The assert was originally added to make sure that higher order regions (> PAGE_ORDER_4K) could not be used to bypass the mmio_ro_ranges check performed by p2m_type_to_flags. This however is already checked in set_mmio_p2m_entry, which makes sure that higher order mappings don't overlap with mmio_ro_ranges, thus allowing the creation of high order MMIO mappings safely. Replace the assert to allow 2M/1G entries to be created for MMIO regions and add some extra asserts as a replacement to make sure there's no overlapping with MMIO read-only ranges. Note that 1G MMIO entries will not be created unless mmio_order is changed to allow it. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> Acked-by: George Dunlap <george.dunlap@citrix.com> Release-acked-by: Juergen Gross <jgross@suse.com>
This commit is contained in:
1 parent
036c6cbddc
commit
6fa1755644
1 file changed
+19
-4
@@ -479,6 +479,23 @@ int p2m_pt_handle_deferred_changes(uint64_t gpa)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Checks only applicable to entries with order > PAGE_ORDER_4K */
|
||||
static void check_entry(mfn_t mfn, p2m_type_t new, p2m_type_t old,
|
||||
unsigned int order)
|
||||
{
|
||||
ASSERT(order > PAGE_ORDER_4K);
|
||||
ASSERT(old != p2m_ioreq_server);
|
||||
if ( new == p2m_mmio_direct )
|
||||
ASSERT(!mfn_eq(mfn, INVALID_MFN) &&
|
||||
!rangeset_overlaps_range(mmio_ro_ranges, mfn_x(mfn),
|
||||
mfn_x(mfn) + (1ul << order)));
|
||||
else if ( p2m_allows_invalid_mfn(new) || new == p2m_invalid ||
|
||||
new == p2m_mmio_dm )
|
||||
ASSERT(mfn_valid(mfn) || mfn_eq(mfn, INVALID_MFN));
|
||||
else
|
||||
ASSERT(mfn_valid(mfn));
|
||||
}
|
||||
|
||||
/* Returns: 0 for success, -errno for failure */
|
||||
static int
|
||||
p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
@@ -575,8 +592,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(p2m_flags_to_type(flags) != p2m_ioreq_server);
|
||||
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
|
||||
check_entry(mfn, p2mt, p2m_flags_to_type(flags), page_order);
|
||||
l3e_content = mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt)
|
||||
? p2m_l3e_from_pfn(mfn_x(mfn),
|
||||
p2m_type_to_flags(p2m, p2mt, mfn, 2))
|
||||
@@ -667,8 +683,7 @@ p2m_pt_set_entry(struct p2m_domain *p2m, gfn_t gfn_, mfn_t mfn,
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(p2m_flags_to_type(flags) != p2m_ioreq_server);
|
||||
ASSERT(!mfn_valid(mfn) || p2mt != p2m_mmio_direct);
|
||||
check_entry(mfn, p2mt, p2m_flags_to_type(flags), page_order);
|
||||
l2e_content = mfn_valid(mfn) || p2m_allows_invalid_mfn(p2mt)
|
||||
? p2m_l2e_from_pfn(mfn_x(mfn),
|
||||
p2m_type_to_flags(p2m, p2mt, mfn, 1))
|
||||
|
||||