x86: fix domain cleanup
authorJan Beulich <jbeulich@suse.com>
Fri, 29 Apr 2016 16:30:22 +0000 (18:30 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 29 Apr 2016 16:30:22 +0000 (18:30 +0200)
Free d->arch.cpuids on both the creation error path and during
destruction.

Don't bypass iommu_domain_destroy().

Move psr_domain_init() up so that hvm_domain_initialise() again is the
last thing which can fail, and hence doesn't require undoing later on.

Move psr_domain_free() up on the creation error path, so that cleanup
once again gets done in reverse order of setup.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Release-acked-by: Wei Liu <wei.liu2@citrix.com>
xen/arch/x86/domain.c

index d13b272ce3342e9e34c2e573dd106f9b739182f8..5af2cc5b7f466d033ecfde6141eb3622bfbb40d3 100644 (file)
@@ -648,21 +648,18 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
     }
     spin_lock_init(&d->arch.e820_lock);
 
+    if ( (rc = psr_domain_init(d)) != 0 )
+        goto fail;
+
     if ( has_hvm_container_domain(d) )
     {
         if ( (rc = hvm_domain_initialise(d)) != 0 )
-        {
-            iommu_domain_destroy(d);
             goto fail;
-        }
     }
     else
         /* 64-bit PV guest by default. */
         d->arch.is_32bit_pv = d->arch.has_32bit_shinfo = 0;
 
-    if ( (rc = psr_domain_init(d)) != 0 )
-        goto fail;
-
     /* initialize default tsc behavior in case tools don't */
     tsc_set_info(d, TSC_MODE_DEFAULT, 0UL, 0, 0);
     spin_lock_init(&d->arch.vtsc_lock);
@@ -680,8 +677,11 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
 
  fail:
     d->is_dying = DOMDYING_dead;
+    psr_domain_free(d);
+    iommu_domain_destroy(d);
     cleanup_domain_irq_mapping(d);
     free_xenheap_page(d->shared_info);
+    xfree(d->arch.cpuids);
     if ( paging_initialised )
         paging_final_teardown(d);
     free_perdomain_mappings(d);
@@ -690,7 +690,6 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags,
         xfree(d->arch.pv_domain.cpuidmasks);
         free_xenheap_page(d->arch.pv_domain.gdt_ldt_l1tab);
     }
-    psr_domain_free(d);
     return rc;
 }
 
@@ -700,6 +699,7 @@ void arch_domain_destroy(struct domain *d)
         hvm_domain_destroy(d);
 
     xfree(d->arch.e820);
+    xfree(d->arch.cpuids);
 
     free_domain_pirqs(d);
     if ( !is_idle_domain(d) )