]> xenbits.xensource.com Git - xen.git/commitdiff
mm: populate_physmap: validate correctly the gfn for direct mapped domain
authorJulien Grall <julien.grall@citrix.com>
Thu, 10 Sep 2015 13:56:03 +0000 (15:56 +0200)
committerJan Beulich <jbeulich@suse.com>
Thu, 10 Sep 2015 13:56:03 +0000 (15:56 +0200)
Direct mapped domain has already the memory allocated 1:1, so we are
directly using the gfn as mfn to map the RAM in the guest.

While we are validating that the page associated to the first mfn belongs to
the domain, the subsequent MFN are not validated when the extent_order
is > 0.

This may result to map memory region (MMIO, RAM) which doesn't belong to the
domain.

Although, only DOM0 on ARM is using a direct memory mapped. So it
doesn't affect any guest (at least on the upstream version) or even x86.

Signed-off-by: Julien Grall <julien.grall@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
master commit: 9503ab0e9c6a41a1ee7a70c8ea9313d08ebaa8c5
master date: 2015-08-13 14:41:09 +0200

xen/common/memory.c

index 38f79b37a31f87541891463e6ff3e8c31b599255..701c5fb0a9682bff483752206c2ad85257797616 100644 (file)
@@ -129,22 +129,28 @@ static void populate_physmap(struct memop_args *a)
             if ( is_domain_direct_mapped(d) )
             {
                 mfn = gpfn;
-                if ( !mfn_valid(mfn) )
-                {
-                    gdprintk(XENLOG_INFO, "Invalid mfn %#"PRI_xen_pfn"\n",
-                             mfn);
-                    goto out;
-                }
 
-                page = mfn_to_page(mfn);
-                if ( !get_page(page, d) )
+                for ( j = 0; j < (1U << a->extent_order); j++, mfn++ )
                 {
-                    gdprintk(XENLOG_INFO,
-                             "mfn %#"PRI_xen_pfn" doesn't belong to the"
-                             " domain\n", mfn);
-                    goto out;
+                    if ( !mfn_valid(mfn) )
+                    {
+                        gdprintk(XENLOG_INFO, "Invalid mfn %#"PRI_xen_pfn"\n",
+                                 mfn);
+                        goto out;
+                    }
+
+                    page = mfn_to_page(mfn);
+                    if ( !get_page(page, d) )
+                    {
+                        gdprintk(XENLOG_INFO,
+                                 "mfn %#"PRI_xen_pfn" doesn't belong to the"
+                                 " domain\n", mfn);
+                        goto out;
+                    }
+                    put_page(page);
                 }
-                put_page(page);
+
+                page = mfn_to_page(gpfn);
             }
             else
                 page = alloc_domheap_pages(d, a->extent_order, a->memflags);