Grant P2M entries, which are covered by p2m_is_any_ram(), wouldn't pass the get_page() unless the grant was a local one. These need to take the same path as foreign entries. Just the assertion there is not valid for local grants, and hence it triggering needs to be avoided.
Shared entries, when unshare is requested, would bypass the retrieval of "page" and thus always take the error path rather than actually trying to unshare by taking the slow path. Signed-off-by: Jan Beulich <[email protected]> --- Using | instead of || helps the compiler fold the two p2m_is_*(). --- a/xen/arch/x86/mm/p2m.c +++ b/xen/arch/x86/mm/p2m.c @@ -584,11 +584,11 @@ struct page_info *p2m_get_page_from_gfn( && !((q & P2M_UNSHARE) && p2m_is_shared(*t)) ) { page = mfn_to_page(mfn); - if ( unlikely(p2m_is_foreign(*t)) ) + if ( unlikely(p2m_is_foreign(*t) | p2m_is_grant(*t)) ) { struct domain *fdom = page_get_owner_and_reference(page); - ASSERT(fdom != p2m->domain); + ASSERT(!p2m_is_foreign(*t) || fdom != p2m->domain); if ( fdom == NULL ) page = NULL; } @@ -607,6 +607,7 @@ struct page_info *p2m_get_page_from_gfn( /* Error path: not a suitable GFN at all */ if ( !p2m_is_ram(*t) && !p2m_is_paging(*t) && !p2m_is_pod(*t) && + (!p2m_is_shared(*t) || !(q & P2M_UNSHARE)) && !mem_sharing_is_fork(p2m->domain) ) return NULL; }
