MMIO regions below the maximum address on the memory map can have a
backing page struct that's shared with dom_io (see x86
arch_init_memory and it's usage of share_xen_page_with_guest), and
thus also fulfill the is_special_page check because the page has the
Xen heap bit set.

This is incorrect for MMIO regions when is_special_page is used by
epte_get_entry_emt, as it will force direct MMIO regions mapped into
the guest p2m to have the cache attributes set to write-back.

Add an extra check in epte_get_entry_emt in order to detect pages
shared with dom_io (ie: MMIO regions) and don't force them to
write-back cache type on that case.

Fixes: 81fd0d3ca4b2cd ('x86/hvm: simplify 'mmio_direct' check in 
epte_get_entry_emt()')
Signed-off-by: Roger Pau Monné <roger....@citrix.com>
---
Cc: Paul Durrant <p...@xen.org>
---
 xen/arch/x86/hvm/mtrr.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/hvm/mtrr.c b/xen/arch/x86/hvm/mtrr.c
index fb051d59c3..33b1dd9052 100644
--- a/xen/arch/x86/hvm/mtrr.c
+++ b/xen/arch/x86/hvm/mtrr.c
@@ -829,7 +829,9 @@ int epte_get_entry_emt(struct domain *d, unsigned long gfn, 
mfn_t mfn,
 
     for ( i = 0; i < (1ul << order); i++ )
     {
-        if ( is_special_page(mfn_to_page(mfn_add(mfn, i))) )
+        const struct page_info *page = mfn_to_page(mfn_add(mfn, i));
+
+        if ( is_special_page(page) && page_get_owner(page) != dom_io )
         {
             if ( order )
                 return -1;
-- 
2.28.0


Reply via email to