]> xenbits.xensource.com Git - xen.git/commitdiff
xen/arm: p2m: Check for p2m->domain to be initialized before releasing resources
authorOleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Mon, 28 Aug 2017 17:32:26 +0000 (20:32 +0300)
committerStefano Stabellini <sstabellini@kernel.org>
Fri, 15 Sep 2017 21:29:09 +0000 (14:29 -0700)
Since p2m_teardown() can be called when p2m_init() haven't executed yet
we might deal with unitialized list "p2m->pages" which leads to crash.
To avoid this use back pointer to domain as end-of-initialization indicator.

Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
Reviewed-by: Stefano Stabellini <sstabellini@kernel.org>
xen/arch/arm/p2m.c

index c484469e6c3d0ec44b25f152556e78ffb7bfd981..192a1c329daee34ea1e739e726c1a84c407924fb 100644 (file)
@@ -1219,6 +1219,10 @@ void p2m_teardown(struct domain *d)
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
     struct page_info *pg;
 
+    /* p2m not actually initialized */
+    if ( !p2m->domain )
+        return;
+
     while ( (pg = page_list_remove_head(&p2m->pages)) )
         free_domheap_page(pg);
 
@@ -1230,6 +1234,8 @@ void p2m_teardown(struct domain *d)
     p2m_free_vmid(d);
 
     radix_tree_destroy(&p2m->mem_access_settings, NULL);
+
+    p2m->domain = NULL;
 }
 
 int p2m_init(struct domain *d)
@@ -1247,7 +1253,6 @@ int p2m_init(struct domain *d)
     if ( rc != 0 )
         return rc;
 
-    p2m->domain = d;
     p2m->max_mapped_gfn = _gfn(0);
     p2m->lowest_mapped_gfn = _gfn(ULONG_MAX);
 
@@ -1276,6 +1281,13 @@ int p2m_init(struct domain *d)
     for_each_possible_cpu(cpu)
        p2m->last_vcpu_ran[cpu] = INVALID_VCPU_ID;
 
+    /*
+     * Besides getting a domain when we only have the p2m in hand,
+     * the back pointer to domain is also used in p2m_teardown()
+     * as an end-of-initialization indicator.
+     */
+    p2m->domain = d;
+
     return rc;
 }