diff --git a/xen/arch/x86/mm/p2m-pt.c b/xen/arch/x86/mm/p2m-pt.c index 12f92cf1f0..52eaa24b18 100644 --- a/xen/arch/x86/mm/p2m-pt.c +++ b/xen/arch/x86/mm/p2m-pt.c @@ -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))